将 Azure 资源部署到多个订阅或资源组Deploy Azure resources to more than one subscription or resource group

Note

本文进行了更新,以便使用新的 Azure PowerShell Az 模块。This article has been updated to use the new Azure PowerShell Az module. 你仍然可以使用 AzureRM 模块,至少在 2020 年 12 月之前,它将继续接收 bug 修补程序。You can still use the AzureRM module, which will continue to receive bug fixes until at least December 2020. 若要详细了解新的 Az 模块和 AzureRM 兼容性,请参阅新 Azure Powershell Az 模块简介To learn more about the new Az module and AzureRM compatibility, see Introducing the new Azure PowerShell Az module. 有关 Az 模块安装说明,请参阅安装 Azure PowerShellFor Az module installation instructions, see Install Azure PowerShell.

通常情况下,将模板中的所有资源部署到单个资源组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 different subscriptions and resource groups than the subscription and resource group used for the parent template.

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 a subscription and resource group

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

用于部署模板的帐户必须有权部署到指定的订阅 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:

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

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

以下示例部署两个存储帐户 - 一个在部署期间指定的资源组中,另一个在 secondResourceGroup 参数指定的资源组中:The following example deploys two storage accounts - one in the resource group specified during deployment, and one in a resource group specified in the secondResourceGroup parameter:

{
    "$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": [
        {
            "apiVersion": "2017-05-10",
            "name": "nestedTemplate",
            "type": "Microsoft.Resources/deployments",
            "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",
                            "name": "[variables('secondStorageName')]",
                            "apiVersion": "2017-06-01",
                            "location": "[parameters('secondStorageLocation')]",
                            "sku":{
                                "name": "Standard_LRS"
                            },
                            "kind": "Storage",
                            "properties": {
                            }
                        }
                    ]
                },
                "parameters": {}
            }
        },
        {
            "type": "Microsoft.Storage/storageAccounts",
            "name": "[variables('firstStorageName')]",
            "apiVersion": "2017-06-01",
            "location": "[resourceGroup().location]",
            "sku":{
                "name": "Standard_LRS"
            },
            "kind": "Storage",
            "properties": {
            }
        }
    ]
}

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

使用 resourceGroup() 和 subscription() 函数Use the resourceGroup() and subscription() functions

对于跨资源组部署,resourceGroup()subscription() 函数根据指定嵌套模板的方式以不同的方式解析。For cross resource group deployments, the resourceGroup() and subscription() functions resolve differently based on how you specify the nested template.

如果在一个模板内嵌入另一个模板,嵌套模板中的函数会解析到父资源组和订阅。If you embed one template within another template, the functions in the nested template resolve to the parent resource group and subscription. 嵌入模板使用以下格式:An embedded template uses the following format:

"apiVersion": "2017-05-10",
"name": "embeddedTemplate",
"type": "Microsoft.Resources/deployments",
"resourceGroup": "crossResourceGroupDeployment",
"properties": {
    "mode": "Incremental",
    "template": {
        ...
        resourceGroup() and subscription() refer to parent resource group/subscription
    }
}

如果链接到单独的模板,则链接模板中的函数会解析到嵌套资源组和订阅。If you link to a separate template, the functions in the linked template resolve to the nested resource group and subscription. 链接模板使用以下格式:A linked template uses the following format:

"apiVersion": "2017-05-10",
"name": "linkedTemplate",
"type": "Microsoft.Resources/deployments",
"resourceGroup": "crossResourceGroupDeployment",
"properties": {
    "mode": "Incremental",
    "templateLink": {
        ...
        resourceGroup() and subscription() in linked template refer to linked resource group/subscription
    }
}

示例模板Example templates

以下模板演示了多个资源组部署。The following templates demonstrate multiple resource group deployments. 用于部署模板的脚本在表后显示。Scripts to deploy the templates are shown after the table.

模板Template 说明Description
跨订阅模板Cross subscription template 将一个存储帐户部署到一个资源组,再将一个存储帐户部署到另一个资源组。Deploys one storage account to one resource group and one storage account to a second resource group. 当第二个资源组属于其他订阅时,包括一个用于订阅 ID 的值。Include a value for the subscription ID when the second resource group is in a different subscription.
跨资源组属性模板Cross resource group properties template 演示 resourceGroup() 函数如何解析。Demonstrates how the resourceGroup() function resolves. 它不部署任何资源。It does not deploy any resources.

PowerShellPowerShell

对于 PowerShell,若要将两个存储帐户部署到同一订阅中的两个资源组,请使用:For PowerShell, 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

