Итерация ресурсов, свойств или переменных в шаблонах Azure Resource ManagerResource, property, or variable iteration in Azure Resource Manager templates

В этой статье показано, как создать более одного экземпляра ресурса, переменной или свойства в шаблоне Azure Resource Manager.This article shows you how to create more than one instance of a resource, variable, or property in your Azure Resource Manager template. Чтобы создать несколько экземпляров, добавьте copy объект в шаблон.To create multiple instances, add the copy object to your template.

При использовании с ресурсом объект copy имеет следующий формат:When used with a resource, the copy object has the following format:

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

При использовании с переменной или свойством объект copy имеет следующий формат:When used with a variable or property, the copy object has the following format:

"copy": [
  {
      "name": "<name-of-loop>",
      "count": <number-of-iterations>,
      "input": <values-for-the-property-or-variable>
  }
]

Оба варианта использования описаны более подробно в этой статье.Both uses are described in greater detail in this article. См. статью Руководство: создание нескольких экземпляров ресурса с помощью шаблонов Resource Manager.For a tutorial, see Tutorial: create multiple resource instances using Resource Manager templates.

Если вам нужно указать, развернут ли ресурс, см. описание элемента condition.If you need to specify whether a resource is deployed at all, see condition element.

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

Чтобы указать число итераций, необходимо указать значение для свойства Count.To specify the number of iterations, you provide a value for the count property. Число не может превышать 800.The count can't exceed 800.

Число не может быть отрицательным числом.The count can't be a negative number. Если вы развертываете шаблон с REST API версии 2019-05-10 или более поздней, можно установить значение счетчика равным нулю.If you deploy a template with REST API version 2019-05-10 or later, you can set count to zero. Более ранние версии REST API не поддерживают нулевое значение для счетчика.Earlier versions of the REST API don't support zero for count. В настоящее время Azure CLI или PowerShell не поддерживают ноль для подсчета, но эта поддержка будет добавлена в следующем выпуске.Currently, Azure CLI or PowerShell don't support zero for count, but that support will be added in a future release.

Будьте внимательны при развертывании полного режима с помощью команды Copy.Be careful using complete mode deployment with copy. При повторном развертывании с полным режимом для группы ресурсов все ресурсы, не указанные в шаблоне после разрешения цикла копирования, удаляются.If you redeploy with complete mode to a resource group, any resources that aren't specified in the template after resolving the copy loop are deleted.

Ограничения для счетчика одинаковы, когда используются с ресурсом, переменной или свойством.The limits for the count are the same whether used with a resource, variable, or property.

Итерация ресурсаResource iteration

Чтобы во время развертывания создать один или несколько экземпляров ресурса, добавьте к типу ресурса элемент copy.When you must decide during deployment to create one or more instances of a resource, add a copy element to the resource type. В элементе Copy укажите число итераций и имя для этого цикла.In the copy element, specify the number of iterations and a name for this loop.

Для многократного создания ресурса используется следующий формат.The resource to create several times takes the following format:

{
  "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "resources": [
    {
      "apiVersion": "2016-01-01",
      "type": "Microsoft.Storage/storageAccounts",
      "name": "[concat(copyIndex(),'storage', uniqueString(resourceGroup().id))]",
      "location": "[resourceGroup().location]",
      "sku": {
        "name": "Standard_LRS"
      },
      "kind": "Storage",
      "properties": {},
      "copy": {
        "name": "storagecopy",
        "count": 3
      }
    }
  ],
  "outputs": {}
}

Обратите внимание, что имя каждого ресурса содержит функцию copyIndex(), которая возвращает текущую итерацию в цикле.Notice that the name of each resource includes the copyIndex() function, which returns the current iteration in the loop. copyIndex() отсчитывается, начиная с нуля.copyIndex() is zero-based. См. приведенный ниже пример.So, the following example:

"name": "[concat('storage', copyIndex())]",

Он создает следующие имена:Creates these names:

  • storage0;storage0
  • storage1;storage1
  • storage2.storage2.

Чтобы сместить значение индекса, можно передать нужное значение в функцию copyIndex().To offset the index value, you can pass a value in the copyIndex() function. Число итераций по-прежнему указывается в элементе Copy, но значение copyIndex смещается на указанное значение.The number of iterations is still specified in the copy element, but the value of copyIndex is offset by the specified value. См. приведенный ниже пример.So, the following example:

