Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Чтобы развернуть сложные решения, можно разбить шаблон Azure Resource Manager (шаблон ARM) на множество связанных шаблонов, а затем развернуть их вместе с помощью основного шаблона. Связанные шаблоны могут быть отдельными файлами или синтаксисом шаблона, внедренным в основной шаблон. В этой статье используется термин связанный шаблон для обозначения отдельного файла шаблона, на который ссылаются из основного шаблона. Он использует термин «вложенный шаблон», чтобы указать на встроенный синтаксис шаблона в основном шаблоне.
Для небольших и средних решений отдельный шаблон проще в понимании и обслуживании. Все ресурсы и значения можно увидеть в отдельном файле. Для более сложных сценариев связанные шаблоны позволяют разбить решение на целевые компоненты. Эти шаблоны можно многократно использовать в других сценариях.
Для получения инструкции см. руководство: Развертывание связанного шаблона.
Примечание.
Для связанных или вложенных шаблонов можно задать только режим развертывания добавочным. Однако основной шаблон можно развертывать в полноценном режиме. Если основной шаблон развертывается в режиме полного выполнения, а связанный или вложенный шаблон предназначен для одной и той же группы ресурсов, то ресурсы, развернутые в связанном или вложенном шаблоне, включаются в оценку развертывания в режиме полного выполнения. Объединенная коллекция ресурсов, развернутых в основном шаблоне, а также связанные или вложенные шаблоны, сравниваются с существующими ресурсами из группы ресурсов. Все ресурсы, не входящие в такой объединенный набор, будут удалены.
Если связанный или вложенный шаблон предназначен для другой группы ресурсов, при таком развертывании используется добавочный режим. Дополнительные сведения см. в разделе "Область развертывания".
Подсказка
рекомендуется 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"
}
]
}
}
}
}
}
Область видимости вычислений выражений во вложенных шаблонах
При использовании вложенного шаблона можно указать, вычисляются ли выражения шаблонов в пределах области родительского шаблона или вложенного шаблона. Область определяет, как разрешаются такие параметры, переменные и функции, как resourceGroup и subscription.
Вы задаёте область с помощью свойства 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 в разделе outputs вложенного шаблона для ресурса, который развернут во вложенном шаблоне. Чтобы вернуть значения развернутого ресурса в вложенном шаблоне, либо используйте область 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 изменяется в зависимости от значения свойства scope в expressionEvaluationOptions. В таблице ниже показаны результаты для обеих областей.
| Область оценки | Выходные данные |
|---|---|
| внутренний | из вложенного шаблона |
| внешний (или по умолчанию) | из родительского шаблона |
В следующем примере выполняется развертывание SQL Server и получение секрета хранилища ключей, используемого для пароля. Область имеет значение inner, поскольку динамически создает идентификатор хранилища ключей (см. adminPassword.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": {
}
}
Будьте внимательны, используя значения защищенных параметров во вложенном шаблоне. Если область установлена на outer, то защищенные значения будут храниться в открытом виде в истории развертывания. Просматривая шаблон в журнале развертывания, пользователь может видеть защищенные значения. Вместо этого используйте область inner или добавьте к родительскому шаблону ресурсы, которым требуются защищенные значения.
В следующем фрагменте показано, какие значения являются или не защищены:
{
"$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 должен иметь доступ к шаблону. Укажите значение URI, загружаемое как HTTP или HTTPS.
Вы можете ссылаться на шаблоны с помощью параметров, включающих 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. Чтобы получить необработанную ссылку, нажмите кнопку "Необработанный".
Примечание.
Сведения о развертывании шаблона или ссылке на связанный шаблон, хранящийся в частном репозитории GitHub, см. в пользовательском решении, описанном в Создание пользовательского и безопасного предложения портал Azure. Вы можете создать функцию Azure, которая извлекает маркер GitHub из Azure Key Vault.
Для связанных шаблонов можно вложить развертывание с несвязанным именем в шаблон символического имени, вложить развертывание с символическим именем в шаблон несвязанного имени или вложить развертывание с символическим именем в другой шаблон символического имени (или наоборот).
Параметры для связанного шаблона
Параметры для связанного шаблона можно указать во внешнем файле или встроить непосредственно. Если предоставляется внешний файл параметров, используйте свойство 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')]"
}
}
}
}
]
Нельзя использовать одновременно встроенные параметры и ссылку на их файл. Развертывание завершается с ошибкой, когда указываются parametersLink и parameters.
Используйте относительный путь для связанных шаблонов.
Свойство relativePath, являющееся частью Майкрософт.Resources/deployments, упрощает создание связанных шаблонов. Это свойство можно использовать для развертывания удаленного связанного шаблона в расположении, относящемся к родительскому элементу. Эта функция требует, чтобы все файлы шаблонов были подготовлены и доступны по удаленному URI, например, в GitHub или учетной записи хранения Azure. При вызове основного шаблона с помощью URI из Azure PowerShell или Azure CLI дочерний URI для развертывания является сочетанием родительского и относительного пути.
Примечание.
При создании templateSpec все шаблоны, на которые ссылается свойство relativePath, упаковываются в ресурс templateSpec с помощью Azure PowerShell или Azure CLI. Для этого не требуется размещение файлов. Дополнительные сведения см. в статье "Создание спецификации шаблона с связанными шаблонами".
Предположим, что структура папок выглядит следующим образом:
В следующем шаблоне показано, как 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, используйте параметр QueryString/query-string, чтобы указать маркер SAS, используемый с параметром TemplateUri. Этот параметр поддерживается только 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 для развертываний.
Спецификации шаблонов
Вместо того чтобы поддерживать ваши связанные шаблоны в доступной конечной точке, вы можете создать спецификацию шаблона, которая объединяет основной шаблон и связанные шаблоны в одну сущность для последующего развертывания. Спецификация шаблона — это ресурс в вашей подписке Azure. Такой способ позволяет с легкостью обеспечить безопасный общий доступ к шаблону для пользователей вашей организации. Вы используете управление доступом на основе ролей Azure (Azure RBAC) для предоставления доступа к шаблону спецификаций.
Дополнительные сведения см. в разделе:
- Руководство. Создание спецификации шаблона с связанными шаблонами.
- Руководство. Развертывание спецификации шаблона в виде связанного шаблона.
Зависимости
Как и в случае с другими типами ресурсов, можно задать зависимости между вложенными и связанными шаблонами. Если ресурсы в одном вложенном или связанном шаблоне должны быть развернуты перед тем, как ресурсы во втором вложенном или связанном шаблоне задайте второй шаблон, чтобы он зависел от первого:
{
"$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-адреса для связанных шаблонов на основе этого адреса. Преимущество этого подхода заключается в том, что его можно с легкостью перемещать или разветвлять, поскольку для этого надо лишь изменить статическую переменную в основном шаблоне. Основной шаблон передает правильные URI через весь разложенный шаблон.
В следующем примере показано, как использовать базовый URL-адрес для создания двух URL-адресов для связанных шаблонов sharedTemplateUrl и vmTemplateUrl:
"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 на уровне ресурса Майкрософт.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-адрес и возвращает идентификатор Azure ресурса для этого IP-адреса.
{
"$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-адрес из предыдущего шаблона при развертывании подсистемы балансировки нагрузки, свяжите с шаблоном и объявите зависимость от ресурса Майкрософт.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 обрабатывает каждый шаблон как отдельное развертывание в журнале развертывания. Основной шаблон с тремя связанными или вложенными шаблонами отображается в журнале развертывания следующим образом.
С помощью этих отдельных записей в журнале можно извлечь выходные значения после развертывания. Следующий шаблон создает общедоступный 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]"
}
}
}
Указанный ниже шаблон ссылается на предыдущий шаблон. Он создает три общедоступных 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)"
}
Или скрипт Azure CLI в оболочке Bash:
#!/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
Обеспечьте безопасность внешнего шаблона
Хотя связанный шаблон должен быть доступен извне, он не должен быть общедоступным. Вы можете добавить шаблон в частную учетную запись хранения, доступную только владельцу учетной записи хранения. Затем создайте маркер SAS, чтобы обеспечить доступ во время развертывания. Вы добавляете этот токен SAS к URI связанного шаблона. Несмотря на то, что токен передается в защищенной строке, URI связанного шаблона, содержащий SAS токен, добавляется в журнал операций развертывания. Чтобы снизить риск раскрытия, задайте срок действия маркера.
Файл параметров также может быть ограничен доступом через маркер SAS.
В настоящее время вы не можете ссылаться на шаблон в учетной записи хранения, которая находится за брандмауэром служба хранилища Azure.
Внимание
Вместо защиты связанного шаблона с помощью маркера SAS рекомендуется создать спецификацию template. Спецификация шаблона безопасно сохраняет основной шаблон и связанные шаблоны в качестве ресурса в подписке 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
Для Azure CLI в оболочке Bash вы получите токен для контейнера, а также развернёте шаблоны с помощью следующего кода:
#!/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
Образцы шаблонов
В следующих примерах показаны наиболее частые способы использования связанных шаблонов.
| Основной шаблон | Связанный шаблон | Описание |
|---|---|---|
| Всем привет | связанный шаблон | Возвращает строку из связанного шаблона. |
| Load Balancer с общедоступным IP-адресом | связанный шаблон | Возвращает общедоступный IP-адрес из связанного шаблона и задает это значение в подсистеме балансировки нагрузки. |
| Множественные IP-адреса | связанный шаблон | Создает несколько общедоступных IP-адресов в связанном шаблоне. |
Следующие шаги
- Чтобы пройти учебное пособие, см. Учебное пособие: Развертывание связанного шаблона.
- Чтобы узнать об определении порядка развертывания ресурсов, см. инструкции по определению порядка развертывания ресурсов в шаблонах ARM.
- Чтобы узнать, как определить один ресурс, но создать множество экземпляров, см. итерацию ресурсов в шаблонах ARM.
- Для получения инструкций по настройке шаблона в учетной записи хранилища и создании маркера SAS см. в разделе о том, как развернуть ресурсы с помощью шаблонов ARM и Azure PowerShell или развернуть ресурсы с помощью шаблонов ARM и Azure CLI.