修正 Azure Policy 中的不符合资源

可以通过修正将不符合 deployIfNotExists 或 modify 策略的资源置于符合状态。 修正是通过指示 Azure Policy 在现有资源和订阅上运行所分配策略的 deployIfNotExists 效果或 Modify 操作来完成的,无论该策略是分配给管理组、订阅、资源组还是单个资源 。 本文介绍了使用 Azure Policy 了解并完成修正所需执行的步骤。

修正安全的工作原理

当 Azure Policy 在 deployIfNotExists 策略定义中运行模板时,它使用托管标识来执行此操作。 Azure Policy 会为每个分配创建一个托管标识,但必须具有要向托管标识授予哪些角色的相关详细信息。 如果托管标识缺少角色,则在分配策略或计划期间会显示错误。 使用门户时,一旦启动分配,Azure Policy 将自动授予托管标识所列的角色。 使用 SDK 时,必须手动向托管标识授予角色。 托管标识的位置不会影响它对 Azure Policy 的操作。

缺少对托管标识的已定义权限的 deployIfNotExists 策略的屏幕截图。

重要

在以下情况下,必须向分配的托管标识手动授予访问权限,否则修正部署将失败:

  • 如果分配是通过 SDK 创建的
  • 如果 deployIfNotExists 或 modify 修改的资源在策略分配的范围之外
  • 如果模板访问策略分配范围之外的资源的属性

配置策略定义

第一步是定义 deployIfNotExists 和 modify 在策略定义中需要的角色,以成功部署所包含模板的内容。 在“details”属性下,添加“roleDefinitionIds”属性。 此属性是与环境中的角色相匹配的一组字符串。 有关完整示例,请参阅 deployIfNotExists 示例modify 示例

"details": {
    ...
    "roleDefinitionIds": [
        "/subscriptions/{subscriptionId}/providers/Microsoft.Authorization/roleDefinitions/{roleGUID}",
        "/providers/Microsoft.Authorization/roleDefinitions/{builtinroleGUID}"
    ]
}

roleDefinitionIds 属性使用完整的资源标识符,并且不会使用角色的短 roleName。 若要获取环境中“参与者”角色的 ID,请使用以下代码:

az role definition list --name 'Contributor'

手动配置托管标识

使用门户创建分配时,Azure Policy 会生成托管标识并向它授予 roleDefinitionIds 中定义的角色。 在以下情况下,必须手动执行步骤以创建托管标识,并向其分配权限:

  • 在使用 SDK 时(如 Azure PowerShell)
  • 当模板修改分配范围以外的资源
  • 当模板读取分配范围以外的资源

使用 PowerShell 创建托管标识

若要在策略分配期间创建托管标识,必须定义 Location 并使用 AssignIdentity。 下面的示例获取内置策略“部署 SQL DB 透明数据加密”的定义,设置目标资源组,然后创建分配。

# Login first with Connect-AzAccount
Connect-AzAccount -Environment AzureChinaCloud

# Get the built-in "Deploy SQL DB transparent data encryption" policy definition
$policyDef = Get-AzPolicyDefinition -Id '/providers/Microsoft.Authorization/policyDefinitions/86a912f6-9a06-4e26-b447-11b16ba8659f'

# Get the reference to the resource group
$resourceGroup = Get-AzResourceGroup -Name 'MyResourceGroup'

# Create the assignment using the -Location and -AssignIdentity properties
$assignment = New-AzPolicyAssignment -Name 'sqlDbTDE' -DisplayName 'Deploy SQL DB transparent data encryption' -Scope $resourceGroup.ResourceId -PolicyDefinition $policyDef -Location 'chinaeast2' -AssignIdentity

$assignment 变量现包含托管标识的主体 ID,以及创建策略分配时返回的标准值。 可以通过 $assignment.Identity.PrincipalId 访问它。

使用 PowerShell 授予定义的角色

新的托管标识必须通过 Azure Active Directory 完成复制,然后才会向其授予所需的角色。 复制完成后,下面的示例将循环访问 $policyDef 中有关 roleDefinitionIds 的策略定义,并使用 New-AzRoleAssignment 授予新托管标识角色。

# Use the $policyDef to get to the roleDefinitionIds array
$roleDefinitionIds = $policyDef.Properties.policyRule.then.details.roleDefinitionIds

if ($roleDefinitionIds.Count -gt 0)
{
    $roleDefinitionIds | ForEach-Object {
        $roleDefId = $_.Split("/") | Select-Object -Last 1
        New-AzRoleAssignment -Scope $resourceGroup.ResourceId -ObjectId $assignment.Identity.PrincipalId -RoleDefinitionId $roleDefId
    }
}

通过门户授予定义的角色

可以通过以下两种方法使用门户向分配的托管标识授予定义的角色:使用访问控制 (IAM),或通过编辑策略或计划分配并选择“保存” 。

