向工作负载标识授予对 Azure 的访问权限
工作负荷标识本身无法在 Azure 环境中执行任何操作,就像用户无法处理你的 Azure 资源一样,除非它们得到授权。 在本单元中,你将了解如何授权工作负荷标识部署和配置 Azure 资源,同时避免授予不必要的权限。
工作负载标识授权
到目前为止,你重点学习了什么是工作负载标识,以及如何使用它们向 Microsoft Entra ID 证明部署工作流的标识。 这一切都与身份验证有关。
在 Microsoft Entra ID 对工作负载标识进行身份验证后,下一个问题将是:此工作负载标识可以做什么? 这是“授权”的概念。 这是 Azure 基于角色的访问控制 (RBAC) 系统的职责,有时也称为标识和访问管理 (IAM)。 使用 Azure RBAC,可向工作负载标识授予访问特定资源组、订阅或管理组的权限。
注意
这里执行的一切操作都是使用 Azure RBAC 系统授予访问权限来创建和管理 Azure 资源,例如存储帐户、Azure 应用服务计划和虚拟网络。 Microsoft Entra ID 也有自己的角色系统,有时称为目录角色。 可使用这些角色向工作负载标识授予管理 Microsoft Entra ID 的权限。 本模块不会深入讨论此主题,但请注意在某些文档中,术语“角色”用于这两种情况。
为工作流选择正确的角色分配
角色分配有三个关键部分:将角色分配给谁(被分派人)、他们可执行什么操作(角色),以及角色分配应用于哪些资源(范围)。
被分派人
使用工作负载标识时,将为其分配角色。 若要分配角色,需要首先创建服务主体,这样就可以在 Azure 中授予应用程序角色。 创建服务主体后,可以继续使用应用程序注册的应用程序 ID。
若要创建服务主体,请使用 az ad sp create
命令并指定应用程序注册的应用 ID:
az ad sp create --id A123b4567c-1234-1a2b-2b1a-1234abc12345
若要创建服务主体,请使用 New-AzADServicePrincipal
cmdlet 并指定应用程序注册的应用 ID:
New-AzADServicePrincipal -AppId A123b4567c-1234-1a2b-2b1a-1234abc12345
角色
若要确定要分配的角色,可能还有一些操作。 在 Azure 中,有几个常见角色:
- 读者:允许被分派人读取资源信息,但禁止修改或删除这些资源。
- 参与者:允许被分派人创建资源,还允许他们读取和修改现有资源。 但是,参与者无法向其他主体授予对资源的访问权限。
- 所有者:允许完全控制资源,包括向其他主体授予访问权限。
注意
仅向工作负载标识授予执行其作业所需的最低权限。 大多数情况下,所有者角色对于部署工作流来说过于宽松。
还有许多特定角色提供对部分功能的访问权限。 你甚至可创建自己的自定义角色定义,来指定要分配的权限的确切列表。
备注
自定义角色定义是为 Azure 资源授予权限的一种强大方法,但可能难以使用。 精确确定需要将哪些权限添加到自定义角色定义并非总是很容易, 而且可能会无意中使角色定义过于严格或过于宽松。
如果不确定该怎么做,最好使用内置角色定义之一。 自定义角色定义不在本模块的讨论范围内。
范围
你需要确定分配角色的大致范围。 此决定会影响工作负载标识可修改的资源数。 常见范围包括:
- 单个资源:可以授予对特定资源的访问权限。 通常,部署工作流不使用此范围,因为工作流会创建尚不存在的资源,或者重新配置多个资源。
- 资源组:可以授予对资源组中所有资源的访问权限。 参与者和所有者还可在组中创建资源。 对于许多部署工作流来说,这是一个不错的选择。
- 订阅:可以授予对订阅中所有资源的访问权限。 如果单个订阅中有多个应用程序、工作负载或环境,则可向订阅的范围授予权限。 但对于部署工作流来说,这通常太宽松了。 应改为考虑将角色分配范围限定为资源组,除非部署工作流需要创建资源组。
请记住,角色分配会被继承。 如果在订阅中分配角色,则被分派人有权访问该订阅中的每个资源组和资源。
选择合适的角色分配
现在你已了解角色分配的组成部分,接下来可为你的方案确定适当的值。 下面是需要考虑的一些常规指导:
尽可能使用最严格的角色。 如果你的工作流只打算部署基本 Bicep 文件而不管理角色分配,请不要使用所有者角色。
尽可能使用最窄的范围。 大多数工作流只需要将资源部署到资源组,因此不应为它们提供订阅范围的角色分配。
对于许多工作流,角色分配的一个好的默认选项是资源组范围上的参与者角色。
请考虑你的工作流执行的所有操作,还有它将来可能会执行的各项操作。 例如,你可能考虑为网站的部署工作流创建自定义角色定义,并且仅授予应用服务和 Application Insights 的权限。 下个月,你可能需要将 Azure Cosmos DB 帐户添加到 Bicep 文件,但自定义角色阻止创建 Azure Cosmos DB 资源。
相反,通常最好使用内置角色或内置角色的组合,以避免重复更改你的角色定义。 请考虑使用 Azure Policy 对允许的服务、SKU 和位置强制实施治理要求。
测试工作流来验证角色分配是否有效。
混搭并匹配角色分配
你可创建多个角色分配,在不同的范围提供不同的权限。 例如,可以将工作负载标识分配给具有整个订阅范围的读者角色。 可以将特定资源组的参与者角色单独分配给同一工作负荷标识。 当工作负载标识尝试使用资源组时,将应用更宽松的分配。
使用多个环境
你可能会使用多个环境,例如应用程序的开发、测试和生产环境。 每个环境的资源应部署到不同的资源组或订阅。
应为每个环境创建单独的工作负载标识。 为每个工作负载标识授予其部署所需的最小权限集。 请特别注意,不要将生产部署的权限与用于部署到非生产环境的权限相混合。
为工作负载标识创建角色分配
若要为工作负载标识创建角色分配,请使用 az role assignment create
命令。 你需要指定被分派人、角色和范围:
az role assignment create \
--assignee A123b4567c-1234-1a2b-2b1a-1234abc12345 \
--role Contributor \
--scope "/subscriptions/B123a4567c-1234-2b1a-1b2b-11a2b01b2b3c0/resourceGroups/ToyWebsite" \
--description "The deployment workflow for the company's website needs to be able to create resources within the resource group."
让我们看看每个参数:
--assignee
指定工作负载标识。 可以通过多种方式指定此功能,但最好使用应用程序 ID,因为它可以避免产生歧义。--role
指定角色。 如果使用内置角色,则可按名称指定它。 如果使用自定义角色定义,请指定完整的角色定义 ID。--scope
指定范围。 这通常是单个资源、资源组或订阅的资源 ID。--description
是角色分配的用户可读说明。
若要为工作负载标识创建角色分配,请使用 New-AzRoleAssignment
cmdlet。 指定被分派人、角色和范围:
New-AzRoleAssignment `
-ApplicationId A123b4567c-1234-1a2b-2b1a-1234abc12345 `
-RoleDefinitionName Contributor `
-Scope '/subscriptions/B123a4567c-1234-2b1a-1b2b-11a2b01b2b3c0/resourceGroups/ToyWebsite' `
-Description "The deployment workflow for the company's website needs to be able to create resources within the resource group."
让我们看看每个参数:
-ApplicationId
指定工作负载标识的应用程序注册 ID。-RoleDefinitionName
指定内置角色的名称。 如果使用自定义角色定义,请改为使用-RoleDefinitionId
参数指定完整的角色定义 ID。-Scope
指定范围。 这通常是单个资源、资源组或订阅的资源 ID。-Description
是角色分配的用户可读说明。
提示
最好是通过指定说明为角色分配提供理由。 说明可帮助稍后查看角色分配的任何人理解其用途,并了解你如何决定被分派人、角色和范围。
备注
角色分配可能需要几分钟才能生效。
通过使用 Bicep 授予访问权限
角色分配是 Azure 资源。 这意味着可使用 Bicep 创建角色分配。 如果通过使用 Bicep 初始化资源组,然后通过使用工作负荷标识将资源部署到资源组,则可执行此操作。 下面是上述角色分配的示例 Bicep 定义:
resource roleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: guid(principalId, roleDefinitionId, resourceGroup().id)
properties: {
principalType: 'ServicePrincipal'
roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', roleDefinitionId)
principalId: principalId
description: 'The deployment workflow for the company\'s website needs to be able to create resources within the resource group.'
}
}
让我们看看每个参数:
name
是角色分配的全局唯一标识符 (GUID)。 最好使用 Bicep 中的guid()
函数来创建 GUID。 要确保为每个角色分配创建唯一名称,请使用主体 ID、角色定义 ID 和范围作为函数的种子参数。principalType
应设置为ServicePrincipal
。roleDefinitionId
是要分配的角色定义的完全限定的资源 ID。 大多数情况下,你可使用内置角色,因此可在 Azure 内置角色文档中找到角色定义 ID。例如,参与者角色具有角色定义 ID
b24988ac-6180-42a0-ab88-20f7382dd24c
。 在 Bicep 文件中指定它时,可使用完全限定的资源 ID,例如/subscriptions/B123a4567c-1234-2b1a-1b2b-11a2b01b2b3c0/providers/Microsoft.Authorization/roleDefinitions/b24988ac-6180-42a0-ab88-20f7382dd24c
。principalId
是服务主体的对象 ID。 请确保不使用应用程序 ID 或应用程序注册的对象 ID。description
是角色分配的用户可读说明。