使用 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() 返回值 2copyIndex() 的语法如下所示:

copyIndex(loopName, offset)

copyIndex() 函数具有两个不同的输入参数 loopNameoffsetoffset 参数始终是可选的,并且用于从当前索引偏移。 添加为 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 元素具有值为 storagecopyname 属性。 依赖的资源(一个存储帐户)正在等待 copy 元素操作完成。 此情况由 "dependsOn": ["storagecopy"] 表示。

因此,ARM 模板会切换到这两个资源之间的串行部署模式。 这可能会影响部署的吞吐量速度,但你已表示你关注的是特定部署顺序,现在优先级最高。