跨订阅或资源组部署 Azure 资源Deploy Azure resources across subscriptions or resource groups

通常情况下,将模板中的所有资源部署到单个资源组Typically, you deploy all the resources in your template to a single resource group. 不过,在某些情况下,你可能希望将一组资源部署在一起但将其放置在不同的资源组或订阅中。However, there are scenarios where you want to deploy a set of resources together but place them in different resource groups or subscriptions. 例如,你可能希望将 Azure Site Recovery 的备份虚拟机部署到一个单独的资源组和位置。For example, you may want to deploy the backup virtual machine for Azure Site Recovery to a separate resource group and location. 资源管理器允许使用嵌套模板,以多个订阅和资源组为目标。Resource Manager enables you to use nested templates to target more than one subscription and resource group.

Note

在单个部署中可以仅部署到五个资源组。You can deploy to only five resource groups in a single deployment. 通常情况下,此限制意味着,在嵌套或链接的部署中可以部署到为父模板指定的一个资源组和最多四个资源组。Typically, this limitation means you can deploy to one resource group specified for the parent template, and up to four resource groups in nested or linked deployments. 但是,如果父模板仅包含嵌套或链接的模板,并且本身不部署任何资源,则在嵌套或链接的部署中最多可包含五个资源组。However, if your parent template contains only nested or linked templates and does not itself deploy any resources, then you can include up to five resource groups in nested or linked deployments.

指定订阅和资源组Specify subscription and resource group

若要以其他资源组或订阅为目标,请使用嵌套或链接模板To target a different resource group or subscription, use a nested or linked template. Microsoft.Resources/deployments 资源类型为 subscriptionIdresourceGroup 提供参数,使你可以为嵌套部署指定订阅和资源组。The Microsoft.Resources/deployments resource type provides parameters for subscriptionId and resourceGroup, which enable you to specify the subscription and resource group for the nested deployment. 如果未指定订阅 ID 或资源组,将使用父模板中的订阅和资源组。If you don't specify the subscription ID or resource group, the subscription and resource group from the parent template is used. 在运行部署之前,所有资源组都必须存在。All the resource groups must exist before running the deployment.

用于部署模板的帐户必须有权部署到指定的订阅 ID。The account you use to deploy the template must have permissions to deploy to the specified subscription ID.

若要指定其他资源组和订阅,请使用:To specify a different resource group and subscription, use:

{
  "type": "Microsoft.Resources/deployments",
  "apiVersion": "2019-10-01",
  "name": "nestedTemplate",
  "resourceGroup": "[parameters('secondResourceGroup')]",
  "subscriptionId": "[parameters('secondSubscriptionID')]",

如果资源组属于同一订阅,则可删除 subscriptionId 值。If your resource groups are in the same subscription, you can remove the subscriptionId value.

以下示例部署两个存储帐户。The following example deploys two storage accounts. 第一个存储帐户部署到在部署操作中指定的资源组。The first storage account is deployed to the resource group specified in the deployment operation. 第二个存储帐户部署到在 secondResourceGroupsecondSubscriptionID 参数中指定的资源组:The second storage account is deployed to the resource group specified in the secondResourceGroup and secondSubscriptionID parameters:

{
  "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "storagePrefix": {
      "type": "string",
      "maxLength": 11
    },
    "secondResourceGroup": {
      "type": "string"
    },
    "secondSubscriptionID": {
      "type": "string",
      "defaultValue": ""
    },
    "secondStorageLocation": {
      "type": "string",
      "defaultValue": "[resourceGroup().location]"
    }
  },
  "variables": {
    "firstStorageName": "[concat(parameters('storagePrefix'), uniqueString(resourceGroup().id))]",
    "secondStorageName": "[concat(parameters('storagePrefix'), uniqueString(parameters('secondSubscriptionID'), parameters('secondResourceGroup')))]"
  },
  "resources": [
    {
      "type": "Microsoft.Storage/storageAccounts",
      "apiVersion": "2019-06-01",
      "name": "[variables('firstStorageName')]",
      "location": "[resourceGroup().location]",
      "sku":{
        "name": "Standard_LRS"
      },
      "kind": "Storage",
      "properties": {
      }
    },
    {
      "type": "Microsoft.Resources/deployments",
      "apiVersion": "2019-10-01",
      "name": "nestedTemplate",
      "resourceGroup": "[parameters('secondResourceGroup')]",
      "subscriptionId": "[parameters('secondSubscriptionID')]",
      "properties": {
      "mode": "Incremental",
      "template": {
          "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
          "contentVersion": "1.0.0.0",
          "parameters": {},
          "variables": {},
          "resources": [
          {
            "type": "Microsoft.Storage/storageAccounts",
            "apiVersion": "2019-06-01",
            "name": "[variables('secondStorageName')]",
            "location": "[parameters('secondStorageLocation')]",
            "sku":{
              "name": "Standard_LRS"
            },
            "kind": "Storage",
            "properties": {
            }
          }
          ]
      },
      "parameters": {}
      }
    }
  ]
}

