Udostępnij za pośrednictwem


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 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.

Napiwek

Zalecamy Bicep , ponieważ oferuje te same możliwości co szablony usługi ARM, a składnia jest łatwiejsza w użyciu. 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 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ą identyfikującą pętlę. Właściwość count określa liczbę iteracji, które mają być przeznaczone dla typu zasobu.

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

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ć:

  • Program Azure PowerShell 2.6 lub nowszy
  • 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 wszystkie zasoby, które nie zostały określone w szablonie po usunięciu 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 w poniższym przykładzie:

"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 w poniższym przykładzie:

"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ć kopii 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ży od zasobów w pętli).

Szeregowe lub równoległe

Domyślnie usługa 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ż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 seryjnym usługa Resource Manager tworzy zależność od wcześniejszych wystąpień w pętli, więc nie uruchamia jednej partii, dopóki poprzednia partia nie zostanie ukończona.

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.

Szablon 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