Поделиться через


Итерация ресурсов в шаблонах ARM

В этой статье показано, как создать несколько экземпляров ресурса в шаблоне Azure Resource Manager (шаблон ARM). Добавив цикл копирования в раздел ресурсов шаблона, можно динамически задать количество ресурсов для развертывания. Кроме того, не следует повторять синтаксис шаблона.

Можно также использовать цикл копирования со свойствами, переменными и выходными данными.

Если вам нужно указать, развертывается ли ресурс вообще, см. элемент condition.

Подсказка

Мы рекомендуем Bicep , так как он предлагает те же возможности, что и шаблоны ARM, и синтаксис проще использовать. Чтобы узнать больше, см. циклы.

Синтаксис

copy Добавьте элемент в раздел ресурсов шаблона для развертывания нескольких экземпляров ресурса. Элемент copy имеет следующий общий формат:

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

Свойство name является любым значением, определяющим цикл. Свойство count указывает количество итераций, которые требуется использовать для типа ресурса.

Используйте свойства mode и batchSize для указания, развертываются ли ресурсы параллельно или последовательно. Эти свойства описаны в разделе "Последовательный" или "Параллельный".

Ограничения копирования

Число не может превышать 800.

Число не может быть отрицательным числом. Это может быть нулевым, если вы развертываете шаблон с помощью последней версии Azure CLI, PowerShell или REST API. В частности, необходимо использовать следующее:

  • Azure PowerShell 2.6 или более поздней версии
  • Azure CLI 2.0.74 или более поздней версии
  • REST API версии 2019-05-10 или более поздней
  • Связанные развертывания должны использовать API версии 2019-05-10 или более поздней для типа ресурса развертывания.

Более ранние версии PowerShell, CLI и REST API не поддерживают ноль для подсчета.

Будьте осторожны с использованием развертывания в полном режиме с циклом копирования. При повторном развертывании с полным режимом в группе ресурсов все ресурсы, которые не указаны в шаблоне после разрешения цикла копирования, удаляются.

Итерация ресурсов

В следующем примере создается количество учетных записей хранения, указанных в параметре 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": {}
    }
  ]
}

Обратите внимание, что имя каждого ресурса включает copyIndex() функцию, которая возвращает текущую итерацию в цикле. copyIndex() отсчитывается, начиная с нуля. Итак, следующий пример:

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

Создает следующие имена:

  • хранилище0
  • хранилище1
  • хранилище2

Чтобы сместить значение индекса, можно передать нужное значение в функцию copyIndex(). Число итераций по-прежнему указывается в элементе копирования, но значение copyIndex изменяется на указанное значение. Итак, следующий пример:

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

Создает следующие имена:

  • хранилище1
  • хранилище2
  • storage3

Операция копирования полезна при работе с массивами, так как вы можете выполнять итерацию по каждому элементу в массиве. length Используйте функцию в массиве, чтобы указать количество итераций и copyIndex получить текущий индекс в массиве.

В следующем примере создается одна учетная запись хранения для каждого имени, предоставленного в параметре.

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

Если вы хотите возвращать значения из развернутых ресурсов, можно использовать копию в разделе выходных данных.

Использование символьного имени

Символьное имя будет назначено циклам копирования ресурсов. Индекс цикла начинается с нуля. В следующем примере myStorages[1] ссылается на второй ресурс в цикле ресурсов.

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

Если индекс является значением среды выполнения, отформатируйте ссылку самостоятельно. Например.

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

Символьные имена можно использовать в массивах dependsOn. Если символическое имя предназначено для цикла копирования, все ресурсы в цикле добавляются в качестве зависимостей. Дополнительные сведения см. в разделе "Зависит от ресурсов в цикле".

Последовательный или параллельный

По умолчанию Resource Manager создает ресурсы параллельно. Он не ограничивает количество ресурсов, развернутых параллельно, кроме общего ограничения 800 ресурсов в шаблоне. Порядок, в котором они создаются, не гарантируется.

Однако может потребоваться указать, что ресурсы развертываются в последовательности. Например, при обновлении рабочей среды может потребоваться распределить обновления так, чтобы одновременно обновлялось только определённое количество.

Чтобы последовательно развернуть более одного экземпляра ресурса, установите mode в serial и batchSize в количество экземпляров, которые необходимо развернуть за раз. В последовательном режиме Resource Manager создает зависимость от предыдущих экземпляров цикла, поэтому она не запускает один пакет до завершения предыдущего пакета.

Значение для batchSize не может превышать значение count в элементе 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": {}
    }
  ]
}

Свойство mode также принимает параллельное значение, которое является значением по умолчанию.

Итерация для дочернего ресурса

Нельзя использовать цикл копирования для дочернего ресурса. Чтобы создать несколько экземпляров ресурса, который обычно определяется как вложенный в другой ресурс, необходимо создать этот ресурс как ресурс верхнего уровня. Связь с родительским ресурсом определяется с помощью свойств типа и имени.

Например, предположим, что обычно набор данных определяется как дочерний ресурс в фабрике данных.

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

Чтобы создать несколько наборов данных, переместите его за пределы фабрики данных. Набор данных должен находиться на том же уровне, что и фабрика данных, но он по-прежнему является дочерним ресурсом фабрики данных. Связь между набором данных и фабрикой данных сохраняется с помощью свойств типа и имени. Так как тип больше не может быть выведен из его позиции в шаблоне, необходимо указать полный тип в формате: {resource-provider-namespace}/{parent-resource-type}/{child-resource-type}

Чтобы установить связь родительского или дочернего объекта с экземпляром фабрики данных, укажите имя набора данных, включающего имя родительского ресурса. Используйте формат {parent-resource-name}/{child-resource-name}.

В следующем примере показана реализация.

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

Образцы шаблонов

В следующих примерах показаны распространенные сценарии создания нескольких экземпляров ресурса или свойства.

Шаблон Описание
Копирование хранилища Развертывает несколько учетных записей хранения с номером индекса в имени.
Хранилище последовательного копирования Развертывает несколько учетных записей хранения одновременно. Имя содержит индексный номер.
Копия хранилища, используя массив Развертывает несколько учетных записей хранения. Имя содержит значение из массива.
Копирование группы ресурсов Развертывает несколько групп ресурсов.

Дальнейшие шаги