Compartir a través de

对 Azure RBAC 限制进行故障排除

本文介绍在 Azure 基于角色的访问控制 (Azure RBAC) 中超出限制时的一些常见解决方案。

先决条件

注意

本文中使用的查询仅返回你有权读取的角色分配或自定义角色。 例如,如果你仅有权读取资源组范围内的角色分配,则不会返回订阅范围的角色分配。

症状 -无法创建更多角色分配

尝试分配角色时,收到以下错误消息:

No more role assignments can be created (code: RoleAssignmentLimitExceeded)

原因

Azure 支持每个订阅最多具有 4,000 个角色分配。 此限制包括订阅、资源组和资源范围内的角色分配,但不包括管理组范围内的角色分配。 符合条件的角色分配和将来计划的角色分配不计入此限制。 你应尝试减少订阅中的角色分配数。

注意

每个订阅的角色分配数限制 4000 是固定的,无法提高。

若要获取角色分配数,可以查看 Azure 门户中“访问控制(IAM)”页上的图表。 还可以使用以下 Azure PowerShell 命令:

$scope = "/subscriptions/<subscriptionId>"
$ras = Get-AzRoleAssignment -Scope $scope | Where-Object {$_.scope.StartsWith($scope)}
$ras.Count

解决方案 1 - 将基于主体的角色分配替换为基于组的角色分配

若要减少订阅中的角色分配数,请将主体(用户、服务主体和托管标识)添加到组,并改为将角色分配给组。 按照以下步骤,确定主体的多个角色分配可替换为组的单个角色分配的位置。

  1. 登录到 Azure 门户并打开 Azure Resource Graph 资源管理器。

  2. 选择“范围”并设置查询的范围

    通常将范围设置为“目录”可查询整个租户,但你可以将范围缩小到特定订阅

    显示范围选择的 Azure Resource Graph 资源管理器的屏幕截图。

  3. 选择“设置授权范围”,并将授权范围设置为“处于、高于和低于”,以查询指定范围内的所有资源

    显示“设置授权范围”窗格的 Azure Resource Graph 资源管理器的屏幕截图。

  4. 运行以下查询,获取具有相同角色、处于同一范围但针对不同主体的角色分配。

    此查询检查活动的角色分配,并且不考虑 Microsoft Entra Privileged Identity Management 中符合条件的角色分配。 若要列出符合条件的角色分配,可使用 Microsoft Entra 管理中心、PowerShell 或 REST API。 有关详细信息,请参阅 Get-AzRoleEligibilityScheduleInstance角色资格计划实例 - 范围列表

    如果使用角色分配条件,则应使用条件查询。 否则,使用“默认”查询。

    authorizationresources
    | where type =~ "microsoft.authorization/roleassignments"
    | where id startswith "/subscriptions"
    | extend RoleId = tolower(tostring(properties.roleDefinitionId))
    | join kind = leftouter (
      authorizationresources
      | where type =~ "microsoft.authorization/roledefinitions"
      | extend RoleDefinitionName = tostring(properties.roleName)
      | extend RoleId = tolower(id)
      | project RoleDefinitionName, RoleId
    ) on $left.RoleId == $right.RoleId
    | extend principalId = tostring(properties.principalId)
    | extend principal_to_ra = pack(principalId, id)
    | summarize count_ = count(), AllPrincipals = make_set(principal_to_ra) by RoleDefinitionId = RoleId, Scope = tolower(properties.scope), RoleDefinitionName
    | where count_ > 1
    | order by count_ desc
    

    下面显示了结果示例。 count_ 列是分配了相同角色且处于同一范围的主体数。 计数按降序排序。

    Azure Resource Graph 资源管理器的屏幕截图,其中显示了具有相同角色、处于同一范围但针对不同主体的角色分配。

  5. 确定要将多个角色分配替换为组的单个角色分配的行。

  6. 在该行中,选择“查看详细信息”以打开“详细信息”窗格

    “详细信息”窗格的屏幕截图,其中显示了具有相同角色、处于同一范围但针对不同主体的角色分配。

    说明
    RoleDefinitionId 当前分配的角色的 ID
    范围 角色分配的范围,它将是一个订阅、资源组或资源。
    RoleDefinitionName 当前分配的角色的名称
    count_ 分配了相同角色且处于同一范围的主体数。
    AllPrincipals 分配了相同角色且处于同一范围的主体 ID 列表。
  7. 使用 RoleDefinitionId、RoleDefinitionName 和 Scope 来获取角色和范围

  8. 使用 AllPrincipals 获取具有相同角色分配的主体 ID 的列表

  9. 创建 Microsoft Entra 组。 有关详细信息,请参阅管理 Microsoft Entra 组和组成员身份

  10. 将 AllPrincipals 中的主体添加到组

  11. 将角色分配给在同一范围内创建的组。 有关详细信息,请参阅使用 Azure 门户分配 Azure 角色

    现在,可找到并删除基于主体的角色分配。

  12. 从主体 ID 获取主体名称。

  13. 在角色分配所在的同一范围内打开“访问控制(IAM)”页

  14. 选择“角色分配”选项卡。

  15. 若要筛选角色分配,请选择“角色”筛选器,然后选择角色名称

  16. 查找基于主体的角色分配。

    你还应看到你的基于组的角色分配。

    “访问控制(IAM)”页的屏幕截图,其中显示了具有相同角色、处于同一范围但针对不同主体的角色分配。

  17. 选择并删除基于主体的角色分配。 有关详细信息,请参阅删除 Azure 角色分配