对于 PowerShell,若要将两个存储帐户部署到两个订阅,请使用:For PowerShell, 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

对于 PowerShell,若要测试资源组对象如何针对父模板、内联模板和链接的模板进行解析,请使用:For PowerShell, to test how the resource group object resolves for the parent template, inline template, and linked template, use:

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

在前面的示例中,parentRGinlineRG 都解析为 parentGroupIn the preceding example, both parentRG and inlineRG resolve to parentGroup. linkedRG 解析为 linkedGrouplinkedRG resolves to linkedGroup. 前述示例的输出为:The output from the preceding example is:

 Name             Type                       Value
 ===============  =========================  ==========
 parentRG         Object                     {
                                               "id": "/subscriptions/<subscription-id>/resourceGroups/parentGroup",
                                               "name": "parentGroup",
                                               "location": "chinaeast",
                                               "properties": {
                                                 "provisioningState": "Succeeded"
                                               }
                                             }
 inlineRG         Object                     {
                                               "id": "/subscriptions/<subscription-id>/resourceGroups/parentGroup",
                                               "name": "parentGroup",
                                               "location": "chinaeast",
                                               "properties": {
                                                 "provisioningState": "Succeeded"
                                               }
                                             }
 linkedRG         Object                     {
                                               "id": "/subscriptions/<subscription-id>/resourceGroups/linkedGroup",
                                               "name": "linkedGroup",
                                               "location": "chinaeast",
                                               "properties": {
                                                 "provisioningState": "Succeeded"
                                               }
                                             }

Azure CLIAzure CLI

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

firstRG="primarygroup"
secondRG="secondarygroup"

az group create --name $firstRG --location chinaeast
az group create --name $secondRG --location chinaeast
az group deployment create \
  --name ExampleDeployment \
  --resource-group $firstRG \
  --template-uri https://raw.githubusercontent.com/Azure/azure-docs-json-samples/master/azure-resource-manager/crosssubscription.json \
  --parameters storagePrefix=tfstorage secondResourceGroup=$secondRG secondStorageLocation=chinaeast

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

firstRG="primarygroup"
secondRG="secondarygroup"

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

az account set --subscription $secondSub
az group create --name $secondRG --location chinaeast

az account set --subscription $firstSub
az group create --name $firstRG --location chinaeast

az group deployment create \
  --name ExampleDeployment \
  --resource-group $firstRG \
  --template-uri https://raw.githubusercontent.com/Azure/azure-docs-json-samples/master/azure-resource-manager/crosssubscription.json \
  --parameters storagePrefix=storage secondResourceGroup=$secondRG secondStorageLocation=chinaeast secondSubscriptionID=$secondSub

对于 Azure CLI,若要测试资源组对象如何针对父模板、内联模板和链接的模板进行解析,请使用:For Azure CLI, to test how the resource group object resolves for the parent template, inline template, and linked template, use:

az group create --name parentGroup --location chinaeast
az group create --name inlineGroup --location chinaeast
az group create --name linkedGroup --location chinaeast

az group deployment create \
  --name ExampleDeployment \
  --resource-group parentGroup \
  --template-uri https://raw.githubusercontent.com/Azure/azure-docs-json-samples/master/azure-resource-manager/crossresourcegroupproperties.json 

在前面的示例中,parentRGinlineRG 都解析为 parentGroupIn the preceding example, both parentRG and inlineRG resolve to parentGroup. linkedRG 解析为 linkedGrouplinkedRG resolves to linkedGroup. 前述示例的输出为:The output from the preceding example is:

...
"outputs": {
  "inlineRG": {
    "type": "Object",
    "value": {
      "id": "/subscriptions/<subscription-id>/resourceGroups/parentGroup",
      "location": "chinaeast",
      "name": "parentGroup",
      "properties": {
        "provisioningState": "Succeeded"
      }
    }
  },
  "linkedRG": {
    "type": "Object",
    "value": {
      "id": "/subscriptions/<subscription-id>/resourceGroups/linkedGroup",
      "location": "chinaeast",
      "name": "linkedGroup",
      "properties": {
        "provisioningState": "Succeeded"
      }
    }
  },
  "parentRG": {
    "type": "Object",
    "value": {
      "id": "/subscriptions/<subscription-id>/resourceGroups/parentGroup",
      "location": "chinaeast",
      "name": "parentGroup",
      "properties": {
        "provisioningState": "Succeeded"
      }
    }
  }
},
...

后续步骤Next steps