如果将 resourceGroup 设置为不存在的资源组的名称,则部署会失败。If you set resourceGroup to the name of a resource group that doesn't exist, the deployment fails.

若要测试上述模板并查看结果,请使用 PowerShell 或 Azure CLI。To test the preceding template and see the results, use PowerShell or Azure CLI.

若要将两个存储帐户部署到同一订阅中的两个资源组,请使用:To deploy two storage accounts to two resource groups in the same subscription, use:

$firstRG = "primarygroup"
$secondRG = "secondarygroup"

New-AzResourceGroup -Name $firstRG -Location chinaeast
New-AzResourceGroup -Name $secondRG -Location chinaeast

New-AzResourceGroupDeployment `
  -ResourceGroupName $firstRG `
  -TemplateUri https://raw.githubusercontent.com/Azure/azure-docs-json-samples/master/azure-resource-manager/crosssubscription.json `
  -storagePrefix storage `
  -secondResourceGroup $secondRG `
  -secondStorageLocation chinaeast

若要将两个存储帐户部署到两个订阅,请使用:To deploy two storage accounts to two subscriptions, use:

$firstRG = "primarygroup"
$secondRG = "secondarygroup"

$firstSub = "<first-subscription-id>"
$secondSub = "<second-subscription-id>"

Select-AzSubscription -Subscription $secondSub
New-AzResourceGroup -Name $secondRG -Location chinaeast

Select-AzSubscription -Subscription $firstSub
New-AzResourceGroup -Name $firstRG -Location chinaeast