解决方案 2 - 删除冗余角色分配

若要减少订阅中的角色分配数,请删除冗余角色分配。 按照以下步骤,确定较低范围内的冗余角色分配可能被删除的位置,因为较高范围内的角色分配已授予访问权限。

  1. 登录到 Azure 门户并打开 Azure Resource Graph 资源管理器。

  2. 选择“范围”并设置查询的范围

    通常将范围设置为“目录”可查询整个租户,但你可以将范围缩小到特定订阅

    显示范围选择的 Azure Resource Graph 资源管理器的屏幕截图。

  3. 选择“设置授权范围”,并将授权范围设置为“处于、高于和低于”,以查询指定范围内的所有资源

    显示“设置授权范围”窗格的 Azure Resource Graph 资源管理器的屏幕截图。

  4. 运行以下查询,获取具有相同角色和相同主体但处于不同范围的角色分配。

    此查询检查活动的角色分配,并且不考虑 Microsoft Entra Privileged Identity Management 中符合条件的角色分配。 若要列出符合条件的角色分配,可使用 Microsoft Entra 管理中心、PowerShell 或 REST API。 有关详细信息,请参阅 Get-AzRoleEligibilityScheduleInstance角色资格计划实例 - 范围列表

    如果使用角色分配条件,则应使用条件查询。 否则,使用“默认”查询。

    authorizationresources
    | where type =~ "microsoft.authorization/roleassignments"
    | where id startswith "/subscriptions"
    | extend RoleDefinitionId = tolower(tostring(properties.roleDefinitionId))
    | extend PrincipalId = tolower(properties.principalId)
    | extend RoleDefinitionId_PrincipalId = strcat(RoleDefinitionId, "_", PrincipalId)
    | join kind = leftouter (
      authorizationresources
      | where type =~ "microsoft.authorization/roledefinitions"
      | extend RoleDefinitionName = tostring(properties.roleName)
      | extend rdId = tolower(id)
      | project RoleDefinitionName, rdId
    ) on $left.RoleDefinitionId == $right.rdId
    | summarize count_ = count(), Scopes = make_set(tolower(properties.scope)) by RoleDefinitionId_PrincipalId,RoleDefinitionName
    | project RoleDefinitionId = split(RoleDefinitionId_PrincipalId, "_", 0)[0], RoleDefinitionName, PrincipalId = split(RoleDefinitionId_PrincipalId, "_", 1)[0], count_, Scopes
    | where count_ > 1
    | order by count_ desc
    

    下面显示了结果示例。 count_ 列是具有相同角色和相同主体的不同范围的角色分配数。 计数按降序排序。

    Azure Resource Graph 资源管理器的屏幕截图,其中显示了处于不同范围的相同角色和相同主体的角色分配。

    说明
    RoleDefinitionId 当前分配的角色的 ID
    RoleDefinitionName 当前分配的角色的名称
    PrincipalId 分配了角色的主体的 ID。
    count_ 具有相同角色和相同主体的不同范围的角色分配数。
    作用域 具有相同角色和相同主体的角色分配的范围。
  5. 确定要删除冗余角色分配的行。

  6. 在一行中,选择“查看详细信息”以打开“详细信息”窗格

    “详细信息”窗格的屏幕截图,其中显示了处于不同范围的相同角色和相同主体的角色分配。

  7. 使用 RoleDefinitionId、RoleDefinitionName 和 PrincipalId 来获取角色和主体 ID

  8. 使用“Scopes”获取相同角色和相同主体的范围列表

  9. 确定角色分配所需的范围。 可删除其他角色分配。

    确定可删除哪些角色分配时,应遵循最小特权的最佳做法。 较高范围的角色分配向主体授予的访问权限可能会超过所需的访问权限。 在这种情况下,应删除范围更高的角色分配。 例如,当较低资源组范围的“虚拟机参与者”角色分配授予所需的访问权限时,用户可能不需要订阅范围内的“虚拟机参与者”角色分配。

  10. 从主体 ID 获取主体名称。

  11. 在要删除的角色分配范围内打开“访问控制(IAM)”页

  12. 选择“角色分配”选项卡。

  13. 若要筛选角色分配,请选择“角色”筛选器,然后选择角色名称

  14. 查找主体。

  15. 选择并删除角色分配。 有关详细信息,请参阅删除 Azure 角色分配

