Azure Resource Manager テンプレートでリソースまたはプロパティの複数のインスタンスをデプロイするDeploy multiple instances of a resource or property in Azure Resource Manager templates

このトピックでは、Azure Resource Manager テンプレートで反復処理して、リソースの複数のインスタンス、またはリソース上のプロパティの複数のインスタンスを作成する方法について説明します。This topic shows you how to iterate in your Azure Resource Manager template to create multiple instances of a resource, or multiple instances of a property on a resource.

テンプレートにロジックを追加してリソースをデプロイするかどうかを指定できるようにする必要がある場合、「Conditionally deploy resource (リソースを条件付きでデプロイする)」を参照してください。If you need to add logic to your template that enables you to specify whether a resource is deployed, see Conditionally deploy resource.

配列変数に複数の要素を作成する例については、「変数」を参照してください。For an example of creating multiple elements in an array variable, see Variables.

リソースの反復Resource iteration

あるリソース タイプのインスタンスを複数作成するには、そのリソース タイプに copy 要素を追加します。To create multiple instances of a resource type, add a copy element to the resource type. copy 要素には、そのループの反復回数と名前を指定します。In the copy element, you specify the number of iterations and a name for this loop. 数値は正の整数で、800 を超えることはできません。The count value must be a positive integer and cannot exceed 800. リソース マネージャーは、並列でリソースを作成します。Resource Manager creates the resources in parallel. そのため、作成される順序は保証されません。Therefore, the order in which they are created is not guaranteed. 反復処理されるリソースを順番に作成する場合は、「シリアル コピー」を参照してください。To create iterated resources in sequence, see Serial copy.

複数回作成されるリソースは、次の形式を取ります。The resource to create multiple times takes the following format:

{
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "resources": [
        {
            "apiVersion": "2016-01-01",
            "type": "Microsoft.Storage/storageAccounts",
            "name": "[concat(copyIndex(),'storage', uniqueString(resourceGroup().id))]",
            "location": "[resourceGroup().location]",
            "sku": {
                "name": "Standard_LRS"
            },
            "kind": "Storage",
            "properties": {},
            "copy": {
                "name": "storagecopy",
                "count": 3
            }
        }
    ],
    "outputs": {}
}

各リソースの名前には、現在のループの反復を返す copyIndex() 関数が含まれます。Notice that the name of each resource includes the copyIndex() function, which returns the current iteration in the loop. copyIndex() は 0 から始まります。copyIndex() is zero-based. 次の例を見てください。So, the following example:

"name": "[concat('storage', copyIndex())]",

この場合、以下の名前が作成されます。Creates these names:

  • storage0storage0
  • storage1storage1
  • storage2storage2.

インデックス値をオフセットするには、copyIndex() 関数に値を渡します。To offset the index value, you can pass a value in the copyIndex() function. 実行する反復処理の数は copy 要素で指定されたままですが、copyIndex の値が指定された値でオフセットされます。The number of iterations to perform is still specified in the copy element, but the value of copyIndex is offset by the specified value. 次の例を見てください。So, the following example:

"name": "[concat('storage', copyIndex(1))]",

この場合、以下の名前が作成されます。Creates these names:

  • storage1storage1
  • storage2storage2
  • storage3storage3

コピー操作は、配列内の各要素に対して反復処理するため、配列で作業するときに便利です。The copy operation is helpful when working with arrays because you can iterate through each element in the array. 配列で反復回数を指定するには length 関数を使います。また、配列における現在のインデックスを取得するには copyIndex を使います。Use the length function on the array to specify the count for iterations, and copyIndex to retrieve the current index in the array. 次の例を見てください。So, the following example:

"parameters": { 
  "org": { 
     "type": "array", 
     "defaultValue": [ 
         "contoso", 
         "fabrikam", 
         "coho" 
      ] 
  }
}, 
"resources": [ 
  { 
      "name": "[concat('storage', parameters('org')[copyIndex()])]", 
      "copy": { 
         "name": "storagecopy", 
         "count": "[length(parameters('org'))]" 
      }, 
      ...
  } 
]

