ARM 範本中的資源反覆運算

此文章示範如何在 Azure Resource Manager 範本 (ARM 範本) 中建立資源的多個執行個體。 透過將複製迴圈新增至範本的 resources 區段,您可以動態設定要部署的資源數目。 您也可以避免重複範本語法。

您也可以搭配屬性變數輸出使用複製迴圈。

若需要指定是否要部署資源,請參閱條件元素

提示

我們建議使用 Bicep,因為其提供的功能與 ARM 範本相同,而且語法更易於使用。 若要深入了解,請參閱迴圈

語法

copy 元素新增至範本的 resources 區段,以部署資源的多個執行個體。 copy 元素的一般格式如下:

"copy": {
  "name": "<name-of-loop>",
  "count": <number-of-iterations>,
  "mode": "serial" <or> "parallel",
  "batchSize": <number-to-deploy-serially>
}

name 屬性是可識別迴圈的任何值。 count 屬性可指定您希望資源類型反覆運算的次數。

使用 modebatchSize 屬性來指定資源會以平行方式部署還是循序部署。 這些屬性會在循序或平行中加以描述。

複製限制

次數不能超過 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 不支援次數為零。

搭配複製迴圈使用完整模式部署時請小心。 如果您以完整模式重新部署至資源群組,則會刪除解析複製迴圈之後未在範本中指定的任何資源。

資源反覆項目

下列範例會建立 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": {}
    }
  ]
}

如果您想要從已部署的資源傳回值,您可以使用 outputs 區段中的 copy

使用符號名稱

符號名稱會指派給資源複製迴圈。 迴圈索引是以零為起始。 在下列範例中,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 陣列。 如果符號名稱是複製迴圈,迴圈中所有資源都會做為相依項目新增。 如需詳細資訊,請參閱相依於迴圈中的資源

循序或平行

根據預設,Resource Manager 會以平行方式建立資源。 除了範本中資源的總數限制為 800 個,其對於以平行方式部署的資源數目並無限制。 不保證資源會循序建立。

不過,建議您指定將資源部署在序列中。 例如,在更新生產環境時,您可以錯開更新,因此任何一次就只會更新特定數目。

若要以序列方式部署資源的多個執行個體,請將 mode 設定為 serial 並將 batchSize 設為一次要部署的執行個體數目。 透過序列模式,Resource Manager 會在迴圈中較早的執行個體上建立相依性,因此在前一批次完成之前,它不會啟動一個批次。

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,此為預設值。

子系資源反覆項目

您無法為子資源使用複製迴圈。 若要為通常會在另一個資源內定義為巢狀的資源建立多個執行個體,您必須改為將該資源建立為最上層資源。 您可以透過類型和名稱屬性,定義和父資源之間的關聯性。

例如,假設您通常將資料集定義為 Data Factory 中的子資源。

{
  "resources": [
    {
      "type": "Microsoft.DataFactory/factories",
      "name": "exampleDataFactory",
      ...
      "resources": [
        {
          "type": "datasets",
          "name": "exampleDataSet",
          "dependsOn": [
            "exampleDataFactory"
          ],
          ...
        }
      ]
      ...
    }
  ]
}

若要建立多個資料集,請將它移出資料處理站。 資料集必須位於與資料處理站相同的等級,但它仍是資料處理站的子資源。 您可以透過類型和名稱屬性保留資料集與資料處理站之間的關聯性。 由於無法再從類型位於範本中的位置來推斷類型,您必須以此格式提供完整的類型︰{resource-provider-namespace}/{parent-resource-type}/{child-resource-type}

若要建立與 Data Factory 執行個體的父/子關聯性,請提供包含父資源名稱之資料集的名稱。 使用格式︰{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"
  },
  ...
}]

範本的範例

下列範例顯示為資源或屬性建立多個執行個體的常見案例。

範本 描述
複製儲存體 利用名稱中的索引編號來部署多個儲存體帳戶。
序列複製儲存體 一次一個部署數個儲存體帳戶。 名稱包含索引編號。
以陣列複製儲存體 部署數個儲存體帳戶。 名稱包含陣列中的值。
複製資源群組 (英文) 部署多個資源群組。

下一步