"name": "[concat('storage', copyIndex(1))]",

Он создает следующие имена:Creates these names:

  • storage1;storage1
  • storage2;storage2
  • storage3.storage3

Операция копирования удобна при работе с массивами, так как позволяет выполнить итерацию по каждому элементу в массиве.The copy operation is helpful when working with arrays because you can iterate through each element in the array. Используйте функцию length в массиве, чтобы указать число итераций, а также функцию copyIndex для получения текущего индекса в массиве.Use the length function on the array to specify the count for iterations, and copyIndex to retrieve the current index in the array. См. приведенный ниже пример.So, the following example:

"parameters": { 
  "org": { 
    "type": "array", 
    "defaultValue": [ 
      "contoso", 
      "fabrikam", 
      "coho" 
    ] 
  }
}, 
"resources": [ 
  { 
    "name": "[concat('storage', parameters('org')[copyIndex()])]", 
    "copy": { 
      "name": "storagecopy", 
      "count": "[length(parameters('org'))]" 
    }, 
    ...
  } 
]

Он создает следующие имена:Creates these names:

  • storagecontoso;storagecontoso
  • storagefabrikam;storagefabrikam
  • storagecoho.storagecoho

По умолчанию Resource Manager создает ресурсы параллельно.By default, Resource Manager creates the resources in parallel. Оно не ограничивает количество ресурсов, развернутых параллельно, за исключением общего ограничения в 800 ресурсов в шаблоне.It applies no limit to the number of resources deployed in parallel, other than the total limit of 800 resources in the template. Порядок, в котором они создаются, не гарантируется.The order in which they're created isn't guaranteed.

Тем не менее можно настроить последовательное развертывание ресурсов.However, you may want to specify that the resources are deployed in sequence. Например, при обновлении рабочей среды может потребоваться дифференцировать обновления, чтобы только определенное число элементов могло быть обновлено в любой момент времени.For example, when updating a production environment, you may want to stagger the updates so only a certain number are updated at any one time. Чтобы последовательно развернуть несколько экземпляров ресурса, задайте параметру mode значение serial, а в качестве значения batchSize введите число экземпляров, которое необходимо развернуть за раз.To serially deploy more than one instance of a resource, set mode to serial and batchSize to the number of instances to deploy at a time. В последовательном режиме Resource Manager создает зависимость от предыдущих экземпляров в цикле, поэтому он не начинает выполнение следующего пакета до завершения предыдущего.With serial mode, Resource Manager creates a dependency on earlier instances in the loop, so it doesn't start one batch until the previous batch completes.

Например, чтобы последовательно развернуть две учетные записи хранения за раз, используйте следующую команду:For example, to serially deploy storage accounts two at a time, use:

{
  "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "resources": [
    {
      "apiVersion": "2016-01-01",
      "type": "Microsoft.Storage/storageAccounts",
      "name": "[concat(copyIndex(),'storage', uniqueString(resourceGroup().id))]",
      "location": "[resourceGroup().location]",
      "sku": {
        "name": "Standard_LRS"
      },
      "kind": "Storage",
      "properties": {},
      "copy": {
        "name": "storagecopy",
        "count": 4,
        "mode": "serial",
        "batchSize": 2
      }
    }
  ],
  "outputs": {}
}

Свойство mode также принимает значение parallel, которое является значением по умолчанию.The mode property also accepts parallel, which is the default value.

Сведения об использовании инструкции Copy с вложенными шаблонами см. в разделе Использование копирования.For information about using copy with nested templates, see Using copy.

Итерация свойстваProperty iteration

Чтобы создать несколько значений для свойства ресурса, добавьте массив copy в элемент properties.To create more than one value for a property on a resource, add a copy array in the properties element. Этот массив содержит объекты, каждый из которых имеет следующие свойства:This array contains objects, and each object has the following properties:

  • name — имя свойства, для которого необходимо создать несколько значений;name - the name of the property to create several values for
  • count — количество значений, которые необходимо создатьcount - the number of values to create.
  • input — объект, содержащий значения для назначения свойству.input - an object that contains the values to assign to the property

