您现在访问的是微软AZURE全球版技术文档网站,若需要访问由世纪互联运营的MICROSOFT AZURE中国区技术文档网站,请访问 https://docs.azure.cn.

Azure 资源管理器模板中的资源、属性或变量迭代Resource, property, or variable iteration in Azure Resource Manager templates

本文介绍如何在 Azure 资源管理器模板中创建资源、变量或属性的多个实例。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.

与资源一起使用时,复制对象的格式如下: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>
}

与变量或属性一起使用时,复制对象的格式如下: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. 有关教程,请参阅教程:使用资源管理器模板创建多个资源实例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. 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 的早期版本不支持计数为零。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.

无论与资源、变量还是属性一起使用,count 的限制都是相同的。The limits for the count are the same whether used with a resource, variable, or property.

资源迭代Resource iteration

如果要在部署中创建资源的多个实例,请将 copy 元素添加到资源类型。If you want to create more than one instance of a resource in a deployment, 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:

  • 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. 因此,以下示例: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:

  • storagecontosostoragecontoso
  • storagefabrikamstoragefabrikam
  • storagecohostoragecoho

默认情况下,资源管理器将并行创建资源。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/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.

有关将副本与嵌套的模板配合使用的信息,请参阅使用副本For information about using copy with nested templates, see Using copy.

属性迭代Property iteration

若要为资源上的属性创建多个值,请在属性元素中添加一个 copy 数组。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 - the name of the property to create several values for
  • 计数 - 要创建的值的数目。count - the number of values to create.
  • 输入 - 包含要分配给属性的值的对象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.

Resource Manager 在部署期间扩展 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"
        }
      ],
      ...

copy 元素是一个数组,因此,可以为资源指定多个属性。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 属性。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 属性,或在变量部分的顶层使用该属性。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. 例如,在上一示例中名为 top-level-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
  }
]

名为 top-level-string-array 的变量返回: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 元素中提供 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. 以下示例演示了如何在部署虚拟机之前部署 3 个存储帐户。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 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

不能对子资源使用 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"
  },
  ...
}]

示例模板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.
复制变量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. 有关参数,请参阅多个 NSG 参数文件For the parameter, see multiple NSG parameter file.

后续步骤Next steps