次の方法で共有


リンクされたテンプレートと入れ子になったテンプレートを使用して Azure リソースをデプロイする

複雑なソリューションをデプロイするには、Azure Resource Manager テンプレート (ARM テンプレート) を複数の関連するテンプレートに分割し、メイン テンプレートを使用してそれらをまとめてデプロイできます。 関連するテンプレートは、メイン テンプレート内に埋め込まれている個別のファイルまたはテンプレート構文にすることができます。 この記事では、 リンクされたテンプレート という用語を使用して、メイン テンプレートからのリンクを介して参照される別のテンプレート ファイルを参照します。 メイン テンプレートに埋め込まれたテンプレート構文に対して、入れ子になったテンプレートという用語を使用します。

中小規模のソリューションの場合、テンプレートを 1 つにするとわかりやすく、保守も簡単になります。 すべてのリソースと値を 1 つのファイルで参照できます。 高度なシナリオの場合、リンクされたテンプレートを使用することで、対象となるコンポーネントにソリューションを分割することができます。 これらのテンプレートは、他のシナリオで簡単に再利用できます。

チュートリアルについては、「チュートリアル: リンク済みテンプレートをデプロイする」を参照してください。

リンクされたテンプレートまたは入れ子になったテンプレートの場合、デプロイ モードを 増分に設定することしかできません。 ただし、メイン テンプレートは完全モードでデプロイできます。 メイン テンプレートを完全モードでデプロイし、リンクされたテンプレートまたは入れ子になったテンプレートが同じリソースグループを対象とする場合、リンクされたテンプレートまたは入れ子になったテンプレートにデプロイされたリソースは、完全モード デプロイの評価に含まれます。 メイン テンプレートおよびリンクされたまたは入れ子になったテンプレートにデプロイされたリソースの組み合わされたコレクションは、リソース グループ内の既存のリソースと比較されます。 この組み合わされたコレクションに含まれていないリソースはすべて削除されます。

リンクまたは入れ子になったテンプレートが別のリソース グループを対象としている場合、そのデプロイは増分モードを使用します。 詳しくは、「デプロイ スコープ」を参照してください。

ヒント

Bicep は ARM テンプレートと同じ機能を提供し、構文の方が使いやすいため、推奨されます。 詳細については、「モジュール」を参照してください。

入れ子になったテンプレート

テンプレートを入れ子にするには、メイン テンプレートにデプロイ リソースを追加します。 template プロパティに、テンプレートの構文を指定します。

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {},
  "variables": {},
  "resources": [
    {
      "type": "Microsoft.Resources/deployments",
      "apiVersion": "2025-04-01",
      "name": "nestedTemplate1",
      "properties": {
        "mode": "Incremental",
        "template": {
          <nested-template-syntax>
        }
      }
    }
  ]
}

次の例では、入れ子になったテンプレートを使用して、ストレージ アカウントがデプロイされます。

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "storageAccountName": {
      "type": "string",
      "defaultValue": "[format('{0}{1}', 'store', uniqueString(resourceGroup().id))]"
    },
    "location": {
      "type": "string",
      "defaultValue": "[resourceGroup().location]"
    }
  },
  "resources": [
    {
      "type": "Microsoft.Resources/deployments",
      "apiVersion": "2025-04-01",
      "name": "nestedTemplate1",
      "properties": {
        "mode": "Incremental",
        "template": {
          "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
          "contentVersion": "1.0.0.0",
          "resources": [
            {
              "type": "Microsoft.Storage/storageAccounts",
              "apiVersion": "2025-06-01",
              "name": "[parameters('storageAccountName')]",
              "location": "[parameters('location')]",
              "sku": {
                "name": "Standard_LRS"
              },
              "kind": "StorageV2"
            }
          ]
        }
      }
    }
  ]
}

入れ子になったリソース は、シンボリック名 テンプレートでは使用できません。 次のテンプレートでは、入れ子になったストレージ アカウント リソースでシンボリック名を使うことはできません。

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "languageVersion": "2.0",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "storageAccountName": {
      "type": "string",
      "defaultValue": "[format('{0}{1}', 'storage', uniqueString(resourceGroup().id))]"

    },
    "location": {
      "type": "string",
      "defaultValue": "[resourceGroup().location]"
    }
  },
  "resources": {
    "mainStorage": {
      "type": "Microsoft.Storage/storageAccounts",
      "apiVersion": "2025-06-01",
      "name": "[parameters('storageAccountName')]",
      "location": "[parameters('location')]",
      "sku": {
        "name": "Standard_LRS"
      },
      "kind": "StorageV2"
    },
    "nestedResource": {
      "type": "Microsoft.Resources/deployments",
      "apiVersion": "2025-04-01",
      "name": "nestedTemplate1",
      "properties": {
        "mode": "Incremental",
        "template": {
          "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
          "contentVersion": "1.0.0.0",
          "resources": [
            {
              "type": "Microsoft.Storage/storageAccounts",
              "apiVersion": "2025-06-01",
              "name": "[format('{0}nested', parameters('storageAccountName'))]",
              "location": "[parameters('location')]",
              "sku": {
                "name": "Standard_LRS"
              },
              "kind": "StorageV2"
            }
          ]
        }
      }
    }
  }
}

