将资源部署到多个范围

已完成

有时,你需要在一个部署中跨多个级别的层次结构部署资源。 下面是一些你可能想要执行此操作的情况:

  • 需要跨两个不同的资源组部署资源。 例如,你可能想要在共享资源组中创建网络安全组,同时为应用程序资源组中的虚拟机部署网络接口。
  • 你正在使用模板创建资源组,该资源组是订阅范围资源,然后需要使用资源组范围部署将存储帐户和其他 Azure 资源部署到该资源组。
  • 你正在部署管理组层次结构,并且还希望部署一些订阅,这些订阅是租户范围资源。

借助 Bicep,可以通过使用 scope 关键字创建跨范围运行的部署。

注意

本单元中显示的命令用于说明概念。 请暂时不要运行这些命令。 稍后你将练习在此处学到的知识。

指定模块范围

可以使用 Bicep 模块在与文件中指定的 targetScope 范围不同的范围内部署一组资源。 下面是一个示例 Bicep 文件,它在 targetScopesubscription 的范围内部署,但使用模块将一些资源部署到资源组:

targetScope = 'subscription'

module networkModule 'modules/network.bicep' = {
  scope: resourceGroup('ToyNetworking')
  name: 'networkModule'
}

请注意,scope 属性使用 Bicep 函数来帮助确定目标范围。 前面的示例使用 resourceGroup() 函数并指定目标资源组名称。 还可以使用 subscription()managementGroup()tenant() 函数。 通过对 Bicep 文件使用 targetScope 关键字,并在模块上使用 scope 关键字,可以为部署创建大量不同的范围组合。

注意

一个例外是,targetScoperesourceGroupsubscription 的 Bicep 文件不能包含 scopemanagementGroup 的模块。

提示

如果使用订阅范围的 Bicep 文件来创建资源组,则可以使用资源组的符号名称作为模块的 scope。 在下一练习中,你将了解如何执行此操作。

跨多个资源组部署

范围的一个常见用途是跨多个资源组部署资源。 虽然不能在大多数 Azure 资源上设置 scope 属性,但可以使用模块来告诉 Bicep 应将一组资源部署到其他资源组。

例如,你可能想要创建一组 Bicep 文件,用于将虚拟网络及其关联资源部署到名为 ToyNetworking 的共享资源组,然后将网络接口部署到其他资源组。 Bicep 文件如下所示:

module networkModule 'modules/network.bicep' = {
  scope: resourceGroup('ToyNetworking')
  name: 'networkModule'
}

resource networkInterface 'Microsoft.Network/networkInterfaces@2024-01-01' = {
  name: 'production-nic'
  location: resourceGroup().location
  properties: {
    ipConfigurations: [
      {
        name: 'toy-subnet-ip-configuration'
        properties: {
          subnet: {
            id: networkModule.outputs.subnetResourceId
          }
        }
      }
    ]
  }
}

请注意,要部署到 ToyNetworking 资源组的资源是在模块中定义的,并且 subnetResourceId 输出在网络接口的资源定义中使用。

部署此文件后,可以将名为 ProjectTeddybear 的另一个资源组作为目标,如下所示:

az deployment group create --resource-group ProjectTeddybear ...
New-AzResourceGroupDeployment -ResourceGroupName ProjectTeddybear ...

尽管部署面向 ProjectTeddybear 资源组,但虚拟网络资源将部署到 ToyNetworking 资源组。 网络接口将部署到 ProjectTeddybear 资源组

你甚至可以通过将订阅 ID 包含在 resourceGroup 范围中来在另一个订阅中部署资源组:

module networkModule 'modules/network.bicep' = {
  scope: resourceGroup('f0750bbe-ea75-4ae5-b24d-a92ca601da2c', 'ToyNetworking')
  name: 'networkModule'
}

同样,可以使用 subscription() 范围函数在订阅范围的多个订阅之间部署资源,并可以使用 managementGroup() 范围函数跨多个管理组部署资源。 但是,不能跨多个租户部署它们。

