Iteração de propriedade em modelos ARM

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

Você só pode usar o loop de cópia 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.

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

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 definir o número de itens para uma propriedade. O elemento copy 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 você deseja criar.

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

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

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.

Iteração de propriedade

O exemplo a seguir mostra como aplicar o loop de cópia à dataDisks propriedade 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 suporta 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 iterar através de cada elemento na matriz. Use a função length na matriz para especificar a contagem de iterações e copyIndex 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 copy elemento é uma matriz para que você possa 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ções de recursos e propriedades juntas. Faça referência à iteração da propriedade pelo 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 Description
Implantação de VM com um número variável de discos de dados Implanta vários discos de dados com uma máquina virtual.

Próximos passos