Compartir a través de


Iteración de recursos en plantillas de ARM

En este artículo se muestra cómo crear más de una instancia de un recurso en la plantilla de Azure Resource Manager (plantilla de ARM). Al agregar un bucle de copia a la sección de recursos de la plantilla, puede establecer dinámicamente el número de recursos que se van a implementar. También se evita tener que repetir la sintaxis de la plantilla.

También puede utilizar el bucle de copia con propiedades, variables y salidas.

Si necesita especificar si se implementa un recurso en absoluto, consulte el elemento condition .

Sugerencia

Se recomienda Bicep , ya que ofrece las mismas funcionalidades que las plantillas de ARM y la sintaxis es más fácil de usar. Para obtener más información, consulte bucles.

Sintaxis

Agregue el copy elemento a la sección de recursos de la plantilla para implementar varias instancias del recurso. El copy elemento tiene el siguiente formato general:

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

La name propiedad es cualquier valor que identifica el bucle. La count propiedad especifica el número de iteraciones que desea para el tipo de recurso.

Utilice las mode propiedades y batchSize para especificar si los recursos se implementan en paralelo o en secuencia. Estas propiedades se describen en serie o en paralelo.

Límites de copia

El recuento no puede superar los 800 o ser un número negativo. Puede ser cero si implementa la plantilla con una versión reciente de la CLI de Azure, PowerShell o la API REST. Específicamente, debe utilizar:

  • Azure PowerShell 2.6 o posterior.
  • CLI de Azure 2.0.74 o posterior.
  • API REST versión 2019-05-10 o posterior.
  • Versión de API 2019-05-10 o posterior para el tipo de recurso de implementación durante las implementaciones vinculadas.

Las versiones anteriores de PowerShell, la CLI y la API REST no admiten cero para el recuento.

Tenga cuidado de usar la implementación en modo completo con el bucle de copia. Si vuelve a implementar con el modo completo en un grupo de recursos, se eliminan los recursos que no se especifican en la plantilla después de resolver el bucle de copia.

Iteración de recursos

En el ejemplo siguiente se crea el número de cuentas de almacenamiento especificadas en el 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": "2025-06-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 el nombre de cada recurso incluye la copyIndex() función, que devuelve la iteración actual en el bucle. copyIndex() es de base cero. Entonces, el siguiente ejemplo:

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

Crea estos nombres:

  • almacenamiento0
  • Almacenamiento1
  • Almacenamiento2

Para desplazar el valor de índice, puede pasar un valor en la función copyIndex(). El número de iteraciones se sigue especificando en el elemento copy, pero el valor de copyIndex se desplaza por el valor especificado. Entonces, el siguiente ejemplo:

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

Crea estos nombres:

  • Almacenamiento1
  • Almacenamiento2
  • Almacenamiento3

La operación de copia resulta útil al trabajar con matrices porque puede recorrer en iteración cada elemento de la matriz. Utilice la función de length la matriz para especificar el recuento de iteraciones y copyIndex recuperar el índice actual de la matriz.

En el ejemplo siguiente se crea una cuenta de almacenamiento para cada nombre proporcionado en el 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": "2025-06-01",
      "name": "[format('{0}{1}', parameters('storageNames')[copyIndex()], uniqueString(resourceGroup().id))]",
      "location": "[parameters('location')]",
      "sku": {
        "name": "Standard_LRS"
      },
      "kind": "Storage",
      "properties": {}
    }
  ]
}

Si desea devolver valores de los recursos implementados, puede usar la copia en la sección salidas.

Usar nombre simbólico

Se asignará un nombre simbólico a los bucles de copia de recursos. El índice de bucle es de base cero. En el ejemplo siguiente, myStorages[1] hace referencia al segundo recurso del bucle 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": "2025-06-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]"
    }
  }
}

Si el índice es un valor en tiempo de ejecución, formatee la referencia usted mismo. Por ejemplo:

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

Los nombres simbólicos se pueden usar en matrices dependsOn. Si un nombre simbólico es para un bucle de copia, todos los recursos del bucle se agregan como dependencias. Para obtener más información, consulte depende de los recursos de un bucle.

Serie o paralelo

De forma predeterminada, Resource Manager crea los recursos en paralelo. No se aplica ningún límite al número de recursos implementados en paralelo, excepto el límite total de 800 recursos de la plantilla. No se garantiza el orden en el que se crean.

Sin embargo, es posible que desee especificar que los recursos se implementan en secuencia. Por ejemplo, al actualizar un entorno de producción, puede escalonar las actualizaciones para que solo se actualice un número determinado en cualquier momento.

Para implementar en serie más de una instancia de un recurso, establézcalo mode en serie y batchSize en el número de instancias que se van a implementar a la vez. Con el modo serie, Resource Manager crea una dependencia en instancias anteriores en el bucle para que no inicie un lote hasta que se complete el lote anterior.

El valor de batchSize no puede superar el valor de count en el 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": "2025-06-01",
      "name": "[format('{0}storage{1}', range(0, 4)[copyIndex()], uniqueString(resourceGroup().id))]",
      "location": "[parameters('location')]",
      "sku": {
        "name": "Standard_LRS"
      },
      "kind": "Storage",
      "properties": {}
    }
  ]
}

La mode propiedad también acepta parallel, que es el valor predeterminado.

Iteración para un recurso secundario

No se puede usar un bucle de copia para un recurso secundario. Para crear más de una instancia de un recurso que normalmente se define como anidado dentro de otro recurso, debe crear ese recurso como un recurso de nivel superior. La relación con el recurso primario se define a través de las propiedades type y name.

Por ejemplo, supongamos que normalmente define un conjunto de datos como un recurso secundario dentro de una factoría de datos:

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

Para crear más de un conjunto de datos, muévalo fuera de la factoría de datos. El conjunto de datos debe estar en el mismo nivel que la factoría de datos, pero sigue siendo un recurso secundario de la factoría de datos. Las propiedades type y name conservan la relación entre el conjunto de datos y la factoría de datos. Puesto que el tipo ya no se puede deducir de su posición en la plantilla, debe proporcionar el tipo completo en este formato: {resource-provider-namespace}/{parent-resource-type}/{child-resource-type}.

Para establecer una relación primaria o secundaria con una instancia de la factoría de datos, proporcione un nombre para el conjunto de datos que incluya el nombre del recurso primario. Use este formato: {parent-resource-name}/{child-resource-name}.

En el ejemplo siguiente se muestra la implementación:

"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"
  },
  ...
}]

Plantillas de ejemplo

En los ejemplos siguientes se muestran escenarios comunes para crear más de una instancia de un recurso o propiedad.

Plantilla Descripción
Almacenamiento de copias Implementa más de una cuenta de almacenamiento con un número de índice en el nombre.
Almacenamiento de copias en serie Implementa varias cuentas de almacenamiento de una en una. El nombre incluye el número de índice.
Almacenamiento de copias con cabina Implementa varias cuentas de almacenamiento. El nombre incluye un valor de una matriz.
Copiar grupo de recursos Implementa varios grupos de recursos.

Pasos siguientes