Resource-iteratie in ARM-sjablonen

In dit artikel wordt beschreven hoe u meer dan één instantie van een resource maakt in uw ARM-sjabloon (Azure Resource Manager). Door een kopieerlus toe te voegen aan de sectie resources van uw sjabloon, kunt u het aantal resources dat u wilt implementeren, dynamisch instellen. U voorkomt ook dat u de syntaxis van de sjabloon moet herhalen.

U kunt ook de kopieerlus gebruiken met eigenschappen, variabelen en uitvoer.

Als u wilt opgeven of een resource helemaal wordt geïmplementeerd, raadpleegt u voorwaardeelement.

Tip

We raden Bicep aan omdat het dezelfde mogelijkheden biedt als ARM-sjablonen en de syntaxis eenvoudiger te gebruiken is. Zie Lussen voor meer informatie.

Syntax

Voeg het copy element toe aan de sectie resources van uw sjabloon om meerdere exemplaren van de resource te implementeren. Het copy element heeft de volgende algemene indeling:

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

De name eigenschap is een waarde die de lus identificeert. De count eigenschap geeft het aantal iteraties op dat u wilt gebruiken voor het resourcetype.

Gebruik de mode eigenschappen en batchSize om op te geven of de resources parallel of op volgorde worden geïmplementeerd. Deze eigenschappen worden beschreven in Serieel of Parallel.

Kopieerlimieten

Het aantal mag niet groter zijn dan 800.

Het aantal mag geen negatief getal zijn. Dit kan nul zijn als u de sjabloon implementeert met een recente versie van Azure CLI, PowerShell of REST API. U moet met name het volgende gebruiken:

  • Azure PowerShell 2.6 of hoger
  • Azure CLI 2.0.74 of hoger
  • REST API versie 2019-05-10 of hoger
  • Gekoppelde implementaties moeten API-versie 2019-05-10 of hoger gebruiken voor het implementatieresourcetype

Eerdere versies van PowerShell, CLI en de REST API bieden geen ondersteuning voor aantal.

Wees voorzichtig met het gebruik van volledige modusimplementatie met kopieerlus. Als u de volledige modus opnieuw implementeert in een resourcegroep, worden alle resources die niet in de sjabloon zijn opgegeven, verwijderd nadat de kopieerlus is opgelost.

Resource-iteratie

In het volgende voorbeeld wordt het aantal opslagaccounts gemaakt dat is opgegeven in de storageCount parameter .

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

U ziet dat de naam van elke resource de copyIndex() functie bevat, die de huidige iteratie in de lus retourneert. copyIndex() is gebaseerd op nul. Het volgende voorbeeld:

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

Hiermee maakt u deze namen:

  • storage0
  • storage1
  • opslag2

Als u de indexwaarde wilt verschuiven, kunt u een waarde doorgeven in de functie copyIndex(). Het aantal iteraties wordt nog steeds opgegeven in het copy-element, maar de waarde van copyIndex wordt gecompenseerd door de opgegeven waarde. Het volgende voorbeeld:

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

Hiermee maakt u deze namen:

  • storage1
  • opslag2
  • opslag3

De kopieerbewerking is handig bij het werken met matrices, omdat u elk element in de matrix kunt herhalen. Gebruik de length functie in de matrix om het aantal iteraties op te geven en copyIndex om de huidige index in de matrix op te halen.

In het volgende voorbeeld wordt één opslagaccount gemaakt voor elke naam die in de parameter is opgegeven.

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

Als u waarden uit de geïmplementeerde resources wilt retourneren, kunt u kopiëren gebruiken in de sectie uitvoer.

Symbolische naam gebruiken

Symbolische naam wordt toegewezen aan lussen voor het kopiëren van resources. De lusindex is gebaseerd op nul. In het volgende voorbeeld myStorages[1] verwijst naar de tweede resource in de resourcelus.

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

Als de index een runtimewaarde is, maakt u de verwijzing zelf op. Bijvoorbeeld

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

Symbolische namen kunnen worden gebruikt in dependsOn-matrices. Als een symbolische naam voor een kopieerlus is, worden alle resources in de lus toegevoegd als afhankelijkheden. Zie Afhankelijk van resources in een lus voor meer informatie.

Serieel of parallel

Standaard maakt Resource Manager de resources parallel. Er geldt geen limiet voor het aantal resources dat parallel is geïmplementeerd, behalve de totale limiet van 800 resources in de sjabloon. De volgorde waarin ze worden gemaakt, wordt niet gegarandeerd.

U kunt echter opgeven dat de resources op volgorde worden geïmplementeerd. Als u bijvoorbeeld een productieomgeving bijwerkt, kunt u de updates slingwekkend maken, zodat slechts een bepaald aantal tegelijk wordt bijgewerkt.

Als u meer dan één exemplaar van een resource serieel wilt implementeren, stelt mode u in op serieel en batchSize op het aantal exemplaren dat tegelijk moet worden geïmplementeerd. Met de seriële modus maakt Resource Manager een afhankelijkheid van eerdere exemplaren in de lus, zodat er geen batch wordt gestart totdat de vorige batch is voltooid.

De waarde voor batchSize mag niet groter zijn dan de waarde voor count in het copy-element.

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

De mode eigenschap accepteert ook parallel, wat de standaardwaarde is.

Iteratie voor een onderliggende resource

U kunt geen kopieerlus gebruiken voor een onderliggende resource. Als u meer dan één exemplaar van een resource wilt maken die u doorgaans definieert als genest binnen een andere resource, moet u die resource in plaats daarvan maken als een resource op het hoogste niveau. U definieert de relatie met de bovenliggende resource via de type- en naameigenschappen.

Stel dat u een gegevensset doorgaans definieert als een onderliggende resource binnen een gegevensfactory.

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

Als u meer dan één gegevensset wilt maken, verplaatst u deze buiten de data factory. De gegevensset moet zich op hetzelfde niveau bevinden als de gegevensfactory, maar het is nog steeds een onderliggende resource van de data factory. U behoudt de relatie tussen gegevensset en data factory via de type- en naameigenschappen. Omdat het type niet meer kan worden afgeleid van de positie in de sjabloon, moet u het volledig gekwalificeerde type opgeven in de indeling: {resource-provider-namespace}/{parent-resource-type}/{child-resource-type}.

Als u een bovenliggende/onderliggende relatie tot stand wilt brengen met een exemplaar van de data factory, geeft u een naam op voor de gegevensset die de naam van de bovenliggende resource bevat. Gebruik de notatie {parent-resource-name}/{child-resource-name}.

In het volgende voorbeeld ziet u de implementatie.

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

Voorbeeldsjablonen

In de volgende voorbeelden ziet u veelvoorkomende scenario's voor het maken van meer dan één exemplaar van een resource of eigenschap.

Template Beschrijving
Opslag kopiëren Implementeert meer dan één opslagaccount met een indexnummer in de naam.
Opslag voor serieel kopiëren Implementeert meerdere opslagaccounts één voor één. De naam bevat het indexnummer.
Opslag kopiëren met matrix Implementeert verschillende opslagaccounts. De naam bevat een waarde uit een matrix.
Resourcegroep kopiëren Implementeert meerdere resourcegroepen.

Volgende stappen