New-AzResourceGroupDeployment `
  -ResourceGroupName $firstRG `
  -TemplateUri https://raw.githubusercontent.com/Azure/azure-docs-json-samples/master/azure-resource-manager/crosssubscription.json `
  -storagePrefix storage `
  -secondResourceGroup $secondRG `
  -secondStorageLocation chinaeast `
  -secondSubscriptionID $secondSub

使用函数Use functions

resourceGroup()subscription() 函数根据指定模板的方式以不同的方式解析。The resourceGroup() and subscription() functions resolve differently based on how you specify the template. 链接到外部模板时,函数始终解析为该模板的作用域。When you link to an external template, the functions always resolve to the scope for that template. 在父模板中嵌套模板时,请使用 expressionEvaluationOptions 属性指定函数是否解析为父模板或嵌套模板的资源组和订阅。When you nest a template within a parent template, use the expressionEvaluationOptions property to specify whether the functions resolve to the resource group and subscription for the parent template or the nested template. 将属性设置为 inner,以便解析为嵌套模板的范围。Set the property to inner to resolve to the scope for the nested template. 将属性设置为 outer,以便解析为父模板的范围。Set the property to outer to resolve to the scope of the parent template.

下表显示了函数是解析为父资源组,还是解析为嵌入资源组和订阅。The following table shows whether the functions resolve to the parent or embedded resource group and subscription.

模板类型Template type 作用域Scope 解决方法Resolution
嵌套nested 外部(默认值)outer (default) 父资源组Parent resource group
嵌套nested 内部inner 子资源组Sub resource group
链接linked 空值N/A 子资源组Sub resource group

以下示例模板演示:The following example template shows:

  • 具有默认(外部)范围的嵌套模板nested template with default (outer) scope
  • 具有内部范围的嵌套模板nested template with inner scope
  • 链接的模板linked 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",
            "name": "defaultScopeTemplate",
            "apiVersion": "2017-05-10",
            "resourceGroup": "inlineGroup",
            "properties": {
                "mode": "Incremental",
                "template": {
                    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
                    "contentVersion": "1.0.0.0",
                    "parameters": {},
                    "variables": {},
                    "resources": [
                    ],
                    "outputs": {
                        "resourceGroupOutput": {
                            "type": "string",
                            "value": "[resourceGroup().name]"
                        }
                    }
                },
                "parameters": {}
            }
        },
        {
            "type": "Microsoft.Resources/deployments",
            "name": "innerScopeTemplate",
            "apiVersion": "2017-05-10",
            "resourceGroup": "inlineGroup",
            "properties": {
                "expressionEvaluationOptions": {
                    "scope": "inner"
                },
                "mode": "Incremental",
                "template": {
                    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
                    "contentVersion": "1.0.0.0",
                    "parameters": {},
                    "variables": {},
                    "resources": [
                    ],
                    "outputs": {
                        "resourceGroupOutput": {
                            "type": "string",
                            "value": "[resourceGroup().name]"
                        }
                    }
                },
                "parameters": {}
            }
        },
        {
            "apiVersion": "2017-05-10",
            "name": "linkedTemplate",
            "type": "Microsoft.Resources/deployments",
            "resourceGroup": "linkedGroup",
            "properties": {
                "mode": "Incremental",
                "templateLink": {
                    "contentVersion": "1.0.0.0",
                    "uri": "https://raw.githubusercontent.com/Azure/azure-docs-json-samples/master/azure-resource-manager/resourceGroupName.json"
                },
                "parameters": {}
            }
        }
    ],
    "outputs": {
        "parentRG": {
            "type": "string",
            "value": "[concat('Parent resource group is ', resourceGroup().name)]"
        },
        "defaultScopeRG": {
            "type": "string",
            "value": "[concat('Default scope resource group is ', reference('defaultScopeTemplate').outputs.resourceGroupOutput.value)]"
        },
        "innerScopeRG": {
            "type": "string",
            "value": "[concat('Inner scope resource group is ', reference('innerScopeTemplate').outputs.resourceGroupOutput.value)]"
        },
        "linkedRG": {
            "type": "string",
            "value": "[concat('Linked resource group is ', reference('linkedTemplate').outputs.resourceGroupOutput.value)]"
        }
    }
}

若要测试上述模板并查看结果,请使用 PowerShell 或 Azure CLI。To test the preceding template and see the results, use PowerShell or Azure CLI.

New-AzResourceGroup -Name parentGroup -Location chinaeast
New-AzResourceGroup -Name inlineGroup -Location chinaeast
New-AzResourceGroup -Name linkedGroup -Location chinaeast

New-AzResourceGroupDeployment `
  -ResourceGroupName parentGroup `
  -TemplateUri https://raw.githubusercontent.com/Azure/azure-docs-json-samples/master/azure-resource-manager/crossresourcegroupproperties.json

前述示例的输出为:The output from the preceding example is:

 Name             Type                       Value
 ===============  =========================  ==========
 parentRG         String                     Parent resource group is parentGroup
 defaultScopeRG   String                     Default scope resource group is parentGroup
 innerScopeRG     String                     Inner scope resource group is inlineGroup
 linkedRG         String                     Linked resource group is linkedgroup

后续步骤Next steps