本文介绍如何在 Azure 资源管理器模板(ARM 模板)中创建多个资源实例。 通过将复制循环添加到模板的资源部分,可以动态设置要部署的资源数。 还可以避免重复模板语法。
如果您需要指定资源是否已部署,请参阅 condition 元素。
将 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 不支持将零作为有效计数。
将完整模式部署与 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
- 存储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 数组。 如果符号名称用于复制循环,则循环中的所有资源将添加为依赖项。 有关详细信息,请参阅 “依赖于循环中的资源”。
默认情况下,资源管理器并行创建资源。 它对并行部署的资源数量没有限制,除了模板中的资源总数限制为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
属性还接受 并行,即默认值。
不能对子资源使用复制循环。 若要创建通常定义为嵌套在另一个资源中的资源的多个实例,必须改为将该资源创建为顶级资源。 通过类型和名称属性定义与父资源的关系。
例如,假设通常将数据集定义为数据工厂中的子资源。
{
"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"
},
...
}]
以下示例演示了创建资源或属性的多个实例的常见方案。
模板 | DESCRIPTION |
---|---|
复制存储 | 部署多个带有名称索引号的存储帐户。 |
串行复制存储 | 一次部署多个存储帐户。 该名称包括索引号。 |
使用数组复制存储 | 部署多个存储帐户。 该名称包括数组中的值。 |
复制资源组 | 部署多个资源组。 |
- 若要设置对在复制循环中创建的资源的依赖项,请参阅 定义在 ARM 模板中部署资源的顺序。
- 若要完成教程,请参阅 教程:使用 ARM 模板创建多个资源实例。
- 有关复制循环的其他用途,请参阅:
- 有关将复制与嵌套模板一起使用的信息,请参阅 使用复制。