この場合、以下の名前が作成されます。Creates these names:

  • storagecontosostoragecontoso
  • storagefabrikamstoragefabrikam
  • storagecohostoragecoho

シリアル コピーSerial copy

copy 要素を使用して、あるリソース タイプのインスタンスを複数作成する場合、Resource Manager によって既定でそれらのインスタンスが並列的にデプロイされます。When you use the copy element to create multiple instances of a resource type, Resource Manager, by default, deploys those instances in parallel. しかし、リソースが順番にデプロイされるように指定したい場合もあります。However, you may want to specify that the resources are deployed in sequence. たとえば、運用環境を更新するとき、一度に特定の数だけ更新されるように更新時間をずらす必要がある場合があります。For example, when updating a production environment, you may want to stagger the updates so only a certain number are updated at any one time.

Resource Manager では、複数のインスタンスを順番にデプロイできるようにするプロパティを copy 要素に指定できます。Resource Manager provides properties on the copy element that enable you to serially deploy multiple instances. copy 要素で modeserial に設定し、batchSize を一度にデプロイするインスタンスの数に設定します。In the copy element, set mode to serial and batchSize to the number of instances to deploy at a time. シリアル モードでは、Resource Manager はループ内で前のインスタンスへの依存関係を作成するので、前のバッチが完了するまで次のバッチは実行されません。With serial mode, Resource Manager creates a dependency on earlier instances in the loop, so it does not start one batch until the previous batch completes.

"copy": {
    "name": "iterator",
    "count": "[parameters('numberToDeploy')]",
    "mode": "serial",
    "batchSize": 2
},

mode プロパティでも parallel が既定値として使用されます。The mode property also accepts parallel, which is the default value.

実際のリソースを作成せずにシリアル コピーをテストするには、空の入れ子になったテンプレートをデプロイする次のテンプレートを使用します。To test serial copy without creating actual resources, use the following template that deploys empty nested templates:

{
  "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "numberToDeploy": {
      "type": "int",
      "minValue": 2,
      "defaultValue": 5
    }
  },
  "resources": [
    {
      "apiVersion": "2015-01-01",
      "type": "Microsoft.Resources/deployments",
      "name": "[concat('loop-', copyIndex())]",
      "copy": {
        "name": "iterator",
        "count": "[parameters('numberToDeploy')]",
        "mode": "serial",
        "batchSize": 1
      },
      "properties": {
        "mode": "Incremental",
        "template": {
          "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
          "contentVersion": "1.0.0.0",
          "parameters": {},
          "variables": {},
          "resources": [],
          "outputs": {
          }
        }
      }
    }
  ],
  "outputs": {
  }
}

デプロイ履歴で、入れ子になったデプロイが順番に処理されていることに注意してください。In the deployment history, notice that the nested deployments are processed in sequence.

シリアル デプロイ

より現実に即したシナリオでは、次の例のように、Linux VM の 2 つのインスタンスを、入れ子になったテンプレートから一度にデプロイします。For a more realistic scenario, the following example deploys two instances at a time of a Linux VM from a nested template:

{
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "adminUsername": {
            "type": "string",
            "metadata": {
                "description": "User name for the Virtual Machine."
            }
        },
        "adminPassword": {
            "type": "securestring",
            "metadata": {
                "description": "Password for the Virtual Machine."
            }
        },
        "dnsLabelPrefix": {
            "type": "string",
            "metadata": {
                "description": "Unique DNS Name for the Public IP used to access the Virtual Machine."
            }
        },
        "ubuntuOSVersion": {
            "type": "string",
            "defaultValue": "16.04.0-LTS",
            "allowedValues": [
                "12.04.5-LTS",
                "14.04.5-LTS",
                "15.10",
                "16.04.0-LTS"
            ],
            "metadata": {
                "description": "The Ubuntu version for the VM. This will pick a fully patched image of this given Ubuntu version."
            }
        }
    },
    "variables": {
        "templatelink": "https://raw.githubusercontent.com/rjmax/Build2017/master/Act1.TemplateEnhancements/Chapter03.LinuxVM.json"
    },
    "resources": [
        {
            "apiVersion": "2015-01-01",
            "name": "[concat('nestedDeployment',copyIndex())]",
            "type": "Microsoft.Resources/deployments",
            "copy": {
                "name": "myCopySet",
                "count": 4,
                "mode": "serial",
                "batchSize": 2
            },
            "properties": {
                "mode": "Incremental",
                "templateLink": {
                    "uri": "[variables('templatelink')]",
                    "contentVersion": "1.0.0.0"
                },
                "parameters": {
                    "adminUsername": {
                        "value": "[parameters('adminUsername')]"
                    },
                    "adminPassword": {
                        "value": "[parameters('adminPassword')]"
                    },
                    "dnsLabelPrefix": {
                        "value": "[parameters('dnsLabelPrefix')]"
                    },
                    "ubuntuOSVersion": {
                        "value": "[parameters('ubuntuOSVersion')]"
                    },
                    "index":{
                        "value": "[copyIndex()]"
                    }
                }
            }
        }
    ]
}

プロパティの反復処理Property iteration

リソース上のプロパティに複数の値を作成するには、プロパティ要素に copy 配列を追加します。To create multiple values for a property on a resource, add a copy array in the properties element. この配列にはオブジェクトが含まれていて、各オブジェクトには次のプロパティがあります。This array contains objects, and each object has the following properties:

  • name - 複数の値を作成するプロパティの名前name - the name of the property to create multiple values for
  • count - 作成する値の数count - the number of values to create
  • input - プロパティに割り当てる値を格納するオブジェクトinput - an object that contains the values to assign to the property

次の例は、仮想マシンで dataDisks プロパティに copy を適用する方法を示しています。The following example shows how to apply copy to the dataDisks property on a virtual machine:

{
  "name": "examplevm",
  "type": "Microsoft.Compute/virtualMachines",
  "apiVersion": "2017-03-30",
  "properties": {
    "storageProfile": {
      "copy": [{
          "name": "dataDisks",
          "count": 3,
          "input": {
              "lun": "[copyIndex('dataDisks')]",
              "createOption": "Empty",
              "diskSizeGB": "1023"
          }
      }],
      ...

プロパティの反復処理内で copyIndex を使用する場合、反復処理の名前を指定する必要があります。Notice that when using copyIndex inside a property iteration, you must provide the name of the iteration. リソースの反復処理で使用する場合には名前を指定する必要はありません。You do not have to provide the name when used with resource iteration.

Resource Manager はデプロイ中に copy 配列を展開します。Resource Manager expands the copy array during deployment. 配列の名前がプロパティの名前になります。The name of the array becomes the name of the property. 入力値がオブジェクトのプロパティになります。The input values become the object properties. デプロイされたテンプレートは次のようになります。The deployed template becomes:

{
  "name": "examplevm",
  "type": "Microsoft.Compute/virtualMachines",
  "apiVersion": "2017-03-30",
  "properties": {
    "storageProfile": {
      "dataDisks": [
          {
              "lun": 0,
              "createOption": "Empty",
              "diskSizeGB": "1023"
          },
          {
              "lun": 1,
              "createOption": "Empty",
              "diskSizeGB": "1023"
          },
          {
              "lun": 2,
              "createOption": "Empty",
              "diskSizeGB": "1023"
          }
      }],
      ...

リソースの反復処理とプロパティの反復処理は同時に使用できます。You can use resource and property iteration together. プロパティの反復処理を名前で参照します。Reference the property iteration by name.

{
    "type": "Microsoft.Network/virtualNetworks",
    "name": "[concat(parameters('vnetname'), copyIndex())]",
    "apiVersion": "2016-06-01",
    "copy":{
        "count": 2,
        "name": "vnetloop"
    },
    "location": "[resourceGroup().location]",
    "properties": {
        "addressSpace": {
            "addressPrefixes": [
                "[parameters('addressPrefix')]"
            ]
        },
        "copy": [
            {
                "name": "subnets",
                "count": 2,
                "input": {
                    "name": "[concat('subnet-', copyIndex('subnets'))]",
                    "properties": {
                        "addressPrefix": "[variables('subnetAddressPrefix')[copyIndex('subnets')]]"
                    }
                }
            }
        ]
    }
}

各リソースのプロパティには copy 要素を 1 つのみ含めることができます。You can only include one copy element in the properties for each resource. 1 つの反復ループを複数のプロパティに指定するには、copy 配列内の複数のオブジェクトを定義します。To specify an iteration loop for more than one property, define multiple objects in the copy array. 各オブジェクトは個別に反復処理されます。Each object is iterated separately. たとえば、ロード バランサーで frontendIPConfigurations プロパティと loadBalancingRules プロパティの両方の複数インスタンスを作成するには、1 つの copy 要素に両方のオブジェクトを定義します。For example, to create multiple instances of both the frontendIPConfigurations property and the loadBalancingRules property on a load balancer, define both objects in a single copy element:

{
    "name": "[variables('loadBalancerName')]",
    "type": "Microsoft.Network/loadBalancers",
    "properties": {
        "copy": [
          {
              "name": "frontendIPConfigurations",
              "count": 2,
              "input": {
                  "name": "[concat('loadBalancerFrontEnd', copyIndex('frontendIPConfigurations', 1))]",
                  "properties": {
                      "publicIPAddress": {
                          "id": "[variables(concat('publicIPAddressID', copyIndex('frontendIPConfigurations', 1)))]"
                      }
                  }
              }
          },
          {
              "name": "loadBalancingRules",
              "count": 2,
              "input": {
                  "name": "[concat('LBRuleForVIP', copyIndex('loadBalancingRules', 1))]",
                  "properties": {
                      "frontendIPConfiguration": {
                          "id": "[variables(concat('frontEndIPConfigID', copyIndex('loadBalancingRules', 1)))]"
                      },
                      "backendAddressPool": {
                          "id": "[variables('lbBackendPoolID')]"
                      },
                      "protocol": "tcp",
                      "frontendPort": "[variables(concat('frontEndPort' copyIndex('loadBalancingRules', 1))]",
                      "backendPort": "[variables(concat('backEndPort' copyIndex('loadBalancingRules', 1))]",
                      "probe": {
                          "id": "[variables('lbProbeID')]"
                      }
                  }
              }
          }
        ],
        ...
    }
}

ループ内のリソースへの依存Depend on resources in a loop

dependsOn 要素を使用することで、リソースを別のリソースの後にデプロイするよう指定することが可能です。You specify that a resource is deployed after another resource by using the dependsOn element. ループ内のリソースの集合に依存するリソースをデプロイするには、dependsOn 要素にコピー ループの名前を指定します。To deploy a resource that depends on the collection of resources in a loop, provide the name of the copy loop in the dependsOn element. 次の例では、仮想マシンをデプロイする前に 3 つのストレージ アカウントをデプロイする方法を示します。The following example shows how to deploy three storage accounts before deploying the Virtual Machine. 完全な仮想マシン定義は示されていません。The full Virtual Machine definition is not shown. コピー要素の name が storagecopy に設定され、Virtual Machines の dependsOn 要素が storagecopy に設定されるよう注意してください。Notice that the copy element has name set to storagecopy and the dependsOn element for the Virtual Machines is also set to storagecopy.

{
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {},
    "resources": [
        {
            "apiVersion": "2016-01-01",
            "type": "Microsoft.Storage/storageAccounts",
            "name": "[concat(copyIndex(),'storage', uniqueString(resourceGroup().id))]",
            "location": "[resourceGroup().location]",
            "sku": {
                "name": "Standard_LRS"
            },
            "kind": "Storage",
            "properties": {},
            "copy": {
                "name": "storagecopy",
                "count": 3
            }
        },
        {
            "apiVersion": "2015-06-15", 
            "type": "Microsoft.Compute/virtualMachines", 
            "name": "[concat('VM', uniqueString(resourceGroup().id))]",  
            "dependsOn": ["storagecopy"],
            ...
        }
    ],
    "outputs": {}
}

子リソースの複数のインスタンスの作成Create multiple instances of a child resource

子リソースにコピー ループを使用することはできません。You cannot use a copy loop for a child resource. 通常他のリソース内の入れ子として定義されるリソースの複数のインスタンスを作成するには、代わりにそのリソースを最上位のリソースとして作成する必要があります。To create multiple instances of a resource that you typically define as nested within another resource, you must instead create that resource as a top-level resource. type および name の各プロパティを使用して、親リソースとの関係を定義します。You define the relationship with the parent resource through the type and name properties.

たとえば、通常はデータ ファクトリ内の子リソースとしてデータセットを定義するとします。For example, suppose you typically define a dataset as a child resource within a data factory.

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

データセットの複数のインスタンスを作成するには、データ ファクトリの外部に移動します。To create multiple instances of data sets, move it outside of the data factory. データセットは、データ ファクトリと同じレベルである必要がありますが、今までどおりデータ ファクトリの子リソースです。The dataset must be at the same level as the data factory, but it is still a child resource of the data factory. type および name の各プロパティを使用して、データセットとデータ ファクトリの関係を保存します。You preserve the relationship between data set and data factory through the type and name properties. テンプレート内の位置から type を推論できなくなったため、{resource-provider-namespace}/{parent-resource-type}/{child-resource-type} の形式で完全修飾型を指定する必要があります。Since type can no longer be inferred from its position in the template, you must provide the fully qualified type in the format: {resource-provider-namespace}/{parent-resource-type}/{child-resource-type}.

データ ファクトリのインスタンスを使用して親子関係を確立するには、親リソースの名前を含むデータ セットの名前を指定します。To establish a parent/child relationship with an instance of the data factory, provide a name for the data set that includes the parent resource name. {parent-resource-name}/{child-resource-name} の形式で入力します。Use the format: {parent-resource-name}/{child-resource-name}.

次の例は、実装を示します。The following example shows the implementation:

"resources": [
{
    "type": "Microsoft.DataFactory/datafactories",
    "name": "exampleDataFactory",
    ...
},
{
    "type": "Microsoft.DataFactory/datafactories/datasets",
    "name": "[concat('exampleDataFactory', '/', 'exampleDataSet', copyIndex())]",
    "dependsOn": [
        "exampleDataFactory"
    ],
    "copy": { 
        "name": "datasetcopy", 
        "count": "3" 
    } 
    ...
}]

条件付きでリソースをデプロイするConditionally deploy resource

リソースをデプロイするかどうかを指定するには、condition 要素を使用します。To specify whether a resource is deployed, use the condition element. この要素の値は、true または false に解決されます。The value for this element resolves to true or false. 値が true の場合、リソースはデプロイされます。When the value is true, the resource is deployed. 値が false の場合、リソースはデプロイされません。When the value is false, the resource is not deployed. たとえば、新しいストレージ アカウントをデプロイするか、既存のストレージ アカウントを使用するかを指定するには、次のようにします。For example, to specify whether a new storage account is deployed or an existing storage account is used, use:

{
    "condition": "[equals(parameters('newOrExisting'),'new')]",
    "type": "Microsoft.Storage/storageAccounts",
    "name": "[variables('storageAccountName')]",
    "apiVersion": "2017-06-01",
    "location": "[resourceGroup().location]",
    "sku": {
        "name": "[variables('storageAccountType')]"
    },
    "kind": "Storage",
    "properties": {}
}

新しいリソースを使用するか、既存のリソースを使用するかの例は、「新規または既存の条件テンプレート」の例を参照してください。For an example of using a new or existing resource, see New or existing condition template.

仮想マシンのデプロイにパスワードを使用するか、SSH キーを使用するかの例は、「ユーザー名または SSH 条件テンプレート」の例を参照してください。For an example of using a password or SSH key to deploy virtual machine, see Username or SSH condition template.

次のステップNext steps