入れ子になったテンプレートでの式の評価のスコープ

入れ子になったテンプレートを使用する場合は、親テンプレートまたは入れ子になったテンプレートのスコープ内でテンプレート式を評価するかどうかを指定できます。 スコープによって、パラメーター、変数、および resourceGroupsubscription などの関数がどのように解決されるかが決まります。

スコープは、expressionEvaluationOptions プロパティを使用して設定します。 既定では、expressionEvaluationOptions プロパティは outer に設定されます。これは、親テンプレート スコープを使用することを意味します。 値を inner に設定すると、入れ子になったテンプレートのスコープ内で式が評価されます。

重要

languageVersion 2.0 の場合、expressionEvaluationOptions プロパティに対する既定値は inner です。 outer値はブロックされます。

{
  "type": "Microsoft.Resources/deployments",
  "apiVersion": "2025-04-01",
  "name": "nestedTemplate1",
  "properties": {
    "expressionEvaluationOptions": {
      "scope": "inner"
    },
  ...

スコープがouterに設定されている場合、入れ子になったテンプレートにデプロイしたリソースの入れ子になったテンプレートのreferenceセクションで関数を使用することはできません。 入れ子になったテンプレートでデプロイされたリソースの値を返すには、 inner スコープを使用するか、入れ子になったテンプレートをリンクされたテンプレートに変換します。

次のテンプレートは、テンプレート式がスコープに従ってどのように解決されるかを示しています。 親テンプレートと入れ子になったテンプレートの両方で定義されている exampleVar という名前の変数が含まれています。 変数の値を返します。

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
  },
  "variables": {
    "exampleVar": "from parent template"
  },
  "resources": [
    {
      "type": "Microsoft.Resources/deployments",
      "apiVersion": "2025-04-01",
      "name": "nestedTemplate1",
      "properties": {
        "expressionEvaluationOptions": {
          "scope": "inner"
        },
        "mode": "Incremental",
        "template": {
          "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
          "contentVersion": "1.0.0.0",
          "variables": {
            "exampleVar": "from nested template"
          },
          "resources": [
          ],
          "outputs": {
            "testVar": {
              "type": "string",
              "value": "[variables('exampleVar')]"
            }
          }
        }
      }
    }
  ],
  "outputs": {
    "messageFromLinkedTemplate": {
      "type": "string",
      "value": "[reference('nestedTemplate1').outputs.testVar.value]"
    }
  }
}

exampleVar の値は、scopeexpressionEvaluationOptions プロパティの値によって変わります。 次の表に、両方のスコープの結果を示します。

評価のスコープ 出力
内部 入れ子になったテンプレートから
outer (既定値) 親テンプレートから

次の例では、SQL サーバーをデプロイし、パスワードに使用するキー コンテナー シークレットを取得します。 キー コンテナー ID は動的に作成され (outer テンプレート inneradminPassword.reference.keyVault を参照)、パラメーターとして入れ子になったテンプレートに渡されるため、スコープは parameters に設定されます。

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "location": {
      "type": "string",
      "defaultValue": "[resourceGroup().location]",
      "metadata": {
        "description": "The location where the resources will be deployed."
      }
    },
    "vaultName": {
      "type": "string",
      "metadata": {
        "description": "The name of the keyvault that contains the secret."
      }
    },
    "secretName": {
      "type": "string",
      "metadata": {
        "description": "The name of the secret."
      }
    },
    "vaultResourceGroupName": {
      "type": "string",
      "metadata": {
        "description": "The name of the resource group that contains the keyvault."
      }
    },
    "vaultSubscription": {
      "type": "string",
      "defaultValue": "[subscription().subscriptionId]",
      "metadata": {
        "description": "The name of the subscription that contains the keyvault."
      }
    }
  },
  "resources": [
    {
      "type": "Microsoft.Resources/deployments",
      "apiVersion": "2025-04-01",
      "name": "dynamicSecret",
      "properties": {
        "mode": "Incremental",
        "expressionEvaluationOptions": {
          "scope": "inner"
        },
        "parameters": {
          "location": {
            "value": "[parameters('location')]"
          },
          "adminLogin": {
            "value": "ghuser"
          },
          "adminPassword": {
            "reference": {
              "keyVault": {
                "id": "[resourceId(parameters('vaultSubscription'), parameters('vaultResourceGroupName'), 'Microsoft.KeyVault/vaults', parameters('vaultName'))]"
              },
              "secretName": "[parameters('secretName')]"
            }
          }
        },
        "template": {
          "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
          "contentVersion": "1.0.0.0",
          "parameters": {
            "adminLogin": {
              "type": "string"
            },
            "adminPassword": {
              "type": "securestring"
            },
            "location": {
              "type": "string"
            }
          },
          "variables": {
            "sqlServerName": "[format('sql-{0}sql', uniqueString(resourceGroup().id, 'sql'))]"
          },
          "resources": [
            {
              "type": "Microsoft.Sql/servers",
              "apiVersion": "2022-05-01-preview",
              "name": "[variables('sqlServerName')]",
              "location": "[parameters('location')]",
              "properties": {
                "administratorLogin": "[parameters('adminLogin')]",
                "administratorLoginPassword": "[parameters('adminPassword')]"
              }
            }
          ],
          "outputs": {
            "sqlFQDN": {
              "type": "string",
              "value": "[reference(variables('sqlServerName')).fullyQualifiedDomainName]"
            }
          }
        }
      }
    }
  ],
  "outputs": {
  }
}