若要将角色添加到分配的托管标识,请按照下列步骤操作:

  1. 在 Azure 门户中选择“所有服务”,然后搜索并选择“策略”,启动 Azure Policy 服务 。

  2. 选择“Azure Policy”页左侧的“分配”。

  3. 找到具有托管标识的分配,并选择相应名称。

  4. 在编辑页上查找“Assignment ID”属性。 分配 ID 将类似于:

    /subscriptions/{subscriptionId}/resourceGroups/PolicyTarget/providers/Microsoft.Authorization/policyAssignments/2802056bfc094dfb95d4d7a5
    

    托管标识的名称是分配资源 ID 的最后一部分,本例为 2802056bfc094dfb95d4d7a5。 复制分配资源 ID 的这一部分。

  5. 导航到需要手动添加角色定义的资源或资源父容器(资源组、订阅、管理组)。

  6. 选择资源页中的“访问控制 (IAM)”链接,然后选择访问控制页顶部的“+ 添加角色分配” 。

  7. 从策略定义中选择匹配 roleDefinitionIds 的合适角色。 将“分配访问权限至”设置保留为默认设置“Azure AD 用户、组或应用程序”。 在“选择”框中,粘贴或键入先前找到的分配资源 ID 部分。 完成搜索后,选择具有相同名称的对象来选择 ID,然后选择“保存”。

创建修正任务

通过门户创建修正任务

在评估期间,带 deployIfNotExists 或 modify 效果的策略分配确定是否存在不兼容资源或订阅。 当发现不兼容资源或订阅时,将在“修正”页上提供详细信息。 具有不兼容资源或订阅的策略列表也可以用来触发修正任务。 此选项用于基于 deployIfNotExists 模板或 modify 操作创建部署。

若要创建修正任务,请执行以下步骤:

  1. 在 Azure 门户中选择“所有服务”,然后搜索并选择“策略”,启动 Azure Policy 服务 。

    在“所有服务”中搜索“Policy”的屏幕截图。

  2. 选择“Azure Policy”页左侧的“修正”。

    “Policy”页中“修正”节点的屏幕截图。

  3. “要修正的策略”选项卡和数据表中包含所有具有不合规的资源的 deployIfNotExists 和 modify 策略分配。 选择其中一个具有不符合资源的策略。 “新修正任务”页随即打开。

    备注

    打开“修正任务”页的另一种方法是查找并选择“合规性”页面上的策略,然后选择“创建修正任务”按钮 。

  4. 在“新修正任务”页上,通过使用“范围”省略号从分配策略的位置选取子资源(包括下面的单个资源对象)来筛选要修正的资源。 此外,使用“位置”下拉列表来进一步筛选资源。 仅对表中列出的资源进行修正。

    “修正”节点和要修正的资源的网格的屏幕截图。

  5. 筛选资源后,通过选择“修正”来启动修正任务。 “策略符合性”页将打开到“修正任务”选项卡,以显示任务进度的状态。 由修正任务创建的部署将立即开始。

    “修正任务”选项卡和现有修正任务的进度的屏幕截图。

  6. 选择“策略合规性”页中的“修正任务”以获取有关进度的详细信息。 任务所使用的筛选与正在修正的资源列表一同显示。

  7. 从“修正任务”页中,选择并按住(或右键单击)资源以查看修正任务的部署或资源。 在行末尾,选择“相关事件”以查看诸如错误消息之类的详细信息。

    “修正任务”选项卡上的资源上下文菜单的屏幕截图。

通过“修正任务”部署的资源将添加到“策略符合性”页上的“部署的资源”选项卡。

通过 Azure CLI 创建修正任务

若要使用 Azure CLI 创建修正任务,请使用 az policy remediation 命令。 将 {subscriptionId} 替换为你的订阅 ID,将 {myAssignmentId} 替换为你的 deployIfNotExists 或 modify 策略分配 ID。

# Login first with az login
az cloud set -n AzureChinaCloud
az login

# Create a remediation for a specific assignment
az policy remediation create --name myRemediation --policy-assignment '/subscriptions/{subscriptionId}/providers/Microsoft.Authorization/policyAssignments/{myAssignmentId}'

有关其他修正命令和示例,请参阅 az policy remediation 命令。

通过 Azure PowerShell 创建修正任务

若要使用 Azure PowerShell 创建修正任务,请使用 Start-AzPolicyRemediation 命令。 将 {subscriptionId} 替换为你的订阅 ID,将 {myAssignmentId} 替换为你的 deployIfNotExists 或 modify 策略分配 ID。

# Login first with Connect-AzAccount
Connect-AzAccount -Environment AzureChinaCloud

# Create a remediation for a specific assignment
Start-AzPolicyRemediation -Name 'myRemedation' -PolicyAssignmentId '/subscriptions/{subscriptionId}/providers/Microsoft.Authorization/policyAssignments/{myAssignmentId}'

有关其他修正 cmdlet 和示例,请参阅 Az.PolicyInsights 模块。

在策略分配期间通过 Azure 门户创建修正任务

创建修正任务的一种简化方法是在策略分配期间通过 Azure 门户执行此操作。 如果要分配的策略定义是 deployIfNotExists 或 Modify 效果 ,“修正”选项卡上的向导会提供“创建修正任务”选项。 如果选择此选项,则会在分配策略的同时创建修正任务。

后续步骤