不符合具有 deployIfNotExists
或 modify
效果的策略的资源可以通过修正进入合规状态。 修正是通过修正任务来完成的,这些任务在现有资源和订阅上部署 deployIfNotExists
模板或已分配策略的 modify
操作,无论该分配是在管理组、订阅、资源组还是单个资源上。 本文介绍了使用 Azure Policy 了解并完成修正所需执行的步骤。
如果 Azure Policy 在评估 deployIfNotExists
策略时启动模板部署,或在评估 modify
策略时修改资源,则使用与策略分配关联的托管标识来执行这些操作。 策略分配使用托管标识进行 Azure 资源授权。 你可以使用由策略服务创建的系统分配的托管标识,也可以使用由用户提供的用户分配的标识。 需要为托管标识分配修正资源所需的最小 Azure 基于角色的访问控制 (Azure RBAC) 角色。 如果托管标识缺少角色,则在分配策略或计划期间将在门户中显示错误。 使用门户时,一旦启动分配,Azure Policy 将自动授予托管标识所列的角色。 使用 Azure 软件开发工具包 (SDK) 时,必须手动向托管标识授予角色。 托管标识的位置不会影响它对 Azure Policy 的操作。
注意
更改策略定义不会自动更新分配或关联的托管标识。
可以通过以下步骤配置修正安全性:
作为先决条件,策略定义必须定义 deployIfNotExists
和 modify
成功部署所包含模板的内容所需的角色。 内置策略定义不需要执行任何操作,因为这些角色已预先填充。 对于自定义策略定义,在 details
属性下,添加一个 roleDefinitionIds
属性。 此属性是与环境中的角色相匹配的一组字符串。 有关完整示例,请参阅 deployIfNotExists 或 modify。
"details": {
...
"roleDefinitionIds": [
"/subscriptions/{subscriptionId}/providers/Microsoft.Authorization/roleDefinitions/{roleGUID}",
"/providers/Microsoft.Authorization/roleDefinitions/{builtinroleGUID}"
]
}
roleDefinitionIds
属性使用完整的资源标识符,并且不会使用角色的短 roleName
。 若要获取环境中“参与者”角色的 ID,请使用以下 Azure CLI 代码:
az role definition list --name "Contributor"
重要
在策略定义中定义 roleDefinitionIds
或手动将权限分配给托管标识时,应将权限限制在尽可能小的范围内。 若要了解更多最佳做法,请参阅托管标识最佳做法建议。
每个 Azure Policy 分配只能与一个托管标识相关联。 但是,可以为托管标识分配多个角色。 配置分为两个步骤:首先创建系统分配的托管标识或用户分配的托管标识,然后向其授予必要的角色。
注意
通过门户创建托管标识时,将自动向托管标识授予角色。 如果稍后在策略定义中编辑 roleDefinitionIds
,则必须手动授予新权限,即使在门户中也是如此。
创建托管标识
使用门户创建分配时,Azure Policy 会生成系统分配的托管标识并向它授予策略定义的 roleDefinitionIds
中定义的角色。 也可以指定接收相同角色分配的用户分配的托管标识。
在门户中设置系统分配的托管标识:
在“创建/编辑分配”视图的“修正”选项卡上的“托管标识类型”下,确保选中“系统分配的托管标识”。
指定托管标识所在的位置。
不要为系统分配的托管标识分配范围,因为范围将从分配范围继承。
在门户中设置用户分配的托管标识:
在“创建/编辑分配”视图的“修正”选项卡上的“托管标识类型”下,确保选中“用户分配的托管标识”。
指定托管标识的托管范围。 托管标识的范围不一定要等于分配的范围,但必须在同一租户中。
在“现有用户分配的标识”下,选择“托管标识”。
若要在策略分配期间创建标识,必须定义“位置”并使用“标识”。
下面的示例获取内置策略“部署 SQL DB 透明数据加密”的定义,设置目标资源组,然后使用系统分配的托管标识创建分配。
# Login first with 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 -Identity properties
$assignment = New-AzPolicyAssignment -Name 'sqlDbTDE' -DisplayName 'Deploy SQL DB transparent data encryption' -Scope $resourceGroup.ResourceId -PolicyDefinition $policyDef -Location 'chinaeast2' -IdentityType "SystemAssigned"
下面的示例获取内置策略“部署 SQL DB 透明数据加密”的定义,设置目标资源组,然后使用用户分配的托管标识创建分配。
# Login first with 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'
# Get the existing user assigned managed identity ID
$userassignedidentity = Get-AzUserAssignedIdentity -ResourceGroupName $rgname -Name $userassignedidentityname
$userassignedidentityid = $userassignedidentity.Id
# Create the assignment using the -Location and -Identity properties
$assignment = New-AzPolicyAssignment -Name 'sqlDbTDE' -DisplayName 'Deploy SQL DB transparent data encryption' -Scope $resourceGroup.ResourceId -PolicyDefinition $policyDef -Location 'chinaeast2' -IdentityType "UserAssigned" -IdentityId $userassignedidentityid
$assignment
变量现包含托管标识的主体 ID,以及创建策略分配时返回的标准值。 对于系统分配的托管标识和用户分配的托管标识,可以分别通过 $assignment.Identity.PrincipalId
和 $assignment.Identity.UserAssignedIdentities[$userassignedidentityid].PrincipalId
访问。
通过定义的角色向托管标识授予权限
重要
如果托管标识不具备执行所需修正任务所需的权限,则只能通过门户自动为其授予权限。 如果通过门户创建托管标识,则可以跳过此步骤。
对于所有其他方法,必须通过添加角色向分配的托管标识手动授予访问权限,否则修正部署将失败。
需要手动权限的示例方案:
- 如果分配是通过 Azure 软件开发工具包 (SDK) 创建的
- 如果
deployIfNotExists
或 modify
修改的资源在策略分配的范围之外
- 如果模板访问策略分配范围之外的资源的属性
可以通过以下两种方法使用门户向分配的托管标识授予定义的角色:使用访问控制 (IAM),或通过编辑策略或计划分配并选择“保存”。
若要将角色添加到分配的托管标识,请按照下列步骤操作:
在 Azure 门户中选择“所有服务”,然后搜索并选择“策略”,启动 Azure Policy 服务 。
选择“Azure Policy”页左侧的“分配”。
找到具有托管标识的分配,并选择相应名称。
在编辑页上查找“Assignment ID”属性。 分配 ID 应类似于以下示例:
/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Authorization/policyAssignments/2802056bfc094dfb95d4d7a5
托管标识的名称是分配资源 ID 的最后一部分,本例为 2802056bfc094dfb95d4d7a5
。 复制分配资源 ID 的这一部分。
导航到需要手动添加角色定义的资源或资源父容器(资源组、订阅、管理组)。
选择资源页中的“访问控制 (IAM)”链接,然后选择访问控制页顶部的“+ 添加角色分配” 。
从策略定义中选择与 roleDefinitionIds
匹配的合适角色。 将“分配访问权限至”设置保留为默认设置“用户、组或应用程序”。 在“选择”框中,粘贴或键入先前找到的分配资源 ID 部分。 完成搜索后,选择具有相同名称的对象来选择 ID,然后选择“保存”。
新的托管标识必须通过 Microsoft Entra ID 完成复制,然后才会向其授予所需的角色。 复制完成后,下面的示例将循环访问 $policyDef
中有关 roleDefinitionIds
的策略定义,并使用 New-AzRoleAssignment 向新的托管标识授予角色。
具体而言,第一个示例演示如何在策略范围内授予角色。 第二个示例演示如何在计划(策略集)范围内授予角色。
###################################################
# Grant roles to managed identity at policy scope #
###################################################
# 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
}
}
#######################################################
# Grant roles to managed identity at initiative scope #
#######################################################
#If the policy had no managed identity in its logic, then no impact. If there is a managed identity
used for enforcement, replicate it on the new assignment.
$getNewInitiativeAssignment = Get-AzPolicyAssignment -Name $newInitiativeDefinition.Name
#Create an array to store role definition's IDs used by policies inside the initiative.
$InitiativeRoleDefinitionIds = @();
#Loop through the policy definitions inside the initiative and gather their role definition IDs
foreach ($policyDefinitionIdInsideInitiative in $InitiativeDefinition.Properties.PolicyDefinitions.policyDefinitionId) {
$policyDef = Get-AzPolicyDefinition -Id $policyDefinitionIdInsideInitiative
$roleDefinitionIds = $policyDef.Properties.PolicyRule.then.details.roleDefinitionIds
$InitiativeRoleDefinitionIds += $roleDefinitionIds
}
#Create the role assignments used by the initiative assignment at the subscription scope.
if ($InitiativeRoleDefinitionIds.Count -gt 0) {
$InitiativeRoleDefinitionIds | Sort-Object -Unique | ForEach-Object {
$roleDefId = $_.Split("/") | Select-Object -Last 1
New-AzRoleAssignment -Scope "/subscriptions/$($subscription)" -ObjectId $getNewInitiativeAssignment.Identity.PrincipalId
-RoleDefinitionId $roleDefId
}
}
在 Azure 门户中选择“所有服务”,然后搜索并选择“策略”,启动 Azure Policy 服务。
可通过三种方法使用门户创建修正任务。
选项 1:从“修正”页创建修正任务
选择“Azure Policy”页左侧的“修正”。
所有 deployIfNotExists
和 modify
策略分配都显示在“要修正的策略”选项卡上。选择一个具有不合规资源的策略分配,以打开“新建修正任务”页面。
按照以下步骤指定修正任务详细信息。
选择“Azure Policy”页左侧的“合规性”。
选择包含 deployIfNotExists
或 modify
效果的不合规策略或计划分配。
选择页面顶部的“创建修正任务”按钮以打开“新建修正任务”页。
按照以下步骤指定修正任务详细信息。
如果要分配的策略或计划定义具有 deployIfNotExists
或 modify
效果,则向导的“修正”选项卡会提供“创建修正任务”选项,该选项在进行策略分配的同时创建修正任务。
注意
这是创建修正任务的最简化的方法,支持在订阅上分配的策略。 对于在管理组上分配的策略,评估确定资源合规性后,应使用选项 1 或选项 2 创建修正任务。
在门户中的分配向导中,导航到“修正”选项卡。选中“创建修正任务”复选框。
如果从计划分配启动修正任务,请从下拉列表中选择要修正的策略。
配置托管标识并填写向导的其余部分。 创建分配时,将创建修正任务。
仅当使用选项 1 或选项 2 启动修正任务创建时,此步骤才适用。
如果从计划分配启动修正任务,请从下拉列表中选择要修正的策略。 一次可以通过单个修正任务修正一个 deployIfNotExists
或 modify
策略。
(可选)在该页上修改修正设置。 有关每个设置控制的内容的信息,请参阅修正任务结构。
在相同页上,通过使用“范围”省略号从分配策略的位置选取子资源(包括下面的单个资源对象)来筛选要修正的资源。 此外,使用“位置”下拉列表来进一步筛选资源。
筛选资源后,通过选择“修正”来启动修正任务。 “策略符合性”页将打开到“修正任务”选项卡,以显示任务进度的状态。 由修正任务创建的部署将立即开始。
导航到“修正”页上的“修正任务”选项卡。 选择一个修正任务来查看有关所用筛选、当前状态和正在修正的资源列表的详细信息。
从“修正任务”详细信息页中,右键单击资源以查看修正任务的部署或资源。 在该行的末尾,选择“相关事件”以查看错误消息等详细信息。
通过“修正任务”部署的资源被添加到“策略分配详细信息”页面上的“已部署资源”选项卡中。
若要使用 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 'myRemediation' -PolicyAssignmentId '/subscriptions/{subscriptionId}/providers/Microsoft.Authorization/policyAssignments/{myAssignmentId}'
还可以选择通过以下可选参数调整修正设置:
-FailureThreshold
- 用于指定如果失败百分比超过给定的阈值,修正任务是否应该失败。 以 0 到 100 之间的数字提供。 默认情况下,失败阈值为 100%。
-ResourceCount
- 确定给定修正任务中要修正的不合规资源数量。 默认值为 500(之前的限制)。 最大数目为 50,000 个资源。
-ParallelDeploymentCount
- 确定要同时修正的资源数量。 取值范围为 1 到 30 个资源。 默认值为 10。
有关更多修正 cmdlet 和示例,请参阅 Az.PolicyInsights 模块。
执行此操作。
若要使用 Azure CLI 创建修正任务,请使用 az policy remediation
命令。 将 {subscriptionId}
替换为你的订阅 ID,并将 {myAssignmentId}
替换为你的 deployIfNotExists
或 modify
策略分配 ID。
# Login first with 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 命令。
后续步骤