您现在访问的是微软AZURE全球版技术文档网站,若需要访问由世纪互联运营的MICROSOFT AZURE中国区技术文档网站,请访问 https://docs.azure.cn.

部署 Azure 资源时使用链接模版和嵌套模版Using linked and nested templates when deploying Azure resources

若要部署解决方案,可以使用单个模板或包含任意相关模板的主模板。To deploy your solution, you can use either a single template or a main template with many related templates. 相关模板可以是从主模板链接到的单独文件,也可以是嵌套在主模板中的模板。The related template can be either a separate file that is linked to from the main template, or a template that is nested within the main template.

对于中小型解决方案,单个模板更易于理解和维护。For small to medium solutions, a single template is easier to understand and maintain. 可以查看单个文件中的所有资源和值。You can see all the resources and values in a single file. 对于高级方案,使用链接模板可将解决方案分解为目标组件,并重复使用模板。For advanced scenarios, linked templates enable you to break down the solution into targeted components, and reuse templates.

使用链接模板时,需创建一个用于在部署期间接收参数值的主模板。When using linked template, you create a main template that receives the parameter values during deployment. 主模板包含所有链接模板,并根据需要将值传递给这些模板。The main template contains all the linked templates and passes values to those templates as needed.

若要链接到另一个模板,请将一个部署资源添加到主模板。To link to another template, add a deployments resource to your main template.

"resources": [
  {
      "apiVersion": "2017-05-10",
      "name": "linkedTemplate",
      "type": "Microsoft.Resources/deployments",
      "properties": {
          "mode": "Incremental",
          <nested-template-or-external-template>
      }
  }
]

为部署资源提供的属性将因要链接到外部模板,还是要将内联模板嵌套在主模板中而异。The properties you provide for the deployment resource vary based on whether you are linking to an external template or nesting an inline template in the main template.

对于链接模板和嵌套模板,只能使用增量部署模式。For both linked and nested templates, you can only use Incremental deployment mode.

嵌套模板Nested template

若要将模板嵌套在主模板中,请使用 template 属性并指定模板语法。To nest the template within the main template, use the template property and specify the template syntax.

"resources": [
  {
    "apiVersion": "2017-05-10",
    "name": "nestedTemplate",
    "type": "Microsoft.Resources/deployments",
    "properties": {
      "mode": "Incremental",
      "template": {
        "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
        "contentVersion": "1.0.0.0",
        "resources": [
          {
            "type": "Microsoft.Storage/storageAccounts",
            "name": "[variables('storageName')]",
            "apiVersion": "2015-06-15",
            "location": "West US",
            "properties": {
              "accountType": "Standard_LRS"
            }
          }
        ]
      }
    }
  }
]

备注

对于嵌套模板,不能使用嵌套模板中定义的参数或变量。For nested templates, you cannot use parameters or variables that are defined within the nested template. 可以使用主模板中的参数和变量。You can use parameters and variables from the main template. 在前面的示例中,[variables('storageName')] 从主模板(而不是嵌套模板)中检索值。In the preceding example, [variables('storageName')] retrieves a value from the main template, not the nested template. 此限制不适用于外部模版。This restriction does not apply to external templates.

不能在嵌套模板的 outputs 节中使用 reference 函数。You cannot use the reference function in the outputs section of a nested template. 若要返回嵌套模板中部署的资源的值,请将嵌套模板转换为链接模板。To return the values for a deployed resource in a nested template, convert your nested template to a linked template.

嵌套模板需要与标准模板相同的属性The nested template requires the same properties as a standard template.

外部模板和外部参数External template and external parameters

若要链接到外部模板和参数文件,请使用 templateLinkparametersLinkTo link to an external template and parameter file, use templateLink and parametersLink. 链接到某个模板时,资源管理器服务必须能够访问该模板。When linking to a template, the Resource Manager service must be able to access it. 不能指定本地文件,或者只能在本地网络中使用的文件。You cannot specify a local file or a file that is only available on your local network. 只能提供包含 httphttps 的 URI 值。You can only provide a URI value that includes either http or https. 一种做法是将链接模板放入存储帐户,并对该项使用 URI。One option is to place your linked template in a storage account, and use the URI for that item.

"resources": [
  {
     "apiVersion": "2017-05-10",
     "name": "linkedTemplate",
     "type": "Microsoft.Resources/deployments",
     "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"
       }
     }
  }
]

无需为模板或参数提供 contentVersion 属性。You don't have to provide the contentVersion property for the template or parameters. 如果未提供内容版本值,将部署模板的当前版本。If you don't provide a content version value, the current version of the template is deployed. 如果提供内容版本值,它必须与链接的模板中的版本相匹配;否则,部署失败并产生错误。If you provide a value for content version, it must match the version in the linked template; otherwise, the deployment fails with an error.

外部模板和内联参数External template and inline parameters

