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żna 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 jest wdrożony w ogóle, zobacz element warunek.

Porada

Zalecamy użycie aplikacji Bicep , ponieważ oferuje te same możliwości co szablony usługi ARM, a składnia jest łatwiejsza. Aby dowiedzieć się więcej, zobacz pętle.

Składnia

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

"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ą, która identyfikuje pętlę. Właściwość count określa liczbę iteracji 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 części Szeregowa lub Równoległa.

Limity kopiowania

Liczba nie może przekroczyć 800.

Liczba nie może być liczbą ujemną. Wdrożenie szablonu przy użyciu najnowszej wersji interfejsu wiersza polecenia platformy Azure, programu PowerShell lub interfejsu API REST może być zerowe. W szczególności należy użyć:

  • Azure PowerShell w wersji 2.6 lub nowszej
  • Interfejs wiersza polecenia platformy Azure w wersji 2.0.74 lub nowszej
  • Interfejs API REST w wersji 2019-05-10 lub nowszej
  • Połączone wdrożenia muszą używać interfejsu API w wersji 2019-05-10 lub nowszej dla typu zasobu wdrożenia

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 do grupy zasobów zostaną usunięte wszystkie zasoby, które nie zostały określone w szablonie po rozpoznaniu pętli kopiowania.

Iteracja zasobów

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

Zwróć uwagę, że nazwa każdego zasobu zawiera copyIndex() funkcję, która zwraca bieżącą iterację w pętli. Funkcja copyIndex() rozpoczyna liczenie od zera. W związku z tym poniższy przykład:

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

Tworzy następujące nazwy:

  • storage0
  • storage1
  • storage2

Aby zrównoważyć wartość indeksu, możesz przekazać wartość w copyIndex() funkcji . Liczba iteracji jest nadal określona w elemecie copy, ale wartość copyIndex jest przesunięty przez określoną wartość. W związku z tym poniższy przykład:

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

Tworzy następujące nazwy:

  • storage1
  • storage2
  • storage3

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 magazynu 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": "2022-09-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ć funkcji kopiowania w sekcji danych wyjściowych.

Użyj nazwy symbolicznej

Nazwa symboliczna zostanie przypisana do pętli kopiowania zasobów. Indeks pętli jest oparty na 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": "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]"
    }
  }
}

Jeśli indeks jest wartością środowiska uruchomieniowego, sformatuj odwołanie samodzielnie. Na 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 Depends on resources in a loop (Zależności od zasobów w pętli).

Szeregowe lub równoległe

Domyślnie Resource Manager tworzy zasoby równolegle. Nie ma 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że być konieczne rozłożenie aktualizacji tak, aby tylko określona liczba została zaktualizowana w dowolnym momencie.

Aby szeregowo wdrożyć więcej niż jedno wystąpienie zasobu, ustaw wartość mode na szeregową i batchSize liczbę wystąpień do wdrożenia naraz. W trybie szeregowym Resource Manager tworzy zależność od wcześniejszych wystąpień w pętli, więc nie uruchamia 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": "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": {}
    }
  ]
}

Właściwość mode akceptuje również wartość równoległą, 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óre zwykle definiuje się jako zagnieżdżone 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 typu i nazwy.

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 być na tym samym poziomie co fabryka danych, ale nadal jest to zasób podrzędny fabryki danych. Relacje między zestawem danych i fabryką danych są zachowywane za pomocą właściwości typu i nazwy. Ponieważ typ nie może już być wywnioskowany z jego pozycji w szablonie, należy podać w pełni kwalifikowany typ w formacie: {resource-provider-namespace}/{parent-resource-type}/{child-resource-type}.

Aby ustanowić relację nadrzędną/podrzędną z wystąpieniem fabryki danych, podaj nazwę zestawu danych, który zawiera nazwę zasobu nadrzędnego. Użyj formatu: {parent-resource-name}/{child-resource-name}.

Poniższy przykład przedstawia 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.

Template Opis
Kopiowanie magazynu Wdraża więcej niż jedno konto magazynu z numerem indeksu w nazwie.
Magazyn kopii szeregowej Wdraża jednocześnie kilka kont magazynu. Nazwa zawiera numer indeksu.
Kopiowanie magazynu z tablicą Wdraża kilka kont magazynu. Nazwa zawiera wartość z tablicy.
Kopiowanie grupy zasobów Wdraża wiele grup zasobów.

Następne kroki