Partilhar via


Iteração de recursos em modelos ARM

Este artigo mostra como criar mais de uma instância de um recurso em seu modelo do Azure Resource Manager (modelo ARM). Ao adicionar o loop de cópia à seção de recursos do seu modelo, você pode definir dinamicamente o número de recursos a serem implantados. Você também evita ter que repetir a sintaxe do modelo.

Você também pode usar o loop de cópia com propriedades, variáveis e saídas.

Se você precisar especificar se um recurso será implantado, consulte Elemento de condição.

Gorjeta

Recomendamos o Bicep porque ele oferece os mesmos recursos que os modelos ARM e a sintaxe é mais fácil de usar. Para saber mais, consulte loops.

Sintaxe

Adicione o copy elemento à seção de recursos do seu modelo para implantar várias instâncias do recurso. O copy elemento tem o seguinte formato geral:

"copy": {
  "name": "<name-of-loop>",
  "count": <number-of-iterations>,
  "mode": "serial" <or> "parallel",
  "batchSize": <number-to-deploy-serially>
}

A name propriedade é qualquer valor que identifique o loop. A count propriedade especifica o número de iterações que você deseja para o tipo de recurso.

Use as mode propriedades e batchSize para especificar se os recursos são implantados em paralelo ou em sequência. Essas propriedades são descritas em Serial ou Parallel.

Limites de cópia

A contagem não pode exceder 800.

A contagem não pode ser um número negativo. Pode ser zero se você implantar o modelo com uma versão recente da CLI do Azure, PowerShell ou API REST. Especificamente, você deve usar:

As versões anteriores do PowerShell, CLI e da API REST não suportam zero para contagem.

Tenha cuidado ao usar a implantação de modo completo com loop de cópia. Se você reimplantar com o modo completo em um grupo de recursos, todos os recursos que não forem especificados no modelo depois de resolver o loop de cópia serão excluídos.

Iteração de recursos

O exemplo a seguir cria o número de contas de armazenamento especificadas no storageCount parâmetro.

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "location": {
      "type": "string",
      "defaultValue": "[resourceGroup().location]"
    },
    "storageCount": {
      "type": "int",
      "defaultValue": 3
    }
  },
  "resources": [
    {
      "copy": {
        "name": "storagecopy",
        "count": "[length(range(0, parameters('storageCount')))]"
      },
      "type": "Microsoft.Storage/storageAccounts",
      "apiVersion": "2022-09-01",
      "name": "[format('{0}storage{1}', range(0, parameters('storageCount'))[copyIndex()], uniqueString(resourceGroup().id))]",
      "location": "[parameters('location')]",
      "sku": {
        "name": "Standard_LRS"
      },
      "kind": "Storage",
      "properties": {}
    }
  ]
}

Observe que o nome de cada recurso inclui a copyIndex() função, que retorna a iteração atual no loop. copyIndex() é baseado em zero. Assim, o seguinte exemplo:

"name": "[format('storage{0}', copyIndex())]",

Cria estes nomes:

  • armazenamento0
  • Armazenamento1
  • armazenamento2

Para compensar o valor do índice, você pode passar um valor na copyIndex() função. O número de iterações ainda é especificado no elemento copy, mas o valor de é deslocado copyIndex pelo valor especificado. Assim, o seguinte exemplo:

"name": "[format('storage{0}', copyIndex(1))]",

Cria estes nomes:

  • Armazenamento1
  • armazenamento2
  • armazenamento3

A operação de cópia é útil ao trabalhar com matrizes porque você pode iterar através de cada elemento na matriz. Use a length função na matriz para especificar a contagem para iterações e copyIndex para recuperar o índice atual na matriz.

O exemplo a seguir cria uma conta de armazenamento para cada nome fornecido no parâmetro.

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "storageNames": {
      "type": "array",
      "defaultValue": [
        "contoso",
        "fabrikam",
        "coho"
      ]
    },
    "location": {
      "type": "string",
      "defaultValue": "[resourceGroup().location]"
    }
  },
  "resources": [
    {
      "copy": {
        "name": "storagecopy",
        "count": "[length(parameters('storageNames'))]"
      },
      "type": "Microsoft.Storage/storageAccounts",
      "apiVersion": "2022-09-01",
      "name": "[format('{0}{1}', parameters('storageNames')[copyIndex()], uniqueString(resourceGroup().id))]",
      "location": "[parameters('location')]",
      "sku": {
        "name": "Standard_LRS"
      },
      "kind": "Storage",
      "properties": {}
    }
  ]
}

Se quiser retornar valores dos recursos implantados, você pode usar copy na seção de saídas.

Usar nome simbólico