入れ子になったテンプレートで、セキュリティで保護されたパラメーター値を使用する場合は注意してください。 スコープを外部に設定した場合、セキュリティで保護された値は、デプロイ履歴にプレーン テキストとして保存されます。 デプロイ履歴でテンプレートを確認するユーザーは、セキュリティで保護された値を見ることができます。 代わりに、内部スコープを使用するか、セキュリティで保護された値を必要とするリソースを親テンプレートに追加してください。

次の抜粋は、セキュリティで保護されている値またはセキュリティで保護されていない値を示しています。

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "adminUsername": {
      "type": "string",
      "metadata": {
        "description": "Username for the Virtual Machine."
      }
    },
    "adminPasswordOrKey": {
      "type": "securestring",
      "metadata": {
        "description": "SSH Key or password for the Virtual Machine. SSH key is recommended."
      }
    }
  },
  ...
  "resources": [
    {
      "type": "Microsoft.Compute/virtualMachines",
      "apiVersion": "2025-04-01",
      "name": "mainTemplate",
      "properties": {
        ...
        "osProfile": {
          "computerName": "mainTemplate",
          "adminUsername": "[parameters('adminUsername')]",
          "adminPassword": "[parameters('adminPasswordOrKey')]" // Yes, secure because resource is in parent template
        }
      }
    },
    {
      "name": "outer",
      "type": "Microsoft.Resources/deployments",
      "apiVersion": "2025-04-01",
      "properties": {
        "expressionEvaluationOptions": {
          "scope": "outer"
        },
        "mode": "Incremental",
        "template": {
          "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
          "contentVersion": "1.0.0.0",
          "resources": [
            {
              "type": "Microsoft.Compute/virtualMachines",
              "apiVersion": "2025-04-01",
              "name": "outer",
              "properties": {
                ...
                "osProfile": {
                  "computerName": "outer",
                  "adminUsername": "[parameters('adminUsername')]",
                  "adminPassword": "[parameters('adminPasswordOrKey')]" // No, not secure because resource is in nested template with outer scope
                }
              }
            }
          ]
        }
      }
    },
    {
      "name": "inner",
      "type": "Microsoft.Resources/deployments",
      "apiVersion": "2025-04-01",
      "properties": {
        "expressionEvaluationOptions": {
          "scope": "inner"
        },
        "mode": "Incremental",
        "parameters": {
          "adminPasswordOrKey": {
              "value": "[parameters('adminPasswordOrKey')]"
          },
          "adminUsername": {
              "value": "[parameters('adminUsername')]"
          }
        },
        "template": {
          "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
          "contentVersion": "1.0.0.0",
          "parameters": {
            "adminUsername": {
              "type": "string",
              "metadata": {
                "description": "Username for the Virtual Machine."
              }
            },
            "adminPasswordOrKey": {
              "type": "securestring",
              "metadata": {
                "description": "SSH Key or password for the Virtual Machine. SSH key is recommended."
              }
            }
          },
          "resources": [
            {
              "type": "Microsoft.Compute/virtualMachines",
              "apiVersion": "2025-04-01",
              "name": "inner",
              "properties": {
                ...
                "osProfile": {
                  "computerName": "inner",
                  "adminUsername": "[parameters('adminUsername')]",
                  "adminPassword": "[parameters('adminPasswordOrKey')]" // Yes, secure because resource is in nested template and scope is inner
                }
              }
            }
          ]
        }
      }
    }
  ]
}

リンク済みテンプレート