或者,可以提供内联参数。Or, you can provide the parameter inline. 若要将值从主模板传递给链接模板,请使用参数To pass a value from the main template to the linked template, use parameters.

"resources": [
  {
     "apiVersion": "2017-05-10",
     "name": "linkedTemplate",
     "type": "Microsoft.Resources/deployments",
     "properties": {
       "mode": "incremental",
       "templateLink": {
          "uri":"https://mystorageaccount.blob.core.windows.net/AzureTemplates/newStorageAccount.json",
          "contentVersion":"1.0.0.0"
       },
       "parameters": {
          "StorageAccountName":{"value": "[parameters('StorageAccountName')]"}
        }
     }
  }
]

前面的示例演示了用于模板链接的硬编码 URL 值。The previous examples showed hard-coded URL values for the template links. 这种方法可能适用于简单的模板,但如果使用一组大型模块化模板时,将无法正常工作。This approach might work for a simple template but it doesn't work well when working with a large set of modular templates. 相反,可以创建一个存储主模板的基 URL 的静态变量,并从基 URL 动态创建用于链接模板的 URL。Instead, you can create a static variable that stores a base URL for the main template and then dynamically create URLs for the linked templates from that base URL. 这种方法的好处是可以轻松地移动或派生模板,因为只需在主模板中更改静态变量。The benefit of this approach is you can easily move or fork the template because you only need to change the static variable in the main template. 主模板会在整个分解后的模板中传递正确的 URI。The main template passes the correct URIs throughout the decomposed template.

以下示例演示如何使用基 URL 来创建两个用于链接模板的 URL(sharedTemplateUrlvmTemplate)。The following example shows how to use a base URL to create two URLs for linked templates (sharedTemplateUrl and vmTemplate).

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

还可以使用 deployment() 获取当前模板的基 URL,并使用该 URL 来获取同一位置其他模板的 URL。You can also use deployment() to get the base URL for the current template, and use that to get the URL for other templates in the same location. 如果模板位置发生变化或者想要避免对模板文件中的 URL 进行硬编码,则此方法非常有用。This approach is useful if your template location changes or you want to avoid hard coding URLs in the template file. 仅当链接到带有 URL 的远程模板时,才会返回 templateLink 属性。The templateLink property is only returned when linking to a remote template with a URL. 如果使用的是本地模板,该属性不可用。If you're using a local template, that property isn't available.

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

从链接模板中获取值Get values from linked template

若要从链接模板中获取输出值,请使用如下所示的语法检索属性值:"[reference('<name-of-deployment>').outputs.<property-name>.value]"To get an output value from a linked template, retrieve the property value with syntax like: "[reference('<name-of-deployment>').outputs.<property-name>.value]".

以下示例演示如何引用链接模板和检索输出值。The following examples demonstrate how to reference a linked template and retrieve an output value. 链接模板返回一条简单的消息。The linked template returns a simple message.

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

主模板部署链接模板并获取返回值。The main template deploys the linked template and gets the returned value. 请注意,该模板按名称引用部署资源,并使用链接模板返回的属性的名称。Notice that it references the deployment resource by name, and it uses the name of the property returned by the linked template.

{
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {},
    "variables": {},
    "resources": [
        {
            "apiVersion": "2017-05-10",
            "name": "linkedTemplate",
            "type": "Microsoft.Resources/deployments",
            "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]"
        }
    }
}

与其他资源类型一样,可在链接的模板和其他资源间设置依赖关系。Like other resource types, you can set dependencies between the linked template and other resources. 因此,当其他资源需要链接模板的输出值时,请确保在部署这些资源之前部署链接模板。Therefore, when other resources require an output value from the linked template, make sure the linked template is deployed before them. 或者,当链接模板依赖于其他资源时,请确保在部署链接模板之前部署其他资源。Or, when the linked template relies on other resources, make sure other resources are deployed before the linked template.

以下示例演示一个部署公共 IP 地址并返回资源 ID 的模板:The following example shows a template that deploys a public IP address and returns the resource ID:

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

在部署负载均衡器时,若要使用前面所述模板中的公共 IP 地址,请链接到该模板,并添加与部署资源之间的依赖关系。To use the public IP address from the preceding template when deploying a load balancer, link to the template and add a dependency on the deployment resource. 负载均衡器上的公共 IP 地址设置为链接模板的输出值。The public IP address on the load balancer is set to the output value from the linked template.