O nome simbólico será atribuído aos loops de cópia do recurso. O índice de loop é baseado em zero. No exemplo a seguir, myStorages[1] faz referência ao segundo recurso no loop de recursos.

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "languageVersion": "2.0",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "location": {
      "type": "string",
      "defaultValue": "[resourceGroup().location]"
    },
    "storageCount": {
      "type": "int",
      "defaultValue": 2
    }
  },
  "resources": {
    "myStorages": {
      "type": "Microsoft.Storage/storageAccounts",
      "apiVersion": "2022-09-01",
      "name": "[format('{0}storage{1}', copyIndex(), uniqueString(resourceGroup().id))]",
      "location": "[parameters('location')]",
      "sku": {
        "name": "Standard_LRS"
      },
      "kind": "Storage",
      "properties": {},
      "copy": {
        "name": "storagecopy",
        "count": "[parameters('storageCount')]"
      }
    }
  },
  "outputs": {
    "storageEndpoint":{
      "type": "object",
      "value": "[reference('myStorages[1]').primaryEndpoints]"
    }
  }
}

Se o índice for um valor de tempo de execução, formate a referência você mesmo. Por exemplo

"outputs": {
  "storageEndpoint":{
    "type": "object",
    "value": "[reference(format('myStorages[{0}]', variables('runtimeIndex'))).primaryEndpoints]"
  }
}

Nomes simbólicos podem ser usados em matrizes dependsOn. Se um nome simbólico for para um loop de cópia, todos os recursos no loop serão adicionados como dependências. Para obter mais informações, consulte Depende de recursos em um loop.

Série ou Paralelo

Por padrão, o Gerenciador de Recursos cria os recursos em paralelo. Ele não se aplica nenhum limite ao número de recursos implantados em paralelo, além do limite total de 800 recursos no modelo. A ordem em que são criados não é garantida.

No entanto, convém especificar que os recursos sejam implantados em sequência. Por exemplo, ao atualizar um ambiente de produção, convém escalonar as atualizações para que apenas um determinado número seja atualizado a qualquer momento.

Para implantar em série mais de uma instância de um recurso, defina mode como serial e batchSize para o número de instâncias a serem implantadas de cada vez. Com o modo serial, o Resource Manager cria uma dependência de instâncias anteriores no loop, para que ele não inicie um lote até que o lote anterior seja concluído.

O valor para batchSize não pode exceder o valor para count no elemento copy.

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "location": {
      "type": "string",
      "defaultValue": "[resourceGroup().location]"
    }
  },
  "resources": [
    {
      "copy": {
        "name": "storagecopy",
        "count": 4,
        "mode": "serial",
        "batchSize": 2
      },
      "type": "Microsoft.Storage/storageAccounts",
      "apiVersion": "2022-09-01",
      "name": "[format('{0}storage{1}', range(0, 4)[copyIndex()], uniqueString(resourceGroup().id))]",
      "location": "[parameters('location')]",
      "sku": {
        "name": "Standard_LRS"
      },
      "kind": "Storage",
      "properties": {}
    }
  ]
}

A mode propriedade também aceita paralelo, que é o valor padrão.

Iteração para um recurso filho

Não é possível usar um loop de cópia para um recurso filho. Para criar mais de uma instância de um recurso que você normalmente define como aninhado em outro recurso, você deve, em vez disso, criar esse recurso como um recurso de nível superior. Você define o relacionamento com o recurso pai por meio das propriedades type e name.

Por exemplo, suponha que você normalmente defina um conjunto de dados como um recurso filho dentro de um data factory.

{
  "resources": [
    {
      "type": "Microsoft.DataFactory/factories",
      "name": "exampleDataFactory",
      ...
      "resources": [
        {
          "type": "datasets",
          "name": "exampleDataSet",
          "dependsOn": [
            "exampleDataFactory"
          ],
          ...
        }
      ]
      ...
    }
  ]
}

Para criar mais de um conjunto de dados, mova-o para fora do data factory. O conjunto de dados deve estar no mesmo nível do data factory, mas ainda é um recurso filho do data factory. Você preserva a relação entre o conjunto de dados e o data factory por meio das propriedades de tipo e nome. Como o tipo não pode mais ser inferido de sua posição no modelo, você deve fornecer o tipo totalmente qualificado no formato: {resource-provider-namespace}/{parent-resource-type}/{child-resource-type}.

Para estabelecer uma relação pai/filho com uma instância do data factory, forneça um nome para o conjunto de dados que inclua o nome do recurso pai. Use o formato: {parent-resource-name}/{child-resource-name}.

O exemplo a seguir mostra a implementação.

"resources": [
{
  "type": "Microsoft.DataFactory/factories",
  "name": "exampleDataFactory",
  ...
},
{
  "type": "Microsoft.DataFactory/factories/datasets",
  "name": "[format('exampleDataFactory/exampleDataSet{0}', copyIndex())]",
  "dependsOn": [
    "exampleDataFactory"
  ],
  "copy": {
    "name": "datasetcopy",
    "count": "3"
  },
  ...
}]

Modelos de exemplo

Os exemplos a seguir mostram cenários comuns para criar mais de uma instância de um recurso ou propriedade.

Modelo Description
Armazenamento de cópias Implanta mais de uma conta de armazenamento com um número de índice no nome.
Armazenamento de cópias seriais Implanta várias contas de armazenamento uma de cada vez. O nome inclui o número de índice.
Copiar armazenamento com array Implanta várias contas de armazenamento. O nome inclui um valor de uma matriz.
Copiar grupo de recursos Implanta vários grupos de recursos.

Próximos passos