テンプレートをリンクするには、メイン テンプレートにデプロイ リソースを追加します。 templateLink プロパティに、含めるテンプレートの URI を指定します。 次の例では、ストレージ アカウント内のテンプレートにリンクします。

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {},
  "variables": {},
  "resources": [
    {
      "type": "Microsoft.Resources/deployments",
      "apiVersion": "2025-04-01",
      "name": "linkedTemplate",
      "properties": {
        "mode": "Incremental",
        "templateLink": {
          "uri":"https://mystorageaccount.blob.core.windows.net/AzureTemplates/newStorageAccount.json",
          "contentVersion":"1.0.0.0"
        }
      }
    }
  ],
  "outputs": {
  }
}

リンクされたテンプレートを参照する場合、 uri の値をローカル ファイルまたはローカル ネットワークでのみ使用できるファイルにすることはできません。 Azure Resource Manager は、テンプレートにアクセスできる必要があります。 HTTP または HTTPS としてダウンロードできる URI 値を指定してください。

HTTP または HTTPS を含むパラメーターを使用してテンプレートを参照できます。 たとえば、一般的なパターンでは、_artifactsLocation パラメーターを使用します。 次のような式を使用して、リンク済みテンプレートを設定できます。

"uri": "[format('{0}/shared/os-disk-parts-md.json{1}', parameters('_artifactsLocation'), parameters('_artifactsLocationSasToken'))]"

GitHub のテンプレートにリンクしている場合は、生の URL を使用します。 このリンクの形式は、https://raw.githubusercontent.com/Azure/azure-docs-json-samples/master/get-started-with-templates/quickstart-template/azuredeploy.json です。 生のリンクを取得するには [Raw](生) を選択します。

GitHub で生の URL を選択するスクリーンショット。

テンプレートをデプロイするか、プライベート GitHub リポジトリに格納されているリンクされたテンプレートを参照するには、「カスタムのセキュリティ保護された Azure Portal オファリングの作成」に記載されているカスタム ソリューションを参照してください。 Azure Key Vault から GitHub トークンを取得する Azure 関数を作成できます。

リンクされたテンプレートの場合、シンボリック名以外のデプロイを シンボリック名テンプレート内に入れ子にしたり、シンボリック名のデプロイを非シンボリック テンプレート内に入れ子にしたり、シンボリック名のデプロイを別のシンボリック名テンプレート内に入れ子にしたりできます (またはその逆も同様)。

リンクされたテンプレートのパラメーター

リンクされたテンプレートのパラメーターには、外部ファイルまたはインラインを指定できます。 外部パラメーター ファイルを指定する場合は、parametersLink プロパティを使用します。

"resources": [
  {
    "type": "Microsoft.Resources/deployments",
    "apiVersion": "2025-04-01",
    "name": "linkedTemplate",
    "properties": {
      "mode": "Incremental",
      "templateLink": {
        "uri": "https://mystorageaccount.blob.core.windows.net/AzureTemplates/newStorageAccount.json",
        "contentVersion": "1.0.0.0"
      },
      "parametersLink": {
        "uri": "https://mystorageaccount.blob.core.windows.net/AzureTemplates/newStorageAccount.parameters.json",
        "contentVersion": "1.0.0.0"
      }
    }
  }
]

パラメーター値をインラインで渡すには、parameters プロパティを使用します。

"resources": [
  {
    "type": "Microsoft.Resources/deployments",
    "apiVersion": "2025-04-01",
    "name": "linkedTemplate",
    "properties": {
      "mode": "Incremental",
      "templateLink": {
        "uri": "https://mystorageaccount.blob.core.windows.net/AzureTemplates/newStorageAccount.json",
        "contentVersion": "1.0.0.0"
      },
      "parameters": {
        "storageAccountName": {
          "value": "[parameters('storageAccountName')]"
        }
      }
    }
  }
]

インライン パラメーターとパラメーター ファイルへのリンクの両方を使用することはできません。 parametersLinkparameters の両方が指定された場合、デプロイは失敗します。

リンクされたテンプレートの相対パスを使用する

relativePathMicrosoft.Resources/deployments プロパティを使用すると、リンクされたテンプレートを簡単に作成できます。 このプロパティを使用すると、リモートのリンクされたテンプレートを、親を基準とした相対的な場所にデプロイできます。 この機能を使用するには、すべてのテンプレート ファイルをステージングし、GitHub や Azure ストレージ アカウントなどのリモート URI で利用できるようにする必要があります。 Azure PowerShell または Azure CLI の URI を使用してメイン テンプレートを呼び出す場合、子デプロイ URI は親と relativePath の組み合わせです。

templateSpec を作成すると、 relativePath プロパティによって参照されるすべてのテンプレートは、Azure PowerShell または Azure CLI によって templateSpec リソースにパッケージ化されます。 ファイルをステージングする必要はありません。 詳細については、「リンクされたテンプレートを使用してテンプレート スペックを作成する」を参照してください。