指定单个资源的范围

可将 scope 关键字用于其他一些特定的资源类型,而不只是模块。 扩展资源使用 scope 关键字指定它们应用到的资源。 此外,租户范围的资源可以使用 scope 关键字,以便可以从任何模板部署它们。

例如,你可以使用 Bicep 文件来创建管理组层次结构,如以下示例所示:

targetScope = 'managementGroup'

resource parentManagementGroup 'Microsoft.Management/managementGroups@2023-04-01' = {
  scope: tenant()
  name: 'NonProduction'
  properties: {
    displayName: 'Non-production'
  }
}

resource childManagementGroup 'Microsoft.Management/managementGroups@2023-04-01' = {
  scope: tenant()
  name: 'SecretRND'
  properties: {
    displayName: 'Secret R&D Projects'
    details: {
      parent: {
        id: parentManagementGroup.id
      }
    }
  }
}

请注意,此示例使用模板文件中的 targetScope = 'managementGroup',但它会在 tenant() 范围内部署管理组。

注意

前面的示例演示了如何使用 Bicep 来创建管理组层次结构。 NonProduction 管理组将是根管理组的子组,SecretRND 管理组将是 NonProduction 管理组的子组。

创建管理组和订阅层次结构

现在,你已了解如何在各种范围部署多个不同的资源,以及如何使用 Bicep 模块和 scope 关键字来部署资源组合。 让我们应用所有这些新知识,在前面的示例中扩展管理组层次结构。 现在,层次结构还将包含一个订阅别名,这是创建新 Azure 订阅的租户范围资源:

resource subscription 'Microsoft.Subscription/aliases@2024-08-01-preview'
  scope: tenant()
  name: subscriptionAliasName
  properties: {
    // ...
  }
}

注意

创建订阅别名时,还可以指定其他一些属性,如计费范围。 为清楚起见,我们已将其省略。

然后,可以将订阅与管理组相关联,这需要部署名为 Microsoft.Management/managementGroups/subscriptions 的资源类型。 由于此资源的工作方式,你可以在模块中声明它。 例如,下面是名为“modules/mg-subscription-association.bicep”的文件:

targetScope = 'tenant'

@description('The name of the management group that should contain the subscription.')
param managementGroupName string

@description('The subscription ID to place into the management group.')
param subscriptionId string

resource managementGroup 'Microsoft.Management/managementGroups@2023-04-01' existing = {
  name: managementGroupName
}

resource subscriptionAssociation 'Microsoft.Management/managementGroups/subscriptions@2023-04-01' = {
  parent: managementGroup
  name: subscriptionId
}

请注意,管理组是通过 existing 关键字引用的。

然后,主 Bicep 文件可以通过包含模块来创建关联。 下面是整个 Bicep 文件:

targetScope = 'managementGroup'

@description('The name of the subscription alias to deploy.')
param subscriptionAliasName string

resource parentManagementGroup 'Microsoft.Management/managementGroups@2023-04-01' = {
  scope: tenant()
  name: 'NonProduction'
  properties: {
    displayName: 'Non-production'
  }
}

resource childManagementGroup 'Microsoft.Management/managementGroups@2023-04-01' = {
  scope: tenant()
  name: 'SecretRND'
  properties: {
    displayName: 'Secret R&D Projects'
    details: {
      parent: {
        id: parentManagementGroup.id
      }
    }
  }
}

resource subscription 'Microsoft.Subscription/aliases@2024-08-01-preview'
  scope: tenant()
  name: subscriptionAliasName
  properties: {
    // ...
  }
}

module subscriptionAssociation 'modules/mg-subscription-association.bicep' = {
  name: 'subscriptionAssociation'
  scope: tenant()
  params: {
    managementGroupName: childManagementGroup.name
    subscriptionId: subscription.properties.subscriptionId
  }
}

如你所见,你可以将所有范围和 Bicep 语言功能一起使用,以便为整个 Azure 基础结构创建全面部署。