Condividi tramite


Iterazione delle risorse nei modelli ARM di Resource Manager

Questo articolo illustra come creare più di un'istanza di risorse nel modello Azure Resource Manager (ARM template). Aggiungendo un ciclo di copia alla sezione resources del modello, è possibile impostare dinamicamente il numero di risorse da distribuire. Eviti anche di dover ripetere la sintassi del modello.

È anche possibile usare il ciclo di copia con proprietà, variabili e output.

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

Suggerimento

È consigliabile usare Bicep perché offre le stesse funzionalità dei modelli arm e la sintassi è più facile da usare. Per altre informazioni, vedere Cicli.

Sintassi

Aggiungere l'elemento copy alla sezione resources 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 name proprietà è qualsiasi valore che identifica il ciclo. La count proprietà specifica il numero di iterazioni desiderate per il tipo di risorsa.

Usare le mode proprietà e batchSize per specificare se le risorse vengono distribuite in parallelo o in sequenza. Queste proprietà sono descritte in serie o parallele.

Limiti di copia

Il conteggio non può superare 800 o essere un numero negativo. Può essere zero se si distribuisce il modello con una versione recente dell'interfaccia della riga di comando di Azure, di PowerShell o dell'API REST. In particolare, è necessario usare:

  • Azure PowerShell 2.6 o versione successiva.
  • Interfaccia della riga di comando di Azure 2.0.74 o successiva.
  • API REST versione 2019-05-10 o successiva.
  • API versione 2019-05-10 o successiva per il tipo di risorsa di distribuzione durante le distribuzioni collegate.

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

Prestare attenzione all'uso della distribuzione in modalità completa con il ciclo di copia. Se si ridistribuisce 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

L'esempio seguente crea il numero di account di archiviazione specificati nel storageCount parametro :

{
  "$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 copyIndex() funzione , che restituisce l'iterazione corrente nel ciclo. copyIndex() è in base zero. Di conseguenza, l'esempio seguente:

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

Crea questi nomi:

  • stoccaggio0
  • archiviazione1
  • archiviazione2

Per eseguire l'offset del valore di indice, è possibile passare un valore nella funzione copyIndex(). Il numero di iterazioni è ancora specificato nell'elemento copy, ma il valore di copyIndex è offset in base al valore specificato. Di conseguenza, l'esempio seguente:

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

Crea questi nomi:

  • archiviazione1
  • archiviazione2
  • archiviazione3

L'operazione di copia è utile quando si utilizzano matrici perché è possibile scorrere ogni elemento nella matrice. Usare la length funzione nella matrice per specificare il numero di iterazioni e copyIndex recuperare l'indice corrente nella matrice.

L'esempio seguente crea 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 si desidera restituire valori dalle risorse distribuite, è possibile usare la copia nella sezione output.

Usare il nome simbolico

Il nome simbolico verrà assegnato ai cicli di copia delle risorse. L'indice del ciclo parte da zero. Nell'esempio seguente viene myStorages[1] fatto 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 il riferimento da solo. Per 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 altre informazioni, vedere Depends-on resources in a loop.

Seriale o parallelo

Per impostazione predefinita, Resource Manager 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 in cui vengono creati non è garantito.

Tuttavia, è possibile specificare che le risorse vengono distribuite in sequenza. Ad esempio, quando si aggiorna un ambiente di produzione, è possibile sfalsarne gli aggiornamenti in modo che solo un determinato numero venga aggiornato contemporaneamente.

Per distribuire più istanze di una risorsa in modo seriale, impostare mode su seriale e batchSize sul numero di istanze da distribuire contemporaneamente. Con la modalità seriale, Resource Manager crea una dipendenza dalle istanze precedenti del ciclo in modo che non avvii un batch fino al 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 mode proprietà accetta anche parallela, ovvero il valore predefinito.

Iterazione per una risorsa figlia

Non è possibile usare un ciclo di copia per una risorsa figlia. Per creare più di un'istanza di una risorsa definita in genere come annidata all'interno di un'altra risorsa, è invece necessario creare tale risorsa come risorsa di primo livello. Si definisce la relazione con la risorsa padre tramite le proprietà di tipo e nome.

Si supponga, ad esempio, di definire un set di dati come 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 allo stesso livello della Data Factory, ma è ancora una risorsa subordinata della Data Factory. Le proprietà di tipo e nome mantengono la relazione tra il set di dati e la data factory. Poiché il tipo non può più essere dedotto dalla posizione nel modello, è necessario specificare il tipo completo in questo formato: {resource-provider-namespace}/{parent-resource-type}/{child-resource-type}.

Per stabilire una relazione padre/figlio con un'istanza della data factory, specificare un nome per il set di dati che include il nome della risorsa padre. Usare il formato seguente: {parent-resource-name}/{child-resource-name}.

L'esempio seguente illustra 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 illustrano scenari comuni per la creazione di più istanze di una risorsa o di una proprietà.

Modello Descrizione
Copiare l'archiviazione Distribuisce più account di archiviazione con un numero di indice nel nome.
Archiviazione di copia seriale Distribuisce più account di archiviazione uno alla volta. Il nome include il numero di indice.
Copiare l'archiviazione con array Distribuisce diversi account di archiviazione. Il nome include un valore di una matrice.
Copiare un gruppo di risorse Distribuisce più gruppi di risorse.

Passaggi successivi