Iterazione delle risorse nei modelli di ARM

Questo articolo illustra come creare più di un’istanza di una risorsa nel tuo modello di Azure Resource Manager (modello di ARM). Aggiungendo un ciclo di copia alla sezione risorse del modello, puoi impostare dinamicamente il numero di risorse da distribuire. Eviti anche di dover ripetere la sintassi del modello.

Inoltre puoi usare il ciclo di copia con proprietà, variabilie output.

Se è necessario specificare se una risorsa viene distribuita, vedere l'elemento condizionale.

Suggerimento

È consigliabile Bicep perché offre le stesse funzionalità dei modelli di ARM e la sintassi è più semplice da usare. Per saperne di più, vedi cicli.

Sintassi

Aggiungi l'elemento copy alla sezione risorse del modello per distribuire più istanze della risorsa. L'elemento copy ha il formato generale seguente:

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

La proprietà name è qualsiasi valore che identifica il ciclo. La proprietà count specifica il numero di iterazioni desiderate per il tipo di risorsa.

Usa le proprietà mode e batchSize per specificare se le risorse vengono distribuite in parallelo o in sequenza. Queste proprietà sono descritte in Serial o Parallel.

Limiti di copia

Il totale non può superare 800.

Il totale non può essere un numero negativo. Può essere zero se distribuisci il modello con una versione recente dell'interfaccia della riga di comando di Azure, PowerShell o API REST. In particolare, devi usare:

  • Azure PowerShell 2.6 o versione successiva
  • Interfaccia della riga di comando di Azure 2.0.74 o versione successiva
  • API REST versione 2019-05-10 o successiva
  • Le distribuzioni collegate devono usare la versione API 2019-05-10 o successiva per il tipo di risorsa di distribuzione

Le versioni precedenti di PowerShell, dell'interfaccia della riga di comando e dell'API REST non supportano zero per il conteggio.

Presta attenzione all'uso della distribuzione in modalità completa con il ciclo di copia. Se ridistribuisci con la modalità completa in un gruppo di risorse, tutte le risorse non specificate nel modello dopo la risoluzione del ciclo di copia vengono eliminate.

Iterazione delle risorse

Nell'esempio seguente viene creato il numero di account di archiviazione specificati parametro storageCount.

{
  "$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": {}
    }
  ]
}

Si noti che il nome di ogni risorsa include la funzione copyIndex() che restituisce l'iterazione corrente nel ciclo. copyIndex() è in base zero. Quindi l'esempio seguente:

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

Crea questi nomi:

  • storage0
  • storage1
  • storage2

Per eseguire l'offset del valore di indice, è possibile passare un valore nella funzione copyIndex(). Il numero di iterazioni viene comunque specificato nell'elemento copia, ma il valore di copyIndex è compensato dal valore specificato. Quindi l'esempio seguente:

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

Crea questi nomi:

  • storage1
  • storage2
  • storage3

L'operazione di copia è utile quando si lavora con le matrici in quanto è possibile iterare ogni elemento della matrice. Usare la funzione length nella matrice per specificare il conteggio per le iterazioni e copyIndex per recuperare l'indice corrente nella matrice.

Nell'esempio seguente viene creato un account di archiviazione per ogni nome specificato nel parametro.

{
  "$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 vuoi restituire valori dalle risorse distribuite, puoi usare la copia nella sezione output.

Usa il nome simbolico

Il nome simbolico verrà assegnato ai cicli di copia delle risorse. L'indice del ciclo è in base zero. Nell'esempio seguente, myStorages[1] fa riferimento alla seconda risorsa nel ciclo di risorse.

{
  "$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 l'indice è un valore di runtime, formatta manualmente il riferimento. Ad esempio:

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

I nomi simbolici possono essere usati nelle matrici dependsOn. Se un nome simbolico è per un ciclo di copia, tutte le risorse nel ciclo vengono aggiunte come dipendenze. Per ulteriori informazioni, vedi Dipende dalle risorse in un ciclo.

Seriale o parallelo

Per impostazione predefinita, Gestione risorse crea le risorse in parallelo. Non si applica alcun limite al numero di risorse distribuite in parallelo, oltre al limite totale di 800 risorse nel modello. L'ordine di creazione non è garantito.

Tuttavia è consigliabile specificare che le risorse vengano distribuite in sequenza. Ad esempio, quando si aggiorna un ambiente di produzione, è consigliabile sfalsare gli aggiornamenti per aggiornarne solo un determinato numero in un dato momento.

Per distribuire in modo seriale più istanze di una risorsa, impostare mode su serial e batchSize sul numero di istanze da distribuire contemporaneamente. 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.

Il valore per batchSize non può superare il valore per count nell'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": {}
    }
  ]
}

La proprietà mode accetta anche parallel, che è il valore predefinito.

Iterazione di una risorsa figlio

Non è possibile usare un ciclo di copia per una risorsa figlio. 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. La relazione con la risorsa padre si definisce con le proprietà type e name.

Si supponga, ad esempio, di definire in genere un set di dati come una risorsa figlio all'interno di una data factory.

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

Per creare più set di dati, spostarlo all'esterno della data factory. Il set di dati deve essere sullo stesso livello della data factory, di cui è comunque una risorsa figlio. La relazione fra set di dati e data factory viene mantenuta con le proprietà type e name. 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}.

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. Usare il formato: {parent-resource-name}/{child-resource-name}.

Nell'esempio seguente viene descritta l'implementazione.

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

Modelli di esempio

Gli esempi seguenti mostrano alcuni scenari comuni per la creazione di più istanze di una risorsa o proprietà.

Modello Descrizione
Copia risorsa di archiviazione Distribuisce più account di archiviazione con un numero di indice nel nome.
Copia seriale risorse di archiviazione Distribuisce più account di archiviazione uno alla volta. Il nome include il numero di indice.
Copia risorsa di archiviazione con matrice Distribuisce più account di archiviazione. Il nome include un valore di una matrice.
Copiare un gruppo di risorse Distribuire più gruppi di risorse.

Passaggi successivi