使用 ARM 模板进行租户部署

随着组织的成熟,你可能需要在 Azure AD 租户中定义和分配策略Azure 基于角色的访问控制 (Azure RBAC)。 通过租户级模板,可以声明的方式在全局级别应用策略和分配角色。

提示

我们建议使用 Bicep,因为它提供与 ARM 模板相同的功能,并且该语法更易于使用。 有关详细信息,请参阅租户部署

支持的资源

并非所有资源类型都可以部署到租户级别。 本部分列出了支持的资源类型。

对于 Azure 基于角色的访问控制 (Azure RBAC),请使用:

  • roleAssignments

对于部署到管理组、订阅或资源组的嵌套模板,请使用:

  • deployments

对于创建管理组,请使用:

  • managementGroups

若要创建订阅,请使用:

  • aliases

对于管理成本,请使用:

  • billingProfiles
  • billingRoleAssignments
  • 说明
  • invoiceSections
  • 策略

若要配置门户,请使用:

  • tenantConfigurations

内置策略定义是租户级别的资源,但你无法在租户中部署自定义策略定义。 有关为资源分配内置策略定义的示例,请参阅 tenantResourceId 示例

架构

用于租户部署的架构与资源组部署的架构不同。

对于模板,请使用:

{
  "$schema": "https://schema.management.azure.com/schemas/2019-08-01/tenantDeploymentTemplate.json#",
  ...
}

对于所有部署范围,参数文件的架构都相同。 对于参数文件,请使用:

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
  ...
}

所需访问权限