次のようなフォルダー構造があるとします。

Resource Manager にリンクされたテンプレートの相対パスのフォルダー構造を示すダイアグラム。

次のテンプレートは、mainTemplate.json で、前の図で示された nestedChild.json をデプロイする方法を示しています。

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {},
  "functions": [],
  "variables": {},
  "resources": [
    {
      "type": "Microsoft.Resources/deployments",
      "apiVersion": "2025-04-01",
      "name": "childLinked",
      "properties": {
        "mode": "Incremental",
        "templateLink": {
          "relativePath": "children/nestedChild.json"
        }
      }
    }
  ],
  "outputs": {}
}

次のデプロイでは、前のテンプレートのリンクされたテンプレートの URI は、 https://raw.githubusercontent.com/Azure/azure-docs-json-samples/master/linked-template-relpath/children/nestedChild.json です。

New-AzResourceGroupDeployment `
  -Name linkedTemplateWithRelativePath `
  -ResourceGroupName "myResourceGroup" `
  -TemplateUri "https://raw.githubusercontent.com/Azure/azure-docs-json-samples/master/linked-template-relpath/mainTemplate.json"

Azure ストレージ アカウントに保存されている相対パスを使用してリンクされたテンプレートをデプロイするには、TemplateUri パラメーターと共に QueryString/query-string パラメーターを使用して、使用する SAS トークンを指定します。 このパラメーターは、Azure CLI バージョン 2.18 以降および Azure PowerShell バージョン 5.4 以降でのみサポートされています。

New-AzResourceGroupDeployment `
  -Name linkedTemplateWithRelativePath `
  -ResourceGroupName "myResourceGroup" `
  -TemplateUri "https://stage20210126.blob.core.windows.net/template-staging/mainTemplate.json" `
  -QueryString $sasToken

QueryString の先頭が "?" でないことを確認してください。 デプロイの URI をアセンブルすると、これが 1 つ追加されます。

テンプレート スペック

アクセス可能なエンドポイントでリンクされたテンプレートを維持する代わりに、メイン テンプレートとそのリンクされた テンプレート をデプロイできる 1 つのエンティティにパッケージ化するテンプレート スペックを作成できます。 テンプレート スペックは、Azure サブスクリプションのリソースです。 これにより、テンプレートを組織内のユーザーと安全に共有することが容易になります。 テンプレート スペックへのアクセス権を付与するには、Azure ロールベースのアクセス制御 (Azure RBAC) を使用します。

詳細については、以下を参照してください:

依存関係

他のリソースの種類と同様に、入れ子になったテンプレートとリンクされたテンプレートの間で依存関係を設定できます。 1 つの入れ子になった/リンクされたテンプレート内のリソースを、2 番目の入れ子になった/リンクされたテンプレート内のリソースの前にデプロイする必要がある場合は、2 番目のテンプレートを最初のテンプレートに依存するように設定します。

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {},
  "variables": {},
  "resources": [
    {
      "type": "Microsoft.Resources/deployments",
      "apiVersion": "2025-04-01",
      "name": "linkedTemplate1",
      "properties": {
        "mode": "Incremental",
        "templateLink": {
          "uri": "[uri(deployment().properties.templateLink.uri, 'firstresources.json')]",
          "contentVersion": "1.0.0.0"
        }
      }
    },
    {
      "type": "Microsoft.Resources/deployments",
      "apiVersion": "2025-04-01",
      "name": "linkedTemplate2",
      "dependsOn": [
        "[resourceId('Microsoft.Resources/deployments', 'linkedTemplate1')]"
      ],
      "properties": {
        "mode": "Incremental",
        "templateLink": {
          "uri": "[uri(deployment().properties.templateLink.uri, 'secondresources.json')]",
          "contentVersion": "1.0.0.0"
        }
      }
    }
  ]
}

コンテンツバージョン

contentVersion または templateLink プロパティには parametersLink プロパティを指定する必要はありません。 contentVersion を指定しない場合、テンプレートの現在のバージョンがデプロイされます。 コンテンツのバージョン値を指定する場合、リンクされているテンプレートのバージョンと一致している必要があります。それ以外の場合、デプロイはエラーで失敗します。

前の例では、URL の値をハード コーディングしてテンプレートをリンクする方法について説明しました。 この方法は簡単なテンプレートには適していますが、モジュール構造の大規模な一連のテンプレートにはあまり適していません。 その場合は、メイン テンプレートのベース URL を格納する静的変数を作成し、リンクされたテンプレートの URL をそのベース URL から動的に作成することができます。 この方法の利点は、テンプレートを簡単に移動またはフォークできることです。これは、メイン テンプレート内の静的変数のみ変更すれば済むためです。 メイン テンプレート内の静的変数を変更するだけで、正しい URI が、メイン テンプレートから、分解されたテンプレート全体に渡されます。

次の例では、ベース URL を使用して、リンクされたテンプレート sharedTemplateUrlvmTemplateUrl用の 2 つの URL を作成する方法を示します。

"variables": {
  "templateBaseUrl": "https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/application-workloads/postgre/postgresql-on-ubuntu/",
  "sharedTemplateUrl": "[uri(variables('templateBaseUrl'), 'shared-resources.json')]",
  "vmTemplateUrl": "[uri(variables('templateBaseUrl'), 'database-2disk-resources.json')]"
}

deployment()を使用して現在のテンプレートのベース URL を取得し、これを使用して同じ場所にある他のテンプレートの URL を取得することもできます。 この方法は、テンプレートの場所が変更された場合や、テンプレート ファイルのハード コーディング URL を回避する必要がある場合に便利です。 templateLink プロパティは、URL を含むリモート テンプレートにリンクした場合にのみ返されます。 ローカル テンプレートを使用している場合、そのプロパティは使用できません。

"variables": {
  "sharedTemplateUrl": "[uri(deployment().properties.templateLink.uri, 'shared-resources.json')]"
}

最終的には、uri プロパティの templateLink プロパティで変数を使用します。

"templateLink": {
 "uri": "[variables('sharedTemplateUrl')]",
 "contentVersion":"1.0.0.0"
}

コピーを使用する

入れ子になったテンプレートを使用してリソースの複数のインスタンスを作成するには、copy リソースのレベルで Microsoft.Resources/deployments 要素を追加します。 または、スコープが inner の場合は、入れ子になったテンプレート内にコピーを追加できます。

次のテンプレート例は、入れ子になったテンプレートで copy を使用する方法を示しています。

"resources": [
  {
    "type": "Microsoft.Resources/deployments",
    "apiVersion": "2025-04-01",
    "name": "[format('nestedTemplate{0}', copyIndex())]",
    // yes, copy works here
    "copy": {
      "name": "storagecopy",
      "count": 2
    },
    "properties": {
      "mode": "Incremental",
      "expressionEvaluationOptions": {
        "scope": "inner"
      },
      "template": {
        "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
        "contentVersion": "1.0.0.0",
        "resources": [
          {
            "type": "Microsoft.Storage/storageAccounts",
            "apiVersion": "2025-06-01",
            "name": "[format('{0}{1}', variables('storageName'), copyIndex())]",
            "location": "West US",
            "sku": {
              "name": "Standard_LRS"
            },
            "kind": "StorageV2"
            // Copy works here when scope is inner
            // But, when scope is default or outer, you get an error
            // "copy": {
            //   "name": "storagecopy",
            //   "count": 2
            // }
          }
        ]
      }
    }
  }
]

リンク済みテンプレートから値を取得する

リンクされたテンプレートから出力値を取得するには、"[reference('deploymentName').outputs.propertyName.value]" のような構文でプロパティ値を取得します。

リンクされたテンプレートから出力プロパティを取得する場合、プロパティ名にダッシュを含めることはできません。

次の例では、リンクされたテンプレートを参照して、出力値を取得する方法を示します。 リンクされたテンプレートは、単純なメッセージを返します。 最初に、リンクされたテンプレートを示します。

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {},
  "variables": {},
  "resources": [],
  "outputs": {
    "greetingMessage": {
      "value": "Hello World",
      "type": "string"
    }
  }
}

メイン テンプレートは、リンクされたテンプレートを展開し、返される値を取得します。 デプロイ リソースを名前で参照し、リンクされたテンプレートによって返されるプロパティの名前を使用していることに注意してください。

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {},
  "variables": {},
  "resources": [
    {
      "type": "Microsoft.Resources/deployments",
      "apiVersion": "2025-04-01",
      "name": "linkedTemplate",
      "properties": {
        "mode": "incremental",
        "templateLink": {
          "uri": "[uri(deployment().properties.templateLink.uri, 'helloworld.json')]",
          "contentVersion": "1.0.0.0"
        }
      }
    }
  ],
  "outputs": {
    "messageFromLinkedTemplate": {
      "type": "string",
      "value": "[reference('linkedTemplate').outputs.greetingMessage.value]"
    }
  }
}

次の例では、パブリック IP アドレスをデプロイし、そのパブリック IP の Azure リソースのリソース ID を返すテンプレートを示します。

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "publicIPAddresses_name": {
      "type": "string"
    }
  },
  "variables": {},
  "resources": [
    {
      "type": "Microsoft.Network/publicIPAddresses",
      "apiVersion": "2025-01-01",
      "name": "[parameters('publicIPAddresses_name')]",
      "location": "eastus",
      "properties": {
        "publicIPAddressVersion": "IPv4",
        "publicIPAllocationMethod": "Dynamic",
        "idleTimeoutInMinutes": 4
      },
      "dependsOn": []
    }
  ],
  "outputs": {
    "resourceID": {
      "type": "string",
      "value": "[resourceId('Microsoft.Network/publicIPAddresses', parameters('publicIPAddresses_name'))]"
    }
  }
}

ロード バランサーのデプロイ時に、前のテンプレートからのパブリック IP アドレスを使用するには、テンプレートにリンクし、Microsoft.Resources/deployments リソースで依存関係を宣言します。 ロード バランサーのパブリック IP アドレスは、リンクされたテンプレートからの出力値に設定されます。

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "loadBalancers_name": {
      "defaultValue": "mylb",
      "type": "string"
    },
    "publicIPAddresses_name": {
      "defaultValue": "myip",
      "type": "string"
    }
  },
  "variables": {},
  "resources": [
    {
      "type": "Microsoft.Network/loadBalancers",
      "apiVersion": "2025-01-01",
      "name": "[parameters('loadBalancers_name')]",
      "location": "eastus",
      "properties": {
        "frontendIPConfigurations": [
          {
            "name": "LoadBalancerFrontEnd",
            "properties": {
              "privateIPAllocationMethod": "Dynamic",
              "publicIPAddress": {
                "id": "[reference('linkedTemplate').outputs.resourceID.value]"
              }
            }
          }
        ],
        "backendAddressPools": [],
        "loadBalancingRules": [],
        "probes": [],
        "inboundNatRules": [],
        "outboundNatRules": [],
        "inboundNatPools": []
      },
      "dependsOn": [
        "[resourceId('Microsoft.Resources/deployments', 'linkedTemplate')]"
      ]
    },
    {
      "type": "Microsoft.Resources/deployments",
      "apiVersion": "2025-04-01",
      "name": "linkedTemplate",
      "properties": {
        "mode": "Incremental",
        "templateLink": {
          "uri": "[uri(deployment().properties.templateLink.uri, 'public-ip.json')]",
          "contentVersion": "1.0.0.0"
        },
        "parameters": {
          "publicIPAddresses_name": { "value": "[parameters('publicIPAddresses_name')]" }
        }
      }
    }
  ]
}

デプロイ履歴

Resource Manager では、各テンプレートはデプロイ履歴内で個別のデプロイとして処理されます。 3 つのリンクされたテンプレートまたは入れ子になったテンプレートがあるメイン テンプレートは、デプロイ履歴に次のように表示されます。

Azure portal に表示されたデプロイの履歴のスクリーンショット。

履歴内のこれらの個別のエントリを使用して、展開後に出力値を取得できます。 次のテンプレートは、パブリック IP アドレスを作成し、IP アドレスを出力します。

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "publicIPAddresses_name": {
      "type": "string"
    },
    "location": {
      "type": "string",
      "defaultValue": "[resourceGroup().location]"
    }
  },
  "variables": {},
  "resources": [
    {
      "type": "Microsoft.Network/publicIPAddresses",
      "apiVersion": "2025-01-01",
      "name": "[parameters('publicIPAddresses_name')]",
      "location": "[parameters('location')]",
      "properties": {
        "publicIPAddressVersion": "IPv4",
        "publicIPAllocationMethod": "Static",
        "idleTimeoutInMinutes": 4,
        "dnsSettings": {
          "domainNameLabel": "[format('{0}{1}', parameters('publicIPAddresses_name'), uniqueString(resourceGroup().id))]"
        }
      },
      "dependsOn": []
    }
  ],
  "outputs": {
    "returnedIPAddress": {
      "type": "string",
      "value": "[reference(parameters('publicIPAddresses_name')).ipAddress]"
    }
  }
}

次のテンプレートは、前のテンプレートにリンクします。 3 つのパブリック IP アドレスが作成されます。

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
  },
  "variables": {},
  "resources": [
    {
      "type": "Microsoft.Resources/deployments",
      "apiVersion": "2025-04-01",
      "name": "[format('linkedTemplate{0}', copyIndex())]",
      "copy": {
        "count": 3,
        "name": "ip-loop"
      },
      "properties": {
        "mode": "Incremental",
        "templateLink": {
        "uri": "[uri(deployment().properties.templateLink.uri, 'static-public-ip.json')]",
        "contentVersion": "1.0.0.0"
        },
        "parameters":{
          "publicIPAddresses_name":{"value": "[format('myip-{0}', copyIndex())]"}
        }
      }
    }
  ]
}

展開後、次の PowerShell スクリプトを使用して、出力値を取得できます。

$loopCount = 3
for ($i = 0; $i -lt $loopCount; $i++)
{
  $name = 'linkedTemplate' + $i;
  $deployment = Get-AzResourceGroupDeployment -ResourceGroupName examplegroup -Name $name
  Write-Output "deployment $($deployment.DeploymentName) returned $($deployment.Outputs.returnedIPAddress.value)"
}

または、Bash シェルの Azure CLI スクリプト:

#!/bin/bash

for i in 0 1 2;
do
  name="linkedTemplate$i";
  deployment=$(az deployment group show -g examplegroup -n $name);
  ip=$(echo $deployment | jq .properties.outputs.returnedIPAddress.value);
  echo "deployment $name returned $ip";
done

外部テンプレートをセキュリティで保護する

リンクされたテンプレートは外部から利用可能でなければなりませんが、一般公開する必要はありません。 ストレージ アカウント所有者のみがアクセスできるプライベート ストレージ アカウントにテンプレートを追加できます。 次に、デプロイ時にアクセスできるように、Shared Access Signature (SAS) トークンを作成します。 リンクされたテンプレートの URI に SAS トークンを追加します。 トークンがセキュリティで保護された文字列として渡された場合でも、SAS トークンを含むリンクされたテンプレートの URI が、デプロイ操作中にログに記録されます。 公開を制限するには、トークンの有効期限を設定します。

パラメーター ファイルは、SAS トークンを介したアクセスに制限することもできます。

現時点では、 Azure Storage ファイアウォールの背後にあるストレージ アカウント内のテンプレートにリンクすることはできません。

重要

SAS トークンを使用してリンクされたテンプレートをセキュリティで保護する代わりに、テンプレート スペックを作成することを検討してください。テンプレート スペックでは、メイン テンプレートとそのリンクされたテンプレートが、Azure サブスクリプションのリソースとして安全に格納されます。 Azure RBAC を使用して、テンプレートをデプロイする必要があるユーザーにアクセス権を付与します。

次の例は、テンプレートにリンクするときに、SAS トークンを渡す方法を示します。

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "containerSasToken": { "type": "securestring" }
  },
  "resources": [
    {
      "type": "Microsoft.Resources/deployments",
      "apiVersion": "2025-04-01",
      "name": "linkedTemplate",
      "properties": {
        "mode": "Incremental",
        "templateLink": {
          "uri": "[format('{0}{1}', uri(deployment().properties.templateLink.uri, 'helloworld.json'), parameters('containerSasToken'))]",
          "contentVersion": "1.0.0.0"
        }
      }
    }
  ],
  "outputs": {
  }
}

PowerShell では、コンテナーのトークンを取得し、次のコマンドを使ってテンプレートを展開します。 containerSasToken パラメーターはテンプレートで定義されていることに注意してください。 New-AzResourceGroupDeployment コマンド内のパラメーターではありません。

Set-AzCurrentStorageAccount -ResourceGroupName ManageGroup -Name storagecontosotemplates
$token = New-AzStorageContainerSASToken -Name templates -Permission r -ExpiryTime (Get-Date).AddMinutes(30.0)
$url = (Get-AzStorageBlob -Container templates -Blob parent.json).ICloudBlob.uri.AbsoluteUri
New-AzResourceGroupDeployment -ResourceGroupName ExampleGroup -TemplateUri ($url + $token) -containerSasToken $token

Bash シェルの Azure CLI では、コンテナーのトークンを取得し、次のコードを使用してテンプレートをデプロイします。

#!/bin/bash

expiretime=$(date -u -d '30 minutes' +%Y-%m-%dT%H:%MZ)
connection=$(az storage account show-connection-string \
  --resource-group ManageGroup \
  --name storagecontosotemplates \
  --query connectionString)
token=$(az storage container generate-sas \
  --name templates \
  --expiry $expiretime \
  --permissions r \
  --output tsv \
  --connection-string $connection)
url=$(az storage blob url \
  --container-name templates \
  --name parent.json \
  --output tsv \
  --connection-string $connection)
parameter='{"containerSasToken":{"value":"?'$token'"}}'
az deployment group create --resource-group ExampleGroup --template-uri $url?$token --parameters $parameter

サンプル テンプレート

次の例は、リンク済みテンプレートの一般的な使い方を示します。

メイン テンプレート リンク済みテンプレート 説明
ハローワールド リンク済みテンプレート リンク済みテンプレートから文字列を返します。
パブリック IP アドレスを使用する Azure Load Balancer リンク済みテンプレート リンク済みテンプレートからパブリック IP アドレスを返し、ロード バランサーでその値を設定します。
複数の IP アドレス リンク済みテンプレート リンク済みテンプレートにいくつかのパブリック IP アドレスを作成します。

次のステップ