В следующем примере показано, как применить массив copy к свойству dataDisks на виртуальной машине:The following example shows how to apply copy to the dataDisks property on a virtual machine:

{
  "name": "examplevm",
  "type": "Microsoft.Compute/virtualMachines",
  "apiVersion": "2017-03-30",
  "properties": {
    "storageProfile": {
      "copy": [{
        "name": "dataDisks",
        "count": 3,
        "input": {
          "lun": "[copyIndex('dataDisks')]",
          "createOption": "Empty",
          "diskSizeGB": "1023"
        }
      }],
      ...

Обратите внимание, что при использовании copyIndex в итерации свойства, необходимо указать имя итерации.Notice that when using copyIndex inside a property iteration, you must provide the name of the iteration. Вам не нужно указывать имя при использовании итерации ресурса.You don't have to provide the name when used with resource iteration.

Диспетчер ресурсов разворачивает массив copy во время развертывания.Resource Manager expands the copy array during deployment. Имя массива становится именем свойства.The name of the array becomes the name of the property. Входные значения становятся свойствами объекта.The input values become the object properties. Развернутый шаблон выглядит так:The deployed template becomes:

{
  "name": "examplevm",
  "type": "Microsoft.Compute/virtualMachines",
  "apiVersion": "2017-03-30",
  "properties": {
    "storageProfile": {
      "dataDisks": [
        {
          "lun": 0,
          "createOption": "Empty",
          "diskSizeGB": "1023"
        },
        {
          "lun": 1,
          "createOption": "Empty",
          "diskSizeGB": "1023"
        },
        {
          "lun": 2,
          "createOption": "Empty",
          "diskSizeGB": "1023"
        }
      ],
      ...

Элемент копирования представляет собой массив, поэтому вы можете указать несколько свойств для ресурса.The copy element is an array so you can specify more than one property for the resource. Добавьте объект для каждого свойства для создания.Add an object for each property to create.

{
  "name": "string",
  "type": "Microsoft.Network/loadBalancers",
  "apiVersion": "2017-10-01",
  "properties": {
    "copy": [
      {
        "name": "loadBalancingRules",
        "count": "[length(parameters('loadBalancingRules'))]",
        "input": {
          ...
        }
      },
      {
        "name": "probes",
        "count": "[length(parameters('loadBalancingRules'))]",
        "input": {
          ...
        }
      }
    ]
  }
}

Вы можете совместно использовать итерацию свойства и ресурса.You can use resource and property iteration together. Обращайтесь к итерации свойства по имени.Reference the property iteration by name.

{
  "type": "Microsoft.Network/virtualNetworks",
  "name": "[concat(parameters('vnetname'), copyIndex())]",
  "apiVersion": "2018-04-01",
  "copy":{
    "count": 2,
    "name": "vnetloop"
  },
  "location": "[resourceGroup().location]",
  "properties": {
    "addressSpace": {
      "addressPrefixes": [
        "[parameters('addressPrefix')]"
      ]
    },
    "copy": [
      {
        "name": "subnets",
        "count": 2,
        "input": {
          "name": "[concat('subnet-', copyIndex('subnets'))]",
          "properties": {
            "addressPrefix": "[variables('subnetAddressPrefix')[copyIndex('subnets')]]"
          }
        }
      }
    ]
  }
}

Итерация переменнойVariable iteration

Чтобы создать несколько экземпляров переменной, используйте свойство copy в разделе variables.To create multiple instances of a variable, use the copy property in the variables section. Вы создадите массив элементов на основе значения в свойстве input.You create an array of elements constructed from the value in the input property. Вы можете использовать свойство copy в переменной или на верхнем уровне раздела variables.You can use the copy property within a variable, or at the top level of the variables section. Если в итерации переменной используется copyIndex, необходимо указать имя итерации.When using copyIndex inside a variable iteration, you must provide the name of the iteration.

Простой пример создания массива строковых значений см. в разделе Копирование шаблона массива.For a simple example of creating an array of string values, see copy array template.

В примере ниже показано несколько разных способов создания переменных массива с динамически создаваемыми элементами.The following example shows several different ways to create array variables with dynamically constructed elements. Здесь показано использование копирования внутри переменной для создания массивов объектов и строк,It shows how to use copy inside a variable to create arrays of objects and strings. а также на верхнем уровне — для создания массивов объектов, строк и целых чисел.It also shows how to use copy at the top level to create arrays of objects, strings, and integers.

{
  "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {},
  "variables": {
    "disk-array-on-object": {
      "copy": [
        {
          "name": "disks",
          "count": 5,
          "input": {
            "name": "[concat('myDataDisk', copyIndex('disks', 1))]",
            "diskSizeGB": "1",
            "diskIndex": "[copyIndex('disks')]"
          }
        },
        {
          "name": "diskNames",
          "count": 5,
          "input": "[concat('myDataDisk', copyIndex('diskNames', 1))]"
        }
      ]
    },
    "copy": [
      {
        "name": "top-level-object-array",
        "count": 5,
        "input": {
          "name": "[concat('myDataDisk', copyIndex('top-level-object-array', 1))]",
          "diskSizeGB": "1",
          "diskIndex": "[copyIndex('top-level-object-array')]"
        }
      },
      {
        "name": "top-level-string-array",
        "count": 5,
        "input": "[concat('myDataDisk', copyIndex('top-level-string-array', 1))]"
      },
      {
        "name": "top-level-integer-array",
        "count": 5,
        "input": "[copyIndex('top-level-integer-array')]"
      }
    ]
  },
  "resources": [],
  "outputs": {
    "exampleObject": {
      "value": "[variables('disk-array-on-object')]",
      "type": "object"
    },
    "exampleArrayOnObject": {
      "value": "[variables('disk-array-on-object').disks]",
      "type" : "array"
    },
    "exampleObjectArray": {
      "value": "[variables('top-level-object-array')]",
      "type" : "array"
    },
    "exampleStringArray": {
      "value": "[variables('top-level-string-array')]",
      "type" : "array"
    },
    "exampleIntegerArray": {
      "value": "[variables('top-level-integer-array')]",
      "type" : "array"
    }
  }
}

Тип создаваемой переменной зависит от входного объекта.The type of variable that gets created depends on the input object. Например, переменная с именем верхнего уровня-Object-Array в предыдущем примере возвращает:For example, the variable named top-level-object-array in the preceding example returns:

[
  {
    "name": "myDataDisk1",
    "diskSizeGB": "1",
    "diskIndex": 0
  },
  {
    "name": "myDataDisk2",
    "diskSizeGB": "1",
    "diskIndex": 1
  },
  {
    "name": "myDataDisk3",
    "diskSizeGB": "1",
    "diskIndex": 2
  },
  {
    "name": "myDataDisk4",
    "diskSizeGB": "1",
    "diskIndex": 3
  },
  {
    "name": "myDataDisk5",
    "diskSizeGB": "1",
    "diskIndex": 4
  }
]

И переменная с именем верхнего уровня строкового массива возвращает:And, the variable named top-level-string-array returns:

[
  "myDataDisk1",
  "myDataDisk2",
  "myDataDisk3",
  "myDataDisk4",
  "myDataDisk5"
]

Зависимость от ресурсов в циклеDepend on resources in a loop

С помощью элемента dependsOn можно определить последовательность развертывания ресурсов.You specify that a resource is deployed after another resource by using the dependsOn element. Чтобы развернуть ресурс, который зависит от коллекции ресурсов в цикле, укажите имя цикла копирования в элементе dependsOn.To deploy a resource that depends on the collection of resources in a loop, provide the name of the copy loop in the dependsOn element. В следующем примере показано, как развернуть три учетные записи хранения до развертывания виртуальной машины.The following example shows how to deploy three storage accounts before deploying the Virtual Machine. Полное определение виртуальной машины не показано.The full Virtual Machine definition isn't shown. Обратите внимание, что параметр name элемента copy имеет значение storagecopy, а элемент dependsOn для виртуальных машин имеет значение storagecopy.Notice that the copy element has name set to storagecopy and the dependsOn element for the Virtual Machines is also set to storagecopy.

{
  "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {},
  "resources": [
    {
      "apiVersion": "2016-01-01",
      "type": "Microsoft.Storage/storageAccounts",
      "name": "[concat(copyIndex(),'storage', uniqueString(resourceGroup().id))]",
      "location": "[resourceGroup().location]",
      "sku": {
        "name": "Standard_LRS"
      },
      "kind": "Storage",
      "properties": {},
      "copy": {
        "name": "storagecopy",
        "count": 3
      }
    },
    {
      "apiVersion": "2015-06-15", 
      "type": "Microsoft.Compute/virtualMachines", 
      "name": "[concat('VM', uniqueString(resourceGroup().id))]",  
      "dependsOn": ["storagecopy"],
      ...
    }
  ],
  "outputs": {}
}

Итерация дочерних ресурсовIteration for a child resource

Нельзя включить дочерний ресурс в цикл копирования.You can't use a copy loop for a child resource. Чтобы создать несколько экземпляров ресурса, которые определяются как вложенные в другой ресурс, необходимо создать его как ресурс верхнего уровня.To create more than one instance of a resource that you typically define as nested within another resource, you must instead create that resource as a top-level resource. Вы можете определить связь с родительским ресурсом с помощью свойств type и name.You define the relationship with the parent resource through the type and name properties.

Предположим, вы определяете набор данных как дочерний ресурс фабрики данных.For example, suppose you typically define a dataset as a child resource within a data factory.

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

Чтобы создать несколько наборов данных, переместите его за пределы фабрики данных.To create more than one data set, move it outside of the data factory. Набор данных должен находиться на том же уровне, что и фабрика данных, но при этом он должен быть дочерним ресурсом фабрики данных.The dataset must be at the same level as the data factory, but it's still a child resource of the data factory. Вы можете сохранить связь между набором данных и фабрикой данных с помощью свойств type и name.You preserve the relationship between data set and data factory through the type and name properties. Так как тип нельзя определить по положению в шаблоне, укажите полное имя типа в следующем формате: {resource-provider-namespace}/{parent-resource-type}/{child-resource-type}.Since type can no longer be inferred from its position in the template, you must provide the fully qualified type in the format: {resource-provider-namespace}/{parent-resource-type}/{child-resource-type}.

Чтобы установить связь между родительским и дочерним ресурсами, укажите имя набора данных, которое включает имя родительского ресурса.To establish a parent/child relationship with an instance of the data factory, provide a name for the data set that includes the parent resource name. Используйте формат {parent-resource-name}/{child-resource-name}.Use the format: {parent-resource-name}/{child-resource-name}.

В следующем примере показано, как это сделать:The following example shows the implementation:

"resources": [
{
  "type": "Microsoft.DataFactory/datafactories",
  "name": "exampleDataFactory",
  ...
},
{
  "type": "Microsoft.DataFactory/datafactories/datasets",
  "name": "[concat('exampleDataFactory', '/', 'exampleDataSet', copyIndex())]",
  "dependsOn": [
    "exampleDataFactory"
  ],
  "copy": {
    "name": "datasetcopy",
    "count": "3"
  },
  ...
}]

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

Ниже приведены примеры распространенных сценариев для создания нескольких экземпляров ресурса или свойства.The following examples show common scenarios for creating more than one instance of a resource or property.

ШаблонTemplate ОписаниеDescription
Копирования хранилищаCopy storage Развертывает несколько учетных записей хранения с номером индекса в имени.Deploys more than one storage account with an index number in the name.
Последовательное копирование хранилищаSerial copy storage Последовательно развертывает несколько учетных записей хранения.Deploys several storage accounts one at time. Имя содержит номер индекса.The name includes the index number.
Копирования хранилища с массивомCopy storage with array Развертывает несколько учетных записей хранения.Deploys several storage accounts. Имя содержит значение из массива.The name includes a value from an array.
Развертывание виртуальной машины с переменным количеством дисков данныхVM deployment with a variable number of data disks Развертывает несколько дисков данных с виртуальной машиной.Deploys several data disks with a virtual machine.
Копирование переменныхCopy variables Демонстрирует разные способы итерации переменных.Demonstrates the different ways of iterating on variables.
Несколько правил безопасностиMultiple security rules Развертывает несколько правил безопасности в группу безопасности сети.Deploys several security rules to a network security group. Кроме того, этот шаблон создает правила безопасности на основе параметра.It constructs the security rules from a parameter. Чтобы узнать параметр, см. файл параметров нескольких групп безопасности сети.For the parameter, see multiple NSG parameter file.

Следующие шагиNext steps