部署模板的主体必须具有在租户范围中创建资源的权限。 该主体必须有权执行部署操作 (Microsoft.Resources/deployments/*) 和创建模板中定义的资源。 例如,若要创建管理组,主体必须在租户范围内具有参与者权限。 若要创建角色分配,主体则必须具有所有者权限。

Microsoft Entra ID 的全局管理员不会自动拥有分配角色的权限。 若要在租户范围内实现模板部署,全局管理员必须执行以下步骤:

  1. 提升帐户访问权限,使其自身可分配角色。 有关详细信息,请参阅提升访问权限以管理所有 Azure 订阅和管理组

  2. 向需要部署模板的主体分配所有者或参与者角色。

    New-AzRoleAssignment -SignInName "[userId]" -Scope "/" -RoleDefinitionName "Owner"
    
    az role assignment create --assignee "[userId]" --scope "/" --role "Owner"
    

主体现已具有部署模板所需的权限。

部署命令

用于租户部署的命令与资源组部署使用的命令不同。

对于 Azure CLI,请使用 az deployment tenant create

az deployment tenant create \
  --name demoTenantDeployment \
  --location ChinaNorth \
  --template-uri "https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/tenant-deployments/new-mg/azuredeploy.json"

有关部署命令和部署 ARM 模板的选项的更多详细信息,请参阅:

部署位置和名称

对于租户级别的部署,必须提供部署位置。 部署位置独立于部署的资源的位置。 部署位置指定何处存储部署数据。 订阅管理组部署也需要位置。 对于资源组部署,资源组的位置用于存储部署数据。

可以为部署提供一个名称,也可以使用默认部署名称。 默认名称是模板文件的名称。 例如,部署一个名为 azuredeploy.json 的模板将创建默认部署名称 azuredeploy

每个部署名称的位置不可变。 当某个位置中已有某个部署时,无法在另一位置创建同名的部署。 例如,如果在 chinaeast 中创建名为“deployment1”的租户部署,则以后不能创建另一个名为“deployment1”但位置为“chinanorth”的部署。 如果出现错误代码 InvalidDeploymentLocation,请使用其他名称或使用与该名称的以前部署相同的位置。

部署范围

部署到租户时,可以将资源部署到:

  • 租户
  • 租户中的管理组
  • subscriptions
  • resource groups

唯一禁止的范围转换发生在从资源组到管理组或从订阅到管理组的时候。

可以将扩展资源的范围设置为与部署目标不同的范围。

部署模板的用户必须有权访问指定的作用域。

本部分演示如何指定不同范围。 可以在单个模板中组合这些不同范围。

将范围设定为租户

在模板的资源部分中定义的资源将应用于租户。

{
  "$schema": "https://schema.management.azure.com/schemas/2019-08-01/tenantDeploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "resources": [
    tenant-resources
  ],
  "outputs": {}
}

将范围设定为管理组

若要以租户内的管理组为目标,请添加嵌套部署并指定 scope 属性。

{
  "$schema": "https://schema.management.azure.com/schemas/2019-08-01/tenantDeploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "mgName": {
      "type": "string"
    }
  },
  "variables": {
    "mgId": "[concat('Microsoft.Management/managementGroups/', parameters('mgName'))]"
  },
  "resources": [
    {
      "type": "Microsoft.Resources/deployments",
      "apiVersion": "2022-09-01",
      "name": "nestedMG",
      "scope": "[variables('mgId')]",
      "location": "chinaeast",
      "properties": {
        "mode": "Incremental",
        "template": {
          management-group-resources
        }
      }
    }
  ],
  "outputs": {}
}

订阅的范围

还可以将租户中的订阅作为目标。 部署模板的用户必须有权访问指定的作用域。

若要以租户中的订阅为目标,请使用嵌套部署和 subscriptionId 属性。

{
  "$schema": "https://schema.management.azure.com/schemas/2019-08-01/tenantDeploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "resources": [
    {
      "type": "Microsoft.Resources/deployments",
      "apiVersion": "2021-04-01",
      "name": "nestedSub",
      "location": "chinanorth2",
      "subscriptionId": "00000000-0000-0000-0000-000000000000",
      "properties": {
        "mode": "Incremental",
        "template": {
          "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
          "contentVersion": "1.0.0.0",
          "resources": [
            {
              subscription-resources
            }
          ]
        }
      }
    }
  ]
}

将范围限定于资源组

还可以将租户中的资源组作为目标。 部署模板的用户必须有权访问指定的作用域。

若要以租户中的资源组为目标,请使用嵌套部署。 设置 subscriptionIdresourceGroup 属性。 不要为嵌套部署设置位置,因为它部署在资源组的位置。

{
  "$schema": "https://schema.management.azure.com/schemas/2019-08-01/tenantDeploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "resources": [
    {
      "type": "Microsoft.Resources/deployments",
      "apiVersion": "2021-04-01",
      "name": "nestedRGDeploy",
      "subscriptionId": "00000000-0000-0000-0000-000000000000",
      "resourceGroup": "demoResourceGroup",
      "properties": {
        "mode": "Incremental",
        "template": {
          "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
          "contentVersion": "1.0.0.0",
          "resources": [
            {
              resource-group-resources
            }
          ]
        }
      }
    }
  ]
}

创建管理组

以下模板用于创建管理组。

{
    "$schema": "https://schema.management.azure.com/schemas/2019-08-01/tenantDeploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
      "mgName": {
        "type": "string",
        "defaultValue": "[concat('mg-', uniqueString(newGuid()))]"
      }
    },
    "resources": [
      {
        "type": "Microsoft.Management/managementGroups",
        "apiVersion": "2020-02-01",
        "name": "[parameters('mgName')]",
        "properties": {
        }
      }
    ]
  }
  

如果帐户没有部署到租户的权限,仍然可以通过部署到另一个范围来创建管理组。 有关详细信息,请参阅管理组

分配角色

以下模板用于在租户范围内分配角色。

{
  "$schema": "https://schema.management.azure.com/schemas/2019-08-01/tenantDeploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "metadata": {
    "_generator": {
      "name": "bicep",
      "version": "0.5.6.12127",
      "templateHash": "17107802581699825924"
    }
  },
  "parameters": {
    "principalId": {
      "type": "string",
      "metadata": {
        "description": "principalId if the user that will be given contributor access to the tenant"
      }
    },
    "roleDefinitionId": {
      "type": "string",
      "defaultValue": "8e3af657-a8ff-443c-a75c-2fe8c4bcb635",
      "metadata": {
        "description": "roleDefinition for the assignment - default is owner"
      }
    }
  },
  "variables": {
    "roleAssignmentName": "[guid('/', parameters('principalId'), parameters('roleDefinitionId'))]"
  },
  "resources": [
    {
      "type": "Microsoft.Authorization/roleAssignments",
      "apiVersion": "2020-03-01-preview",
      "name": "[variables('roleAssignmentName')]",
      "properties": {
        "roleDefinitionId": "[tenantResourceId('Microsoft.Authorization/roleDefinitions', parameters('roleDefinitionId'))]",
        "principalId": "[parameters('principalId')]"
      }
    }
  ]
}

后续步骤