Iteração de propriedade em modelos ARM

Este artigo mostra como criar mais de uma instância de uma propriedade no seu modelo do ARM (modelo do Azure Resource Manager). Ao adicionar o loop de cópia à seção de propriedades de um recurso em seu modelo, você consegue definir dinamicamente o número de itens para uma propriedade durante a implantação. Você também evita a repetição da sintaxe do modelo.

Você consegue usar o loop de cópia somente com recursos de nível superior, mesmo ao aplicar o loop de cópia a uma propriedade. Para saber mais sobre como alterar um recurso filho para um recurso de nível superior, consulte Iteração para um recurso filho.

O loop de cópia também pode ser usado com recursos, variáveise saídas.

Dica

Recomendamos o Bicep porque ele oferece as mesmas funcionalidades que os modelos do ARM e a sintaxe é mais fácil de usar. Para saber mais, confira loops.

Syntax

Adicione o elemento copy à seção de recursos do modelo para definir o número de itens para uma propriedade. O elemento de cópia tem o seguinte formato geral:

"copy": [
  {
    "name": "<name-of-property>",
    "count": <number-of-iterations>,
    "input": <values-for-the-property>
  }
]

Para name, forneça o nome da propriedade de recurso que deseja criar.

A propriedade count especifica o número de iterações que deseja para a propriedade.

A propriedade input especifica as propriedades que você deseja repetir. Crie uma matriz de elementos construídos a partir do valor na propriedade input.

Limites de cópia

A contagem não pode exceder 800.

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

  • Azure PowerShell 2.6 ou posterior
  • CLI do Azure 2.0.74 ou posterior
  • API REST versão 10-05-2019 ou posterior
  • As implantações vinculadas devem usar a versão de API 10-05-2019 ou posterior para o tipo de recurso de implantação

As versões anteriores do PowerShell, da CLI e da API REST não dão suporte a zero como contagem.

Iteração de propriedade

O exemplo a seguir mostra como aplicar o loop de cópia para a propriedade dataDisks em uma máquina virtual:

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "numberOfDataDisks": {
      "type": "int",
      "minValue": 0,
      "maxValue": 16,
      "defaultValue": 3,
      "metadata": {
        "description": "The number of dataDisks to create."
      }
    },
    ...
  },
  "resources": [
    {
      "type": "Microsoft.Compute/virtualMachines",
      "apiVersion": "2022-11-01",
      ...
      "properties": {
        "storageProfile": {
          ...
          "copy": [
            {
              "name": "dataDisks",
              "count": "[parameters('numberOfDataDisks')]",
              "input": {
                "lun": "[copyIndex('dataDisks')]",
                "createOption": "Empty",
                "diskSizeGB": 1023
              }
            }
          ]
        }
        ...
      }
    }
  ]
}

Observe que ao usar copyIndex dentro de uma iteração de propriedade, você deve fornecer o nome da iteração. A iteração de propriedade também aceita um argumento de deslocamento. O deslocamento deve vir após o nome da iteração, como copyIndex('dataDisks', 1).

O modelo implantado se torna:

{
  "name": "examplevm",
  "type": "Microsoft.Compute/virtualMachines",
  "apiVersion": "2020-06-01",
  "properties": {
    "storageProfile": {
      "dataDisks": [
        {
          "lun": 0,
          "createOption": "Empty",
          "diskSizeGB": 1023
        },
        {
          "lun": 1,
          "createOption": "Empty",
          "diskSizeGB": 1023
        },
        {
          "lun": 2,
          "createOption": "Empty",
          "diskSizeGB": 1023
        }
      ],
      ...

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

O modelo de exemplo a seguir cria um grupo de failover para bancos de dados que são passados como uma matriz.

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "primaryServerName": {
      "type": "string"
    },
    "secondaryServerName": {
      "type": "string"
    },
    "databaseNames": {
      "type": "array",
      "defaultValue": [
        "mydb1",
        "mydb2",
        "mydb3"
      ]
    }
  },
  "variables": {
    "failoverName": "[format('{0}/{1}failovergroups', parameters('primaryServerName'), parameters('primaryServerName'))]"
  },
  "resources": [
    {
      "type": "Microsoft.Sql/servers/failoverGroups",
      "apiVersion": "2015-05-01-preview",
      "name": "[variables('failoverName')]",
      "properties": {
        "readWriteEndpoint": {
          "failoverPolicy": "Automatic",
          "failoverWithDataLossGracePeriodMinutes": 60
        },
        "readOnlyEndpoint": {
          "failoverPolicy": "Disabled"
        },
        "partnerServers": [
          {
            "id": "[resourceId('Microsoft.Sql/servers', parameters('secondaryServerName'))]"
          }
        ],
        "copy": [
          {
            "name": "databases",
            "count": "[length(parameters('databaseNames'))]",
            "input": "[resourceId('Microsoft.Sql/servers/databases', parameters('primaryServerName'), parameters('databaseNames')[copyIndex('databases')])]"
          }
        ]
      }
    }
  ],
  "outputs": {
  }
}

O elemento copy está em uma matriz. Sendo assim, você pode especificar mais de uma propriedade para o recurso.

{
  "type": "Microsoft.Network/loadBalancers",
  "apiVersion": "2017-10-01",
  "name": "exampleLB",
  "properties": {
    "copy": [
      {
        "name": "loadBalancingRules",
        "count": "[length(parameters('loadBalancingRules'))]",
        "input": {
          ...
        }
      },
      {
        "name": "probes",
        "count": "[length(parameters('loadBalancingRules'))]",
        "input": {
          ...
        }
      }
    ]
  }
}

Você pode usar iteração de recurso e propriedade juntos. Referência a iteração de propriedade por nome.

{
  "type": "Microsoft.Network/virtualNetworks",
  "apiVersion": "2018-04-01",
  "name": "[format('{0}{1}', parameters('vnetname'), copyIndex())]",
  "copy":{
    "count": 2,
    "name": "vnetloop"
  },
  "location": "[resourceGroup().location]",
  "properties": {
    "addressSpace": {
      "addressPrefixes": [
        "[parameters('addressPrefix')]"
      ]
    },
    "copy": [
      {
        "name": "subnets",
        "count": 2,
        "input": {
          "name": "[format('subnet-{0}', copyIndex('subnets'))]",
          "properties": {
            "addressPrefix": "[variables('subnetAddressPrefix')[copyIndex('subnets')]]"
          }
        }
      }
    ]
  }
}

Modelos de exemplo

O exemplo a seguir mostra um cenário comum para criar mais de um valor para uma propriedade.

Modelo Descrição
Implantação da VM com um número variável de discos de dados Implanta vários discos de dados com uma máquina virtual.

Próximas etapas