Distribuire più istanze di una risorsa o di una proprietà nei modelli di Azure Resource ManagerDeploy multiple instances of a resource or property in Azure Resource Manager Templates

In questo articolo viene illustrato come eseguire un'iterazione del modello di Azure Resource Manager per creare più istanze di una risorsa.This article shows you how to iterate in your Azure Resource Manager template to create multiple instances of a resource. Se è necessario specificare se una risorsa viene distribuita, vedere l'elemento condizionale.If you need to specify whether a resource is deployed at all, see condition element.

Iterazione delle risorseResource iteration

Quando durante la distribuzione occorre decidere se creare una o più istanze di una risorsa, aggiungere un elemento copy al tipo di risorsa.When you must decide during deployment to create one or more instances of a resource, add a copy element to the resource type. Nell'elemento copy si specifica il numero di iterazioni e un nome per questo ciclo.In the copy element, you specify the number of iterations and a name for this loop. Il valore del conteggio deve essere un numero intero positivo e non può essere maggiore di 800.The count value must be a positive integer and can't exceed 800.

La risorsa da ricreare più volte assume il formato seguente:The resource to create multiple times takes the following format:

{
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "resources": [
        {
            "apiVersion": "2016-01-01",
            "type": "Microsoft.Storage/storageAccounts",
            "name": "[concat(copyIndex(),'storage', uniqueString(resourceGroup().id))]",
            "location": "[resourceGroup().location]",
            "sku": {
                "name": "Standard_LRS"
            },
            "kind": "Storage",
            "properties": {},
            "copy": {
                "name": "storagecopy",
                "count": 3
            }
        }
    ],
    "outputs": {}
}

Si noti che il nome di ogni risorsa include la funzione copyIndex() che restituisce l'iterazione corrente nel ciclo.Notice that the name of each resource includes the copyIndex() function, which returns the current iteration in the loop. copyIndex() è in base zero.copyIndex() is zero-based. Quindi l'esempio seguente:So, the following example:

"name": "[concat('storage', copyIndex())]",

Crea questi nomi:Creates these names:

  • storage0storage0
  • storage1storage1
  • storage2storage2.

Per eseguire l'offset del valore di indice, è possibile passare un valore nella funzione copyIndex().To offset the index value, you can pass a value in the copyIndex() function. Il numero di iterazioni da eseguire viene comunque specificato nell'elemento copia, ma il valore di copyIndex è compensato dal valore specificato.The number of iterations to perform is still specified in the copy element, but the value of copyIndex is offset by the specified value. Quindi l'esempio seguente:So, the following example:

"name": "[concat('storage', copyIndex(1))]",

Crea questi nomi:Creates these names:

  • storage1storage1
  • storage2storage2
  • storage3storage3

L'operazione di copia è utile quando si lavora con le matrici in quanto è possibile iterare ogni elemento della matrice.The copy operation is helpful when working with arrays because you can iterate through each element in the array. Usare la funzione length nella matrice per specificare il conteggio per le iterazioni e copyIndex per recuperare l'indice corrente nella matrice.Use the length function on the array to specify the count for iterations, and copyIndex to retrieve the current index in the array. Quindi l'esempio seguente:So, the following example:

"parameters": { 
  "org": { 
     "type": "array", 
     "defaultValue": [ 
         "contoso", 
         "fabrikam", 
         "coho" 
      ] 
  }
}, 
"resources": [ 
  { 
      "name": "[concat('storage', parameters('org')[copyIndex()])]", 
      "copy": { 
         "name": "storagecopy", 
         "count": "[length(parameters('org'))]" 
      }, 
      ...
  } 
]

Crea questi nomi:Creates these names:

  • storagecontosostoragecontoso
  • storagefabrikamstoragefabrikam
  • storagecohostoragecoho