解决方案 3 - 将多个内置角色分配替换为自定义角色分配

若要减少订阅中的角色分配数,请将多个内置角色分配替换为单个自定义角色分配。 按照以下步骤,确定多个内置角色分配可能被替换的位置。

  1. 登录到 Azure 门户并打开 Azure Resource Graph 资源管理器。

  2. 选择“范围”并设置查询的范围

    通常将范围设置为“目录”可查询整个租户,但你可以将范围缩小到特定订阅

    显示范围选择的 Azure Resource Graph 资源管理器的屏幕截图。

  3. 运行以下查询,获取具有相同主体和相同范围,但具有不同的内置角色的角色分配。

    此查询检查活动的角色分配,并且不考虑 Microsoft Entra Privileged Identity Management 中符合条件的角色分配。 若要列出符合条件的角色分配,可使用 Microsoft Entra 管理中心、PowerShell 或 REST API。 有关详细信息,请参阅 Get-AzRoleEligibilityScheduleInstance角色资格计划实例 - 范围列表

    如果使用角色分配条件,则应使用条件查询。 否则,使用“默认”查询。

    AuthorizationResources
    | where type =~ "microsoft.authorization/roleassignments"
    | where id startswith "/subscriptions"
    | extend PrincipalId = tostring(properties.principalId) 
    | extend Scope = tolower(properties.scope)
    | extend RoleDefinitionId = tolower(tostring(properties.roleDefinitionId))
    | join kind = leftouter (
      AuthorizationResources
      | where type =~ "microsoft.authorization/roledefinitions"
      | extend RoleName = tostring(properties.roleName)
      | extend RoleId = tolower(id)
      | extend RoleType = tostring(properties.type) 
      | where RoleType == "BuiltInRole"
      | extend RoleId_RoleName = pack(RoleId, RoleName)
    ) on $left.RoleDefinitionId == $right.RoleId
    | summarize count_ = count(), AllRD = make_set(RoleId_RoleName) by PrincipalId, Scope
    | where count_ > 1
    | order by count_ desc
    

    下面显示了结果示例。 count_ 列是具有相同主体和相同范围的不同内置角色分配数。 计数按降序排序。

    Azure Resource Graph 资源管理器的屏幕截图,其中显示了具有相同主体和相同范围的角色分配。

    说明
    PrincipalId 分配了内置角色的主体的 ID。
    范围 内置角色分配的范围。
    count_ 具有相同主体和相同范围的内置角色分配数。
    AllRD 内置角色的 ID 和名称。
  4. 在一行中,选择“查看详细信息”以打开“详细信息”窗格

    “详细信息”窗格的屏幕截图,其中显示了具有相同主体和相同范围的角色分配。

  5. 使用“AllRD”查看可能组合为自定义角色的内置角色

  6. 列出内置角色的操作和数据操作。 有关详细信息,请参阅列出 Azure 角色定义Azure 内置角色

  7. 创建一个包含所有操作和数据操作的自定义角色作为内置角色。 若要更轻松地创建自定义角色,可从克隆其中一个内置角色开始。 有关详细信息,请参阅使用 Azure 门户创建或更新 Azure 自定义角色

  8. 从主体 ID 获取主体名称。

  9. 在角色分配所在的同一范围内打开“访问控制(IAM)”页

  10. 将新的自定义角色分配给主体。 有关详细信息,请参阅使用 Azure 门户分配 Azure 角色

    现在,可删除内置角色分配。

  11. 在同一范围内的“访问控制(IAM)”页上,选择“角色分配”选项卡

  12. 查找主体和内置角色分配。

  13. 从主体中删除内置角色分配。 有关详细信息,请参阅删除 Azure 角色分配