{
    "$schema": "https://schema.management.azure.com/schemas/2015-01-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",
            "name": "[parameters('loadBalancers_name')]",
            "apiVersion": "2017-06-01",
            "location": "eastus",
            "properties": {
                "frontendIPConfigurations": [
                    {
                        "name": "LoadBalancerFrontEnd",
                        "properties": {
                            "privateIPAllocationMethod": "Dynamic",
                            "publicIPAddress": {
                                "id": "[reference('linkedTemplate').outputs.resourceID.value]"
                            }
                        }
                    }
                ],
                "backendAddressPools": [],
                "loadBalancingRules": [],
                "probes": [],
                "inboundNatRules": [],
                "outboundNatRules": [],
                "inboundNatPools": []
            },
            "dependsOn": [
                "linkedTemplate"
            ]
        },
        {
            "apiVersion": "2017-05-10",
            "name": "linkedTemplate",
            "type": "Microsoft.Resources/deployments",
            "properties": {
                "mode": "Incremental",
                "templateLink": {
                    "uri": "[uri(deployment().properties.templateLink.uri, 'publicip.json')]",
                    "contentVersion": "1.0.0.0"
                },
                "parameters":{
                    "publicIPAddresses_name":{"value": "[parameters('publicIPAddresses_name')]"}
                }
            }
        }
    ]
}

部署历史记录中的链接模板和嵌套模板Linked and nested templates in deployment history

资源管理器将每个模板作为部署历史记录中的单独部署进行处理。Resource Manager processes each template as a separate deployment in the deployment history. 因此,包含三个链接模板或嵌套模板的主模板在部署历史记录中显示为:Therefore, a main template with three linked or nested templates appears in the deployment history as:

部署历史记录

部署后,可以使用历史记录中这些不同的条目来检索输出值。You can use these separate entries in the history to retrieve output values after the deployment. 以下模板创建一个公共 IP 地址并输出该 IP 地址:The following template creates a public IP address and outputs the IP address:

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

以下模板链接到前面所述的模板。The following template links to the preceding template. 它创建三个公共 IP 地址。It creates three public IP addresses.

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

部署后,可使用以下 PowerShell 脚本检索输出值:After the deployment, you can retrieve the output values with the following PowerShell script:

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

或使用 Azure CLI 脚本:Or, Azure CLI script:

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

保护外部模板Securing an external template

尽管链接模板必须可从外部使用,但它无需向公众正式发布。Although the linked template must be externally available, it doesn't need to be generally available to the public. 可以将模板添加到只有存储帐户所有者可以访问的专用存储帐户。You can add your template to a private storage account that is accessible to only the storage account owner. 然后,在部署期间创建共享访问签名 (SAS) 令牌,用于启用访问。Then, you create a shared access signature (SAS) token to enable access during deployment. 将该 SAS 令牌添加到链接模板的 URI。You add that SAS token to the URI for the linked template. 即使令牌作为安全字符串传入,链接模板的 URI(包括 SAS 令牌)也将记录在部署操作中。Even though the token is passed in as a secure string, the URI of the linked template, including the SAS token, is logged in the deployment operations. 若要限制公开,请设置令牌的到期时间。To limit exposure, set an expiration for the token.

也可将参数文件限制为通过 SAS 令牌进行访问。The parameter file can also be limited to access through a SAS token.

以下示例演示在链接到模板时如何传递 SAS 令牌:The following example shows how to pass a SAS token when linking to a template:

{
  "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "containerSasToken": { "type": "string" }
  },
  "resources": [
    {
      "apiVersion": "2017-05-10",
      "name": "linkedTemplate",
      "type": "Microsoft.Resources/deployments",
      "properties": {
        "mode": "incremental",
        "templateLink": {
          "uri": "[concat(uri(deployment().properties.templateLink.uri, 'helloworld.json'), parameters('containerSasToken'))]",
          "contentVersion": "1.0.0.0"
        }
      }
    }
  ],
  "outputs": {
  }
}

在 PowerShell 中,使用以下命令获取容器的令牌并部署模板。In PowerShell, you get a token for the container and deploy the templates with the following commands. 注意,containerSasToken 参数是在模板中定义的。Notice that the containerSasToken parameter is defined in the template. 它不是 New-AzureRmResourceGroupDeployment 命令中的参数。It isn't a parameter in the New-AzureRmResourceGroupDeployment command.

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

在 Azure CLI 中,使用以下代码获取容器的令牌并部署模板:In Azure CLI, you get a token for the container and deploy the templates with the following code:

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 group deployment create --resource-group ExampleGroup --template-uri $url?$token --parameters $parameter

示例模板Example templates

以下示例演示了链接模板的常见用法。The following examples show common uses of linked templates.

主模板Main template 链接模板Linked template DescriptionDescription
Hello WorldHello World 链接模板linked template 从链接模板返回字符串。Returns string from linked template.
使用公共 IP 地址的负载均衡器Load Balancer with public IP address 链接模板linked template 从链接模板返回公共 IP 地址,并在负载均衡器中设置该值。Returns public IP address from linked template and sets that value in load balancer.
多个 IP 地址Multiple IP addresses 链接模板linked template 在链接模板中创建多个公共 IP 地址。Creates several public IP addresses in linked template.

后续步骤Next steps