Azure 资源管理器模板中的资源迭代Resource iteration in Azure Resource Manager templates

本文介绍如何在 Azure 资源管理器模板中创建一个资源的多个实例。This article shows you how to create more than one instance of a resource in your Azure Resource Manager template. 通过将 copy 元素添加到模板的 resources 节,可以动态设置要部署的资源数。By adding the copy element to the resources section of your template, you can dynamically set the number of resources to deploy. 还可以避免重复模板语法。You also avoid having to repeat template syntax.

还可以将 copy 用于 propertiesvariablesoutputsYou can also use copy with properties, variables and outputs.

如需指定究竟是否部署资源,请参阅 condition 元素If you need to specify whether a resource is deployed at all, see condition element.

资源迭代Resource iteration

copy 元素采用以下常规格式:The copy element has the following general format:

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

name 属性是标识循环的任何值。The name property is any value that identifies the loop. count 属性指定要对该资源类型进行的迭代次数。The count property specifies the number of iterations you want for the resource type.

使用 modebatchSize 属性指定是并行还是按顺序部署资源。Use the mode and batchSize properties to specify if the resources are deployed in parallel or in sequence. 串行或并行中介绍了这些属性。These properties are described in Serial or Parallel.

以下示例创建在 storageCount 参数中指定的存储帐户数目。The following example creates the number of storage accounts specified in the storageCount parameter.

{
    "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "storageCount": {
            "type": "int",
            "defaultValue": 2
        }
    },
    "resources": [
        {
            "type": "Microsoft.Storage/storageAccounts",
            "apiVersion": "2019-04-01",
            "name": "[concat(copyIndex(),'storage', uniqueString(resourceGroup().id))]",
            "location": "[resourceGroup().location]",
            "sku": {
                "name": "Standard_LRS"
            },
            "kind": "Storage",
            "properties": {},
            "copy": {
                "name": "storagecopy",
                "count": "[parameters('storageCount')]"
            }
        }
    ],
    "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:

  • storage0storage0
  • storage1storage1
  • 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:

  • storage1storage1
  • storage2storage2
  • storage3storage3

当使用数组时,copy 操作十分有用,因为这样可以迭代数组中的每个元素。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.

以下示例为参数中提供的每个名称创建一个存储帐户。The following example creates one storage account for each name provided in the parameter.

{
  "$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"
          ]
      }
  },
  "resources": [
    {
      "type": "Microsoft.Storage/storageAccounts",
      "apiVersion": "2019-04-01",
      "name": "[concat(parameters('storageNames')[copyIndex()], uniqueString(resourceGroup().id))]",
      "location": "[resourceGroup().location]",
      "sku": {
        "name": "Standard_LRS"
      },
      "kind": "Storage",
      "properties": {},
      "copy": {
        "name": "storagecopy",
        "count": "[length(parameters('storageNames'))]"
      }
    }
  ],
  "outputs": {}
}

如果要从已部署的资源返回值,可以使用在输出部分中复制If you want to return values from the deployed resources, you can use copy in the outputs section.

串行或并行Serial or Parallel

默认情况下,资源管理器将并行创建资源。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 设置为“串行”,并将 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. 在串行模式下,资源管理器会在循环中创建早前实例的依赖项,以便在前一个批处理完成之前它不会启动一个批处理。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/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "resources": [
    {
      "type": "Microsoft.Storage/storageAccounts",
      "apiVersion": "2019-04-01",
      "name": "[concat(copyIndex(),'storage', uniqueString(resourceGroup().id))]",
      "location": "[resourceGroup().location]",
      "sku": {
        "name": "Standard_LRS"
      },
      "kind": "Storage",
      "copy": {
        "name": "storagecopy",
        "count": 4,
        "mode": "serial",
        "batchSize": 2
      },
      "properties": {}
    }
  ],
  "outputs": {}
}

mode 属性也接受 parallel(它是默认值)。The mode property also accepts parallel, which is the default value.

依赖于循环中的资源Depend on resources in a loop

然后使用 dependsOn 元素指定部署一个资源后再部署另一个资源。You specify that a resource is deployed after another resource by using the dependsOn element. 若要部署的资源依赖于循环中的资源集合,请在 dependsOn 元素中提供 copy 循环的名称。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. 请注意,copy 元素的名称设置为 storagecopy,而虚拟机的 dependsOn 元素也设置为 storagecopyNotice that the copy element has name set to storagecopy and the dependsOn element for the virtual machine is also set to storagecopy.

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

子资源的迭代Iteration for a child resource

不能对子资源使用 copy 循环。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. 由于不能从模板中的位置推断 type,因此必须按以下格式提供完全限定的 type:{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"
  },
  ...
}]

复制限制Copy limits

count 不能超过 800。The count can't exceed 800.

count 不能为负数。The count can't be a negative number. 如果使用 Azure PowerShell 2.6 或更高版本、Azure CLI 2.0.74 或更高版本或者 REST API 版本 2019-05-10 或更高版本部署模板,则可以将 count 设置为零。If you deploy a template with Azure PowerShell 2.6 or later, Azure CLI 2.0.74 or later, or REST API version 2019-05-10 or later, you can set count to zero. 更早版本的 PowerShell、CLI 和 REST API 不支持将 count 设为零。Earlier versions of PowerShell, CLI, and the REST API don't support zero for count.

完整模式部署与复制一起使用时要小心。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.

示例模板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.
部署数据磁盘数量不定的 VMVM deployment with a variable number of data disks 通过虚拟机部署多个数据磁盘。Deploys several data disks with a virtual machine.
多个安全规则Multiple security rules 将多个安全规则部署到网络安全组。Deploys several security rules to a network security group. 这会从参数构造安全规则。It constructs the security rules from a parameter. 有关参数,请参阅多个 NSG 参数文件For the parameter, see multiple NSG parameter file.

后续步骤Next steps