使用 copy 元素创建多个资源实例
目前为止,已在模板的资源列表中声明了资源。 部署时,最终会获得资源列表中指定的每个项的一个实例。 你可能想要创建特定资源的多个实例。 例如,可能需要在虚拟网络中创建多个子网。
考虑创建多个实例以及循环访问构造时,请考虑以下问题和要点:
- 我是否需要多个副本:对于更简单的场景,可能不需要。 对于更高级的场景(如子网或虚拟机),可能需要考虑是否需要某个对象的多个副本。
- 我是否依赖于资源:通常,Azure 资源管理器非常适合用于确定需要按哪种顺序构造哪些内容,以便 Azure 资源管理器模板中的引用起到作用。但在某些情况下,可能需要指定顺序。
- 定义命名方案:你希望为资源指定有意义的名称。 出于此原因,需要在部署时传递参数。 如果有多个副本,则可能需要具有更精细的控制,并基于你当前所处的复制序列中的迭代来命名。
- 配置和控制资源创建:你可能想要限制在生产环境中创建的资源数。 可以通过将资源创建配置为“串行”或“并行”来实现此目的。
- 复制其他类型:资源并不是可创建多个副本并循环访问的唯一对象。 事实上,可以对属性、变量和输出执行相同的操作。
- 父-子:可能需要在资源中配置父子关系。
创建多个实例
可以使用循环构造来节省击键次数。 如果需要多次重复,在名称和类型上非常类似,并且只有细微差异,则可以从使用 copy 元素中获益。
copy 元素是一段 JSON,可用于多种类型的构造,如资源、属性、变量和输出。 copy 元素的语法包含密钥 copy 和数组作为值。 例如:"copy": []
。
数组采用多个元素,每个元素都是由一组属性组成的对象 {}
。 这些属性的含义取决于它们所使用的构造类型。 通常,所有 copy
元素构造都有一个共同的属性:count
。 此属性决定特定类型的构造所需的实例数。 大多数构造还允许 name
属性,该属性提供可在代码的其他部分中参考的引用。 使用的其他属性特定于构造。
如何选择
你可能会问:“如果我可以使用多种类型的构造上的 copy
元素,应选择哪一种,何时选择,以及我是否可以在模板中使用多种类型?”
这一切都取决于你的用例。 使用资源迭代可以创建资源的多个副本,并可以使用多个存储帐户(如果需要)。 另一方面,使用属性迭代可以在一个资源内创建多个属性。 这样可以为你节省击键次数和时间,并且更好地了解模板中有重复部分的位置。
可以在模板中的多个位置使用 copy
元素。 你可以使用 copy
元素创建多个资源,同时在同一个模板中创建多个类似的变量。
工作原理
copy
元素的工作原理是计算并替换 copy
语句。 替换是在根据 copy
字段中所述多次重复的 copy
语句中定义的结果。
使用 copy
的定义如以下示例所示:
"copy": [
{
"name": "dataDisks",
"count": 2,
"input": {
"diskSizeGB": 1023,
"lun": "[copyIndex('dataDisks')]",
"createOption": "Empty"
}
}
]
请注意 count: 2
条目。 值 2
表示你希望上述表达式扩大为两个条目。 结果如下:
"dataDisks": [
{
"lun": 0,
"createOption": "Empty",
"diskSizeGB": 1023
},
{
"lun": 1,
"createOption": "Empty",
"diskSizeGB": 1023
}
你可以看到 name
属性的值已成为属性名称,并且 input
属性的内容已成为 JSON 的重复部分。
注意
copy 表达式及其输出的区别在于所使用的表达式类型。 当表达式转换为一系列重复的语句时,上述示例就会对发生的情况有一个很好的了解。
可以复制的数量存在限制。 目前限制为 800 个条目。
重要
有关确切限制的详细信息,请参阅 ARM 模板中的资源迭代。
控制迭代
Helper 函数可帮助你引用数组中的特定索引。 函数 copyIndex()
返回当前索引。 例如,对于第三个重复项,copyIndex()
返回值 2
。 copyIndex()
的语法如下所示:
copyIndex(loopName, offset)
copyIndex()
函数具有两个不同的输入参数 loopName
和 offset
。 offset
参数始终是可选的,并且用于从当前索引偏移。 添加为 offset
值的任何内容都会添加到当前索引。 如果当前索引返回 2
,并将 1
指定为偏移量,则 copyIndex()
函数将返回 3
。
loopName
参数是可选的或必需的,具体取决于它的使用位置。 如果在 properties
构造中使用,则它是必需的,如果在 resources
数组中使用,则它是可选的。 下面是必需的示例:
"properties": {
"storageProfile": {
"copy": [
{
"name": "dataDisks",
"count": "[parameters('numberOfDataDisks')]",
"input": {
"diskSizeGB": 1023,
"lun": "[copyIndex('dataDisks')]",
"createOption": "Empty"
}
}
]
}
}
请注意 copy
元素在 properties
构造内的用法,并且 copyIndex()
的 loopName
指定为 copyIndex('dataDisks')
。
下面是一个示例,其中 loopName
不是必需的:
{
"type": "Microsoft.Network/virtualNetworks",
"apiVersion": "2018-04-01",
"name": "[concat(parameters('vnetname'), copyIndex())]",
}
它显示了要声明的资源,并且在没有参数的情况下调用 copyIndex()
,因为它正在资源的上下文中使用。
配置部署
使用资源的 copy
元素时,最终会创建许多外观类似的资源。
有时,你可能希望控制资源的创建方式和创建顺序。 控制顺序的原因可能如下:
- 环境限制。 根据你部署到的环境,你可能想要限制此环境受部署影响的程度。 在生产环境中,最好限制在同一时间受影响的资源数。 你可以配置部署模式以控制同时部署的资源数。
- 依赖项。 在冒险创建所需的资源之前,你可能会依赖于已存在的资源。 为了表示此类依赖关系,有一个名为
dependsOn
的构造。
部署模式和 copy
你可能想要确保 copy
构造创建的一组资源都是在其他资源之前创建的。 如果是这样,则需要表示这种情况。 请记住,发挥作用的是资源管理器使用的部署模式。 支持两种模式:
- 串行。 将资源设置为此部署模式意味着将依次创建资源。 在此模式下,还应将属性
batchSize
设置为确定使用此模式部署的资源数。 新的批处理在上一批处理完成前无法启动。 例如,你可能想要在生产环境中按此方式进行限制,这对随时限制受影响的资源数非常重要。 - 并行。 此模式是默认部署模式。 优点是高吞吐量,因此模板的处理速度更快。 缺点在于不能保证顺序,并且它可能不是生产环境所需的。
依赖项
在 copy
元素的上下文中,需要告知资源部分所等待的依赖关系。 可通过按以下 JSON 格式的名称进行引用来实现此依赖关系:
"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"],
}
]
请注意,copy
元素具有值为 storagecopy
的 name
属性。 依赖的资源(一个存储帐户)正在等待 copy
元素操作完成。 此情况由 "dependsOn": ["storagecopy"]
表示。
因此,ARM 模板会切换到这两个资源之间的串行部署模式。 这可能会影响部署的吞吐量速度,但你已表示你关注的是特定部署顺序,现在优先级最高。