解决方案 4 - 使角色分配符合条件

若要减少订阅中的角色分配数,并且你拥有 Microsoft Entra ID P2,请在 Microsoft Entra Privileged Identity Management 中使角色分配符合条件,而不是使之永久分配。

解决方案 5 - 添加其他订阅

添加额外的订阅。

症状 - 无法在管理组范围内创建更多角色分配

无法在管理组范围内分配角色。

原因

Azure 对于每个管理组最多支持 500 个角色分配。 此限制不同于每个订阅的角色分配限制。

注意

每个管理组的角色分配数限制 500 是固定的,无法提高。

解决方案

尝试减少管理组中的角色分配数。 有关可能的选项,请参阅症状 - 无法创建更多角色分配。 若要使查询在管理组级别检索资源,需要对查询进行以下更改:

Replace

| where id startswith "/subscriptions"

With

| where id startswith "/providers/Microsoft.Management/managementGroups"

症状 - 无法创建更多角色定义

尝试创建新的自定义角色时,收到以下消息:

Role definition limit exceeded. No more role definitions can be created (code: RoleDefinitionLimitExceeded)

原因

Azure 在一个目录中最多支持 5000 个自定义角色。 (对于由世纪互联运营的 Microsoft Azure,限制为 2000 个自定义角色。)

解决方案

按照以下步骤,查找和删除未使用的 Azure 自定义角色。

  1. 登录到 Azure 门户并打开 Azure Resource Graph 资源管理器。

  2. 选择“范围”,并将查询的范围设置为“目录”

    显示范围选择的 Azure Resource Graph 资源管理器的屏幕截图。

  3. 运行以下查询,获取没有任何角色分配的所有自定义角色:

    此查询检查活动的角色分配,并且不考虑 Microsoft Entra Privileged Identity Management 中符合条件的自定义角色分配。 若要列出符合条件的自定义角色分配,可使用 Microsoft Entra 管理中心、PowerShell 或 REST API。 有关详细信息,请参阅 Get-AzRoleEligibilityScheduleInstance角色资格计划实例 - 范围列表

    AuthorizationResources
    | where type =~ "microsoft.authorization/roledefinitions"
    | where tolower(properties.type) == "customrole"
    | extend rdId = tolower(id)
    | extend Scope = tolower(properties.assignableScopes)
    | join kind = leftouter (
    AuthorizationResources
      | where type =~ "microsoft.authorization/roleassignments"
      | extend RoleId = tolower(tostring(properties.roleDefinitionId))
      | summarize RoleAssignmentCount = count() by RoleId
    ) on $left.rdId == $right.RoleId
    | where isempty(RoleAssignmentCount)
    | project RoleDefinitionId = rdId, RoleDefinitionName = tostring(properties.roleName), Scope
    

    下面显示了结果示例:

    Azure Resource Graph 资源管理器的屏幕截图,其中显示了没有角色分配的自定义角色。

    说明
    RoleDefinitionId 未使用的自定义角色的 ID。
    RoleDefinitionName 未使用的自定义角色的名称。
    范围 未使用的自定义角色的可分配范围
  4. 打开范围(通常为订阅),然后打开“访问控制(IAM)”页

  5. 选择“角色”选项卡以查看包含所有内置角色和自定义角色的列表。

  6. 在“类型”筛选器中,选择“CustomRole”,以便仅查看你的自定义角色。

  7. 选择要删除的自定义角色对应的省略号 (...),然后选择“删除”

    可选择删除的自定义角色列表的屏幕截图。

后续步骤