ARM 模板中的资源迭代
本文介绍如何在 Azure 资源管理器模板(ARM 模板)中创建一个资源的多个实例。 通过将 copy 循环添加到模板的 resources 节,可以动态设置要部署的资源数。 还可以避免重复模板语法。
还可以将 copy 循环用于 properties、variables 和 outputs。
如需指定究竟是否部署资源,请参阅 condition 元素。
语法
将 copy
元素添加到模板的 resources 节可部署资源的多个实例。 copy
元素采用以下常规格式:
"copy": {
"name": "<name-of-loop>",
"count": <number-of-iterations>,
"mode": "serial" <or> "parallel",
"batchSize": <number-to-deploy-serially>
}
name
属性是标识循环的任何值。 count
属性指定要对该资源类型进行的迭代次数。
使用 mode
和 batchSize
属性指定是并行还是按顺序部署资源。 串行或并行中介绍了这些属性。
复制限制
count 不能超过 800。
count 不能为负数。 如果使用最新版本的 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 不支持将 count 设为零。
将完整模式部署与 copy 循环一起使用时要小心。 如果以完整模式重新部署到资源组,则在解析复制循环后会删除模板中未指定的任何资源。
资源迭代
以下示例创建在 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())]",
将创建以下名称:
- storage0
- storage1
- storage2
若要偏移索引值,可以在 copyIndex()
函数中传递一个值。 迭代次数仍在 copy 元素中指定,但 copyIndex
的值会偏移一个指定的值。 因此,以下示例:
"name": "[format('storage{0}', copyIndex(1))]",
将创建以下名称:
- storage1
- storage2
- 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 数组。 如果符号名称用于复制循环,则循环中的所有资源将添加为依赖项。 有关详细信息,请参阅“依赖于循环中的资源”。
串行或并行
默认情况下,资源管理器并行创建资源。 除了模板中 800 个资源的总限制外,它对并行部署的资源数量没有限制。 不会保证它们的创建顺序。
但是,你可能希望将资源指定为按顺序部署。 例如,在更新生产环境时,可能需要错开更新,使任何一次仅更新一定数量。
若要按顺序部署多个资源实例,请将 mode
设置为“串行”,并将 batchSize
设置为一次要部署的实例数量。 在串行模式下,资源管理器会在循环中创建早前实例的依赖项,以便在前一个批处理完成之前它不会启动一个批处理。
batchSize
的值不能超过 copy 元素中 count
的值。
{
"$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
属性也接受“parallel”(默认值)。
子资源的迭代
不能对子资源使用 copy 循环。 要创建通常定义为嵌套在另一个资源中的资源的多个实例,必须将该资源创建为顶级资源。 可以通过 type 和 name 属性定义与父资源的关系。
例如,假设用户通常会将某个数据集定义为数据工厂中的子资源。
{
"resources": [
{
"type": "Microsoft.DataFactory/factories",
"name": "exampleDataFactory",
...
"resources": [
{
"type": "datasets",
"name": "exampleDataSet",
"dependsOn": [
"exampleDataFactory"
],
...
}
]
...
}
]
}
若要创建多个数据集,请将其移出数据工厂。 数据集必须与数据工厂处于同一级别,但它仍是数据工厂的子资源。 可以通过 type 和 name 属性保留数据集和数据工厂之间的关系。 由于类型不再可以从其在模板中的位置推断,因此必须按以下格式提供完全限定的类型: {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"
},
...
}]
示例模板
以下示例展示了创建资源或属性的多个实例的常见方案。
模板 | 说明 |
---|---|
复制存储 | 部署名称中带索引号的多个存储帐户。 |
串行复制存储 | 一次部署多个存储帐户。 名称包含索引号。 |
使用数组的复制存储 | 部署多个存储帐户。 名称包含数组中的值。 |
复制资源组 | 部署多个资源组。 |
后续步骤
- 若要设置在复制循环中创建的资源的依赖项,请参阅在 ARM 模板中定义部署资源的顺序。
- 若要完成教程,请参阅教程:使用 ARM 模板创建多个资源实例。
- 有关 copy 循环的其他用法,请参阅:
- 有关将副本与嵌套的模板配合使用的信息,请参阅使用副本。