Per impostazione predefinita, Gestione risorse crea le risorse in parallelo.By default, Resource Manager creates the resources in parallel. Pertanto l'ordine di creazione non è garantito.Therefore, the order in which they're created isn't guaranteed. Tuttavia è consigliabile specificare che le risorse vengano distribuite in sequenza.However, you may want to specify that the resources are deployed in sequence. Ad esempio, quando si aggiorna un ambiente di produzione, è consigliabile sfalsare gli aggiornamenti per aggiornarne solo un determinato numero in un dato momento.For example, when updating a production environment, you may want to stagger the updates so only a certain number are updated at any one time.

Per distribuire in modo seriale più istanze di una risorsa, impostare mode su serial e batchSize sul numero di istanze da distribuire contemporaneamente.To serially deploy multiple instances of a resource, set mode to serial and batchSize to the number of instances to deploy at a time. Con la modalità seriale, Resource Manager crea una dipendenza da istanze precedenti nel ciclo in modo un batch venga avviato solo dopo il completamento del batch precedente.With serial mode, Resource Manager creates a dependency on earlier instances in the loop, so it doesn't start one batch until the previous batch completes.

Ad esempio, per distribuire in modo seriale gli account di archiviazione due alla volta, usare:For example, to serially deploy storage accounts two at a time, use:

{
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "resources": [
        {
            "apiVersion": "2016-01-01",
            "type": "Microsoft.Storage/storageAccounts",
            "name": "[concat(copyIndex(),'storage', uniqueString(resourceGroup().id))]",
            "location": "[resourceGroup().location]",
            "sku": {
                "name": "Standard_LRS"
            },
            "kind": "Storage",
            "properties": {},
            "copy": {
                "name": "storagecopy",
                "count": 4,
                "mode": "serial",
                "batchSize": 2
            }
        }
    ],
    "outputs": {}
}

La proprietà mode accetta anche parallel, che è il valore predefinito.The mode property also accepts parallel, which is the default value.

Iterazione delle proprietàProperty iteration

Per creare più valori per una proprietà in una risorsa, aggiungere una matrice copy nell'elemento properties.To create multiple values for a property on a resource, add a copy array in the properties element. Questa matrice contiene oggetti ai quali sono associate le proprietà riportate di seguito.This array contains objects, and each object has the following properties:

  • name: il nome della proprietà per la quale creare più valoriname - the name of the property to create multiple values for
  • count: il numero di valori da crearecount - the number of values to create
  • input: un oggetto che contiene i valori da assegnare alla proprietàinput - an object that contains the values to assign to the property

Nell'esempio seguente viene illustrato come applicare copy alla proprietà dataDisks in una macchina virtuale:The following example shows how to apply copy to the dataDisks property on a virtual machine:

{
  "name": "examplevm",
  "type": "Microsoft.Compute/virtualMachines",
  "apiVersion": "2017-03-30",
  "properties": {
    "storageProfile": {
      "copy": [{
          "name": "dataDisks",
          "count": 3,
          "input": {
              "lun": "[copyIndex('dataDisks')]",
              "createOption": "Empty",
              "diskSizeGB": "1023"
          }
      }],
      ...

Si noti che quando si usa copyIndex all'interno di un'iterazione di proprietà, è necessario specificare il nome dell'iterazione.Notice that when using copyIndex inside a property iteration, you must provide the name of the iteration. Non è necessario fornire il nome se usato con You don't have to provide the name when used with resource iteration.You don't have to provide the name when used with resource iteration.

Resource Manager espande la matrice copy durante la distribuzione.Resource Manager expands the copy array during deployment. Il nome della matrice diventa il nome della proprietà.The name of the array becomes the name of the property. I valori di input diventano le proprietà dell'oggetto.The input values become the object properties. Il modello distribuito diventa:The deployed template becomes:

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

L'elemento di copia è una matrice, pertanto è possibile specificare più di una proprietà per una risorsa.The copy element is an array so you can specify more than one property for the resource. Aggiungere un oggetto per ogni proprietà da creare.Add an object for each property to create.

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

È possibile usare l'iterazione di risorse e di proprietà contemporaneamente.You can use resource and property iteration together. Fare riferimento all'iterazione di proprietà con il nome.Reference the property iteration by name.

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

Iterazione delle variabiliVariable iteration

Per creare più istanze di una variabile, usare l'elemento copy nella sezione variables.To create multiple instances of a variable, use the copy element in the variables section. È possibile creare più istanze di oggetti con valori correlati e quindi assegnare tali valori a istanze della risorsa.You can create multiple instances of objects with related values, and then assign those values to instances of the resource. È possibile usare l'opzione di copia per creare un oggetto con una matrice di proprietà o una matrice.You can use copy to create either an object with an array property or an array. Entrambi gli approcci sono illustrati nell'esempio seguente:Both approaches are shown in the following example:

{
  "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {},
  "variables": {
    "disk-array-on-object": {
      "copy": [
        {
          "name": "disks",
          "count": 5,
          "input": {
            "name": "[concat('myDataDisk', copyIndex('disks', 1))]",
            "diskSizeGB": "1",
            "diskIndex": "[copyIndex('disks')]"
          }
        }
      ]
    },
    "copy": [
      {
        "name": "disks-top-level-array",
        "count": 5,
        "input": {
          "name": "[concat('myDataDisk', copyIndex('disks-top-level-array', 1))]",
          "diskSizeGB": "1",
          "diskIndex": "[copyIndex('disks-top-level-array')]"
        }
      }
    ]
  },
  "resources": [],
  "outputs": {
    "exampleObject": {
      "value": "[variables('disk-array-on-object')]",
      "type": "object"
    },
    "exampleArrayOnObject": {
      "value": "[variables('disk-array-on-object').disks]",
      "type" : "array"
    },
    "exampleArray": {
      "value": "[variables('disks-top-level-array')]",
      "type" : "array"
    }
  }
}

Con qualunque approccio, l'elemento di copia è una matrice, pertanto è possibile specificare più di una variabile.With either approach, the copy element is an array so you can specify more than one variable. Aggiungere un oggetto per ogni variabile da creare.Add an object for each variable to create.

"copy": [
  {
    "name": "first-variable",
    "count": 5,
    "input": {
      "demoProperty": "[concat('myProperty', copyIndex('first-variable'))]",
    }
  },
  {
    "name": "second-variable",
    "count": 3,
    "input": {
      "demoProperty": "[concat('myProperty', copyIndex('second-variable'))]",
    }
  },
]

In base alle risorse in un cicloDepend on resources in a loop

L'elemento dependsOn consente di specificare che una risorsa sia distribuita dopo un'altra.You specify that a resource is deployed after another resource by using the dependsOn element. Per distribuire una risorsa che dipende dalla raccolta di risorse in un ciclo, usare il nome del ciclo di copia nell'elemento dependsOn.To deploy a resource that depends on the collection of resources in a loop, provide the name of the copy loop in the dependsOn element. L'esempio seguente illustra come distribuire tre account di archiviazione prima di distribuire la macchina virtuale.The following example shows how to deploy three storage accounts before deploying the Virtual Machine. La definizione completa di macchina virtuale non viene visualizzata.The full Virtual Machine definition isn't shown. Si noti che la copia ha la proprietà name impostata su storagecopy e l'elemento dependsOn per le macchine virtuali impostato su storagecopy.Notice that the copy element has name set to storagecopy and the dependsOn element for the Virtual Machines is also set to storagecopy.

{
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {},
    "resources": [
        {
            "apiVersion": "2016-01-01",
            "type": "Microsoft.Storage/storageAccounts",
            "name": "[concat(copyIndex(),'storage', uniqueString(resourceGroup().id))]",
            "location": "[resourceGroup().location]",
            "sku": {
                "name": "Standard_LRS"
            },
            "kind": "Storage",
            "properties": {},
            "copy": {
                "name": "storagecopy",
                "count": 3
            }
        },
        {
            "apiVersion": "2015-06-15", 
            "type": "Microsoft.Compute/virtualMachines", 
            "name": "[concat('VM', uniqueString(resourceGroup().id))]",  
            "dependsOn": ["storagecopy"],
            ...
        }
    ],
    "outputs": {}
}

Iterazione di una risorsa figlioIteration for a child resource

Non è possibile usare un ciclo di copia per una risorsa figlio.You can't use a copy loop for a child resource. Per creare più istanze di una risorsa cosiddetta "annidata" all'interno di un'altra risorsa, è invece necessario creare tale risorsa come una risorsa di livello superiore.To create multiple instances of a resource that you typically define as nested within another resource, you must instead create that resource as a top-level resource. La relazione con la risorsa padre si definisce con le proprietà type e name.You define the relationship with the parent resource through the type and name properties.

Si supponga, ad esempio, di definire in genere un set di dati come una risorsa figlio all'interno di una data factory.For example, suppose you typically define a dataset as a child resource within a data factory.

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

Per creare più istanze di un set di dati, spostarlo all'esterno della data factory.To create multiple instances of data sets, move it outside of the data factory. Il set di dati deve essere sullo stesso livello della data factory, di cui è comunque una risorsa figlio.The dataset must be at the same level as the data factory, but it's still a child resource of the data factory. La relazione fra set di dati e data factory viene mantenuta con le proprietà type e name.You preserve the relationship between data set and data factory through the type and name properties. Poiché non è possibile dedurre il tipo dalla sua posizione nel modello, è necessario specificarne il nome completo nel formato: {resource-provider-namespace}/{parent-resource-type}/{child-resource-type}.Since type can no longer be inferred from its position in the template, you must provide the fully qualified type in the format: {resource-provider-namespace}/{parent-resource-type}/{child-resource-type}.

Per stabilire una relazione padre/figlio con un'istanza della data factory, specificare il nome del set di dati che include il nome della risorsa padre.To establish a parent/child relationship with an instance of the data factory, provide a name for the data set that includes the parent resource name. Usare il formato: {parent-resource-name}/{child-resource-name}.Use the format: {parent-resource-name}/{child-resource-name}.

Nell'esempio seguente viene descritta l'implementazione:The following example shows the implementation:

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

Modelli di esempioExample templates

Gli esempi seguenti mostrano alcuni scenari comuni per la creazione di più risorse o proprietà.The following examples show common scenarios for creating multiple resources or properties.

ModelloTemplate DESCRIZIONEDescription
Copia risorsa di archiviazioneCopy storage Distribuisce più account di archiviazione con un numero di indice nel nome.Deploys multiple storage accounts with an index number in the name.
Copia seriale risorse di archiviazioneSerial copy storage Distribuisce più account di archiviazione uno alla volta.Deploys multiple storage accounts one at time. Il nome include il numero di indice.The name includes the index number.
Copia risorsa di archiviazione con matriceCopy storage with array Distribuisce più account di archiviazione.Deploys multiple storage accounts. Il nome include un valore di una matrice.The name includes a value from an array.
Distribuzione VM con un numero variabile di dischi datiVM deployment with a variable number of data disks Distribuisce più dischi dati con una macchina virtuale.Deploys multiple data disks with a virtual machine.
Copia variabiliCopy variables Mostra le diverse modalità di iterazione delle variabili.Demonstrates the different ways of iterating on variables.
Più regole di sicurezzaMultiple security rules Distribuisce più regole di sicurezza a un gruppo di sicurezza di rete.Deploys multiple security rules to a network security group. Costruisce le regole di sicurezza da un parametro.It constructs the security rules from a parameter. Per il parametro, vedere il file di parametri NSG multipli.For the parameter, see multiple NSG parameter file.

Passaggi successiviNext steps