次の方法で共有


ARM テンプレートでのリソースの反復処理

この記事では、Azure Resource Manager テンプレート (ARM テンプレート) でリソースの複数のインスタンスを作成する方法について説明します。 テンプレートのリソース セクションにコピー ループを追加することで、デプロイするリソースの数を動的に設定できます。 また、テンプレート構文を繰り返す必要も回避できます。

プロパティ変数および出力でコピー ループを使用することもできます。

リソースをデプロイするかどうかを指定する必要がある場合は、 condition 要素を参照してください。

ヒント

ARM テンプレートと同じ機能を備え、構文も使いやすいため、Bicep をお勧めします。 詳細については、 ループを参照してください。

構文

テンプレートの resources セクションに 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 では、カウントの 0 はサポートされていません。

コピー ループで 完全モードのデプロイ を使用する場合は注意してください。 完全モードでリソース グループに再デプロイすると、コピー ループの解決後にテンプレートで指定されていないリソースはすべて削除されます。

リソースの反復処理

次の例では、 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() は 0 から始まります。 そのため、次の例を示します。

"name": "[format('storage{0}', copyIndex())]",

これらの名前を作成します。

  • ストレージ0
  • ストレージ1
  • ストレージ2

インデックス値をオフセットするには、copyIndex() 関数に値を渡します。 反復回数はコピー要素で指定されますが、 copyIndex の値は指定された値によってオフセットされます。 そのため、次の例を示します。

"name": "[format('storage{0}', copyIndex(1))]",

これらの名前を作成します。

  • ストレージ1
  • ストレージ2
  • ストレージ3

コピー操作は、配列内の各要素を反復処理できるため、配列を操作するときに役立ちます。 配列の length 関数を使用して反復回数を指定し、配列内の現在のインデックスを取得する copyIndex します。

次の例では、パラメーターに指定された名前ごとに 1 つのストレージ アカウントを作成します。

{
  "$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": {}
    }
  ]
}

デプロイされたリソースから値を返す場合は、 出力セクションでコピーを使用できます。

シンボリック名を使用する

シンボリック名 は、リソース コピー ループに割り当てられます。 ループ インデックスは 0 から始まります。 次の例では、 myStorages[1] リソース ループ内の 2 番目のリソースを参照しています。

{
  "$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シリアル に設定し、一度にデプロイするインスタンスの数に batchSize します。 シリアル モードでは、Resource Manager はループ内の以前のインスタンスに依存関係を作成するため、前のバッチが完了するまで 1 つのバッチは開始されません。

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 も受け入れます。

子リソースの反復処理

子リソースにコピー ループを使用することはできません。 通常、別のリソース内で入れ子として定義するリソースの複数のインスタンスを作成するには、そのリソースを最上位のリソースとして作成する必要があります。 型と名前のプロパティを使用して、親リソースとのリレーションシップを定義します。

たとえば、通常、データセットをデータ ファクトリ内の子リソースとして定義するとします。

{
  "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"
  },
  ...
}]

サンプル テンプレート

次の例は、リソースまたはプロパティの複数のインスタンスを作成する一般的なシナリオを示しています。

テンプレート 説明
ストレージのコピー 名前にインデックス番号を持つ複数のストレージ アカウントをデプロイします。
シリアル コピー ストレージ 一度に複数のストレージ アカウントをデプロイします。 名前にはインデックス番号が含まれます。
配列を使用してストレージをコピーする 複数のストレージ アカウントをデプロイします。 名前には配列の値が含まれます。
リソース グループのコピー 複数のリソース グループをデプロイします。

次のステップ