copy 要素を使用して複数のリソース インスタンスを作成する

完了

これまでは、テンプレート内のリソース リストでリソースを宣言してきました。 デプロイすると、リソース リストで指定されている項目ごとに 1 つのインスタンスが作成されます。 特定のリソースのインスタンスを複数作成する必要がある場合があります。 たとえば、1 つの仮想ネットワーク内に複数のサブネットが必要になる場合があります。

多数のインスタンスを作成し、コンストラクトを反復処理する場合は、次の質問とポイントを考慮してください。

  • 複数のコピーが必要か: よりシンプルなシナリオでは、そうでない場合があります。 サブネットや仮想マシンのようなより高度なシナリオでは、何かの複数のコピーが必要かどうかの検討が必要な場合があります。
  • あるリソースに依存しているか: 通常、Azure Resource Manager は、Azure Resource Manager テンプレート内の参照が動作するように、何をどのような順序で構築する必要があるかを判断するのに適しています。ただし、状況によっては、順序の指定が必要になる場合があります。
  • 名前付けのスキームを定義する: リソースにわかりやすい名前を付けます。 そのため、デプロイ時に渡されるパラメーターを利用します。 複数のコピーがある場合は、より詳細な制御を行い、現在のコピー シーケンスでの反復に基づいて名前を付けることが必要になる場合があります
  • リソースの作成を構成して制御する: 運用環境で作成されるリソースの数を制限することがあります。 リソースの作成を "順次" または "並列" として構成することにより、それを行うことができます。
  • 他の種類をコピーする: 複数のコピーを作成して反復処理できるのはリソースだけではありません。 実際には、プロパティ、変数、出力についても同じことができます。
  • 親子: 場合によっては、リソース内で親子関係を構成する必要があります。

複数のインスタンスの作成

ループ コンストラクトを使用して、キーストロークを保存できます。 必要なのは何度も繰り返すことであり、名前や型はほとんど同じで、違いがほんのわずかである場合は、copy 要素を使用すると利点が得られる可能性があります。

"copy 要素" は JSON の一部であり、リソース、プロパティ、変数、出力などのさまざまな種類のコンストラクトで使用できます。 copy 要素の構文は、キーの copy と、値としての配列で構成されています。 (例: "copy": [])。

この配列では複数の要素を受け取り、各要素は一連のプロパティで構成されるオブジェクト {} です。 これらのプロパティは、使用されるコンストラクトの種類によって異なります。 通常、すべての copy 要素のコンストラクトには、1 つの共通プロパティ count があります。 このプロパティにより、特定の種類のコンストラクトのインスタンス数が決まります。 また、ほとんどのコンストラクトでは、コードの他の部分で参照できる name プロパティも使用できます。 使用されるその他のプロパティは、コンストラクトに固有です。

選択するもの

次のようなことを確認したい場合があります。"さまざまな種類のコンストラクトで copy 要素を使用できるとしたら、どれをどのようなときに選択する必要があるのか。また 1 つのテンプレートで複数の種類を使用できるのか"

すべてはユース ケースによって異なります。 "リソースの反復" を使用すると、リソースの多くのコピーを作成でき、たとえば、多くのストレージ アカウントが必要な場合に使用すると有効です。 一方、"プロパティの反復" を使用すると、1 つのリソース内に多数のプロパティを作成できます。 キーストロークと時間を節約でき、テンプレート内で繰り返されている部分に最適です。

copy 要素は、テンプレート内の多くの場所で使用できます。 copy 要素を使用すると多くのリソースを作成できますが、同じテンプレート内に多数の似たような変数を作成することもできます。

しくみ

copy 要素は、copy ステートメントを評価して置き換えることで機能します。 置き換えの結果として、copy ステートメントで定義されているものが、copy フィールドで指定されている回数だけ繰り返されます。

次の例は、copy を使用した定義がどのようになるかを示しています。

"copy": [
  {
    "name": "dataDisks",
    "count": 2,
    "input": {
      "diskSizeGB": 1023,
      "lun": "[copyIndex('dataDisks')]",
      "createOption": "Empty"
    }
  }
]

count: 2 というエントリに注意してください。 2 という値は、上記の式を 2 つのエントリに展開することを意味します。 結果は次のようになります。

"dataDisks": [
{
  "lun": 0,
  "createOption": "Empty",
  "diskSizeGB": 1023
},
{
  "lun": 1,
  "createOption": "Empty",
  "diskSizeGB": 1023
}

name プロパティの値がプロパティ名になり、input プロパティの内容が JSON の繰り返される部分になることがわかります。

Note

copy 式とその出力は、使用される式の種類によって異なります。 上の例を見ると、式が一連の繰り返されるステートメントに変換されるとどうなるかがよくわかります。

コピーできる数には制限があります。 現時点での制限は 800 エントリです。

重要

正確な制限の詳細については、「ARM テンプレートでのリソースの反復処理」を参照してください。

反復を制御する

配列内の特定のインデックスを参照するのに役立つヘルパー関数が用意されています。 関数 copyIndex() からは、現在のインデックスが返されます。 たとえば、3 番目の繰り返しエントリの場合、copyIndex() から 2 値が返されます。 copyIndex() の構文は、次のようになります。

copyIndex(loopName, offset)

copyIndex() 関数には、2 つの異なる入力パラメーター loopNameoffset があります。 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()copyIndex('dataDisks') として指定された loopName があることに注意してください。

次に、loopName が必須でない場合の例を示します。

{
  "type": "Microsoft.Network/virtualNetworks",
  "apiVersion": "2018-04-01",
  "name": "[concat(parameters('vnetname'), copyIndex())]",
}

リソースが宣言されており、copyIndex() はパラメーターなしで呼び出されています。これはリソースのコンテキストで使用されているためです。

展開を構成する

copy 要素をリソースに使用すると、似たようなさまざまなリソースが作成されます。

場合によっては、リソースの作成方法と順序の制御が必要になることがあります。 順序を制御する理由としては次のようなものがあります。

  • 環境による制限。 デプロイ対象の環境によっては、この環境がデプロイによって影響を受ける量を制限することが必要な場合があります。 運用環境では、一度に影響を受けるリソースの数を制限することに意味があります。 "デプロイ モード" を構成して、同時にデプロイされるリソースの数を制御できます。
  • 依存関係。 必要なリソースを作成する前に何かが既に存在していることに、依存する場合もあります。 そのような依存関係を表すには、dependsOn というコンストラクトがあります。

デプロイ モードと copy

copy コンストラクトによって作成される一連のリソースがすべて確実に、他のものより前に作成されるようにすることが必要な場合があります。 その場合は、この状況を表す必要があります。 Resource Manager で使用されるデプロイ モードがここで役立つことを覚えておいてください。 2 つのモードがサポートされています。

  • 順次。 このデプロイ モードに設定したリソースは、1 つずつ順番に作成されます。 このモードでは、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 テンプレートは、これら 2 つのリソースの間で順次デプロイ モードに切り替わります。 デプロイのスループット速度に影響する可能性はありますが、特定のデプロイ順序が重要であることが示されており、それが優先されます。