Udostępnij przez


Iteracja zasobów w szablonach usługi ARM

W tym artykule pokazano, jak utworzyć więcej niż jedno wystąpienie zasobu w szablonie usługi Azure Resource Manager (szablon usługi ARM). Dodając pętlę kopiowania do sekcji zasobów szablonu, możesz dynamicznie ustawić liczbę zasobów do wdrożenia. Należy również unikać konieczności powtarzania składni szablonu.

Możesz również użyć pętli kopiowania z właściwościami, zmiennymi i danymi wyjściowymi.

Jeśli musisz określić, czy zasób został wdrożony w ogóle, zobacz element warunek .

Wskazówka

Bicep jest zalecany, ponieważ oferuje te same możliwości co szablony ARM, a jego składnia jest łatwiejsza do użycia. Aby dowiedzieć się więcej, zobacz pętle.

Składnia

copy Dodaj element do sekcji zasobów szablonu, aby wdrożyć wiele wystąpień zasobu. Element copy ma następujący ogólny format:

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

Właściwość name jest dowolną wartością identyfikującą pętlę. Właściwość count określa liczbę iteracji, które mają być wykonywane dla typu zasobu.

mode Użyj właściwości i batchSize , aby określić, czy zasoby są wdrażane równolegle, czy w sekwencji. Te właściwości są opisane w szeregowe lub równoległe.

Limity kopiowania

Liczba nie może przekraczać 800 lub być liczbą ujemną. Przy wdrażaniu szablonu za pomocą najnowszej wersji Azure CLI, PowerShell lub interfejsu API REST, wynik może być równy zero. W szczególności należy użyć:

  • Program Azure PowerShell 2.6 lub nowszy.
  • Interfejs wiersza polecenia platformy Azure w wersji 2.0.74 lub nowszej.
  • Interfejs REST API w wersji 2019-05-10 lub nowszej.
  • Wersja interfejsu API 2019-05-10 lub nowsza dla typu zasobu wdrożenia podczas połączonych wdrożeń.

Wcześniejsze wersje programu PowerShell, interfejsu wiersza polecenia i interfejsu API REST nie obsługują wartości zero dla liczby.

Należy zachować ostrożność podczas wdrażania w trybie pełnym z pętlą kopiowania. W przypadku ponownego wdrożenia w trybie pełnym w grupie zasobów wszystkie zasoby, które nie są określone w szablonie po rozpoznaniu pętli kopiowania, zostaną usunięte.

Iteracja zasobu

Poniższy przykład tworzy liczbę kont magazynu określonych w parametrze 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": "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": {}
    }
  ]
}

Zwróć uwagę, że nazwa każdego zasobu copyIndex() zawiera funkcję, która zwraca bieżącą iterację w pętli. Funkcja copyIndex() rozpoczyna liczenie od zera. A więc następujący przykład:

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

Tworzy te nazwy:

  • Pamięć masowa0
  • Pamięć masowa1
  • Pamięć masowa2

Aby zrównoważyć wartość indeksu, możesz przekazać wartość w copyIndex() funkcji. Liczba iteracji jest nadal określona w elemencie copy, ale wartość copyIndex jest przesunięta o określoną wartość. A więc następujący przykład:

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

Tworzy te nazwy:

  • Pamięć masowa1
  • Pamięć masowa2
  • Pamięć masowa3

Operacja kopiowania jest przydatna podczas pracy z tablicami, ponieważ można iterować poszczególne elementy w tablicy. length Użyj funkcji w tablicy, aby określić liczbę iteracji i copyIndex pobrać bieżący indeks w tablicy.

Poniższy przykład tworzy jedno konto przechowywania dla każdej nazwy podanej w parametrze:

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

Jeśli chcesz zwrócić wartości z wdrożonych zasobów, możesz użyć polecenia kopiowania w sekcji danych wyjściowych.

Użyj nazwy symbolicznej

Nazwa symboliczna zostanie przypisana do pętli kopiowania zasobów. Indeks pętli jest liczony od zera. W poniższym przykładzie myStorages[1] odwołuje się do drugiego zasobu w pętli zasobów:

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

Jeśli indeks jest wartością środowiska uruchomieniowego, sformatuj odwołanie samodzielnie. Przykład:

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

Nazwy symboliczne mogą być używane w tablicach dependsOn. Jeśli nazwa symboliczna dotyczy pętli kopiowania, wszystkie zasoby w pętli są dodawane jako zależności. Aby uzyskać więcej informacji, zobacz zasoby zależne w pętli.

Szeregowe lub równoległe

Domyślnie Resource Manager tworzy zasoby równolegle. Nie ma żadnego limitu liczby zasobów wdrożonych równolegle poza całkowitym limitem 800 zasobów w szablonie. Kolejność ich tworzenia nie jest gwarantowana.

Można jednak określić, że zasoby są wdrażane w sekwencji. Na przykład, podczas aktualizowania środowiska produkcyjnego, można etapować aktualizacje, aby jednocześnie aktualizować tylko określoną liczbę jednostek.

Aby szeregowo wdrożyć więcej niż jedno wystąpienie zasobu, ustaw mode wartość szeregową i batchSize liczbę wystąpień do wdrożenia jednocześnie. W trybie seryjnym usługa Resource Manager tworzy zależność od wcześniejszych wystąpień w pętli, tak aby nie uruchamiała jednej partii do momentu zakończenia poprzedniej partii.

Wartość parametru batchSize nie może przekroczyć wartości dla count elementu 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": {}
    }
  ]
}

Właściwość mode akceptuje również wartość parallel, która jest wartością domyślną.

Iteracja zasobu podrzędnego

Nie można użyć pętli kopiowania dla zasobu podrzędnego. Aby utworzyć więcej niż jedno wystąpienie zasobu, który zwykle jest definiowany jako zagnieżdżony w innym zasobie, należy zamiast tego utworzyć ten zasób jako zasób najwyższego poziomu. Relację z zasobem nadrzędnym definiuje się za pomocą właściwości type i name.

Załóżmy na przykład, że zazwyczaj definiujesz zestaw danych jako zasób podrzędny w fabryce danych:

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

Aby utworzyć więcej niż jeden zestaw danych, przenieś go poza fabrykę danych. Zestaw danych musi znajdować się na tym samym poziomie co fabryka danych, ale nadal jest zasobem podrzędnym fabryki danych. Właściwości typu i nazwy zachowują relację między zestawem danych a fabryką danych. Ponieważ typ nie może już być wywnioskowany z jego pozycji w szablonie, należy podać w pełni kwalifikowany typ w tym formacie: {resource-provider-namespace}/{parent-resource-type}/{child-resource-type}.

Aby nawiązać relację nadrzędną/podrzędną z instancją Data Factory, podaj nazwę zestawu danych, która zawiera nazwę zasobu nadrzędnego. Użyj tego formatu: {parent-resource-name}/{child-resource-name}.

W poniższym przykładzie pokazano implementację:

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

Przykładowe szablony

W poniższych przykładach przedstawiono typowe scenariusze tworzenia więcej niż jednego wystąpienia zasobu lub właściwości.

Szablon Opis
Przechowywanie kopii Wdraża więcej niż jedno konto magazynu z numerem indeksu w nazwie.
Magazyn kopii szeregowych Wdraża kilka kont magazynu pojedynczo. Nazwa zawiera numer indeksu.
Kopiowanie pamięci masowej z macierzą Wdraża kilka kont magazynu. Nazwa zawiera wartość z tablicy.
Kopiowanie grupy zasobów Wdraża wiele grup zasobów.

Dalsze kroki