Azure Policy 定义 modify 效果
modify
效果用于在创建或更新期间在订阅或资源中添加、更新或删除属性或标记。 也可使用修正任务来修正现有的不合规资源。 效果设置为 Modify 的策略分配需要使用托管标识进行修正。 使用 modify
效果的常见示例是在“costCenter”等资源上更新标记。
资源属性的修改行为存在一些细微差别。 详细了解跳过修改的情形。
单个 modify
规则可以有任意数量的操作。 支持的操作为:
- 添加、替换或删除资源标记。 只能删除标记。 对于标记,除非目标资源是资源组,否则 Modify 策略的 mode 应设置为
indexed
。 - 添加或替换虚拟机和虚拟机规模集的托管标识类型 (
identity.type
) 的值。 只能修改虚拟机或虚拟机规模集的identity.type
。 - 添加或替换某些别名的值。
- 在 Azure PowerShell 4.6.0 或更高版本中使用
Get-AzPolicyAlias | Select-Object -ExpandProperty 'Aliases' | Where-Object { $_.DefaultMetadata.Attributes -eq 'Modifiable' }
,获取可与modify
一起使用的别名列表。
- 在 Azure PowerShell 4.6.0 或更高版本中使用
重要
如果你正在管理标记,我们建议使用 Modify 而不要使用 Append,因为 Modify 提供更多的操作类型,且能够修正现有的资源。 但如果无法创建托管标识或 Modify 尚不支持资源属性的别名,则建议使用 Append。
修改评估
在创建或更新资源期间,修改会在资源提供程序处理请求之前进行评估。 如果策略规则的 if
条件得到满足,则 modify
操作将应用于请求内容。 每个 modify
操作可以指定一个条件来决定何时应用它。
别名指定后,执行更多检查,确保 modify
操作更改请求内容后不会导致资源提供程序拒绝该请求:
- 在请求 API 版本中,别名映射到的属性标记为“可修改”。
modify
操作中的令牌类型与请求 API 版本中的属性的预期令牌类型匹配。
如果这些检查中的任何一个失败,策略评估将回退到指定的 conflictEffect
。
重要
建议包含别名的 Modify 定义采用“audit”冲突效果,避免使用 API 版本(其中映射的属性不是“可修改”)的请求失败。 如果同一别名在不同 API 版本中的行为不同,可以使用 Conditional modify 操作来确定对每个 API 版本使用的 modify
操作。
跳过的修改
在某些情况下,在评估期间跳过修改操作:
- 现有资源:当使用
modify
效果的策略定义作为评估周期的一部分运行时,它不会更改已存在的资源。 而是将满足if
条件的任何资源标记为不合规,以便能够通过修正任务对其进行修正。 - 不适用:如果
operations
数组中的操作的条件被评估为 false,将会跳过该特定操作。 - 属性不可修改:如果为操作指定的别名在请求的 API 版本中不可修改,则评估使用冲突效果。 如果冲突效果设置为“拒绝”,则阻止请求。 如果冲突效果设置为“审核”,则允许通过请求,但会跳过
modify
操作。 - 属性不存在:如果请求的资源有效负载中不存在某个属性,则可能会跳过修改。 在某些情况下,可修改的属性嵌套在其他属性中,并具有别名,如
Microsoft.Storage/storageAccounts/blobServices/deleteRetentionPolicy.enabled
。 如果“parent”属性(在本例中为deleteRetentionPolicy
)不存在于请求中,则跳过修改,因为该属性被认为是故意省略的。 如需了解实际的示例,请转到“属性不存在”示例部分。 - 非 VM 或 VMSS 标识操作:当修改操作尝试在虚拟机或虚拟机规模集以外的资源上添加或替换
identity.type
字段时,策略评估被完全跳过,因此不执行修改。 在这种情况下,该资源被视为不适用于策略。
“属性不存在”示例
资源属性的修改取决于 API 请求和更新的资源有效负载。 有效负载可能取决于使用的客户端(例如 Azure 门户),以及资源提供程序等其他因素。
假设你应用了一个策略来修改虚拟机 (VM) 上的标记。 每次更新 VM(例如在调整大小或磁盘更改期间)时,无论 VM 有效负载的内容如何,都会相应地更新标记。 这是因为标记独立于 VM 属性。
但是,如果应用一个策略来修改 VM 上的属性,则修改取决于资源有效负载。 如果尝试修改更新有效负载中不包含的属性,则不会进行修改。 例如,修补 VM 的 assessmentMode
属性(别名 Microsoft.Compute/virtualMachines/osProfile.windowsConfiguration.patchSettings.assessmentMode
)时,可能会发生这种情况。 该属性是“嵌套的”,因此如果其父属性未包含在请求中,则认为此省略是有意的,并且会跳过修改。 为了进行修改,资源有效负载应包含此上下文。
修改属性
modify
效果的 details
属性包含定义修正所需权限以及用于添加、更新或删除标记值 operations
的所有子属性。
roleDefinitionIds
(必需)- 此属性必须包含与可通过订阅访问的基于角色的访问控制角色 ID 匹配的字符串数组。 有关详细信息,请参阅修正 - 配置策略定义。
- 定义的角色必须包括所有授予参与者角色的操作。
conflictEffect
(可选)- 确定在多个策略定义修改同一属性的情况下,或在
modify
操作不适用于指定别名的情况下,哪个策略定义“胜出”。- 对于新的或更新的资源,具有 Deny 的策略定义优先。 具有 audit 的策略定义会跳过所有
operations
。 如果多个策略定义具有 deny 效果,则请求会因冲突而被拒绝。 如果所有策略定义都具有 audit,则不处理冲突策略定义的任何operations
。 - 对于现有资源,如果多个策略定义具有 deny 效果,则合规性状态为“冲突”。 如果一个或更少的策略定义具有 deny 效果,则每个分配都返回“不合规”的合规性状态。
- 对于新的或更新的资源,具有 Deny 的策略定义优先。 具有 audit 的策略定义会跳过所有
- 可用值:audit、deny、disabled 。
- 默认值为 deny。
- 确定在多个策略定义修改同一属性的情况下,或在
operations
(必需)- 要在匹配资源上完成的所有标记操作的数组。
- 属性:
operation
(必需)- 定义要在匹配资源上执行的操作。 选项包括:
addOrReplace
、Add
和Remove
。 Add
的行为类似于 append 效果。Remove
仅支持用于资源标记。
- 定义要在匹配资源上执行的操作。 选项包括:
field
(必需)- 要添加、替换或删除的标记。 对于其他字段,标记名称必须遵循相同的命名约定。
value
(可选)- 要设置标记的值。
- 如果
operation
是 addOrReplace 或 Add,则需要此属性。
condition
(可选)- 一个字符串,其中包含使用 Policy 函数的 Azure Policy 语言表达式,该表达式计算结果为 true 或 false 。
- 不支持以下 Policy 函数:
field()
、resourceGroup()
、subscription()
。
修改操作
operations
属性数组能够以不同的方式从单个策略定义中更改多个标记。 每个操作都由 operation
、field
和 value
属性组成。 operation
确定修正任务对标记执行的操作,field
确定更改的标记,value
定义该标记的新设置。 下面的示例进行了以下标记更改:
- 将
environment
标记设置为“Test”,即使它已存在并使用不同的值。 - 删除标记
TempResource
。 - 将
Dept
标记设置为在策略分配上配置的策略参数 DeptName。
"details": {
...
"operations": [
{
"operation": "addOrReplace",
"field": "tags['environment']",
"value": "Test"
},
{
"operation": "Remove",
"field": "tags['TempResource']",
},
{
"operation": "addOrReplace",
"field": "tags['Dept']",
"value": "[parameters('DeptName')]"
}
]
}
operation
具有以下选项:
操作 | 说明 |
---|---|
addOrReplace |
将定义的属性或标记和值添加到资源,即使该属性或标记已存在并使用不同的值。 |
add |
将定义的属性或标记和值添加到资源。 |
remove |
从资源中删除定义的标记。 仅支持用于标记。 |
修改示例
示例 1:添加 environment
标记并将现有 environment
标记替换为“Test”:
"then": {
"effect": "modify",
"details": {
"roleDefinitionIds": [
"/providers/Microsoft.Authorization/roleDefinitions/b24988ac-6180-42a0-ab88-20f7382dd24c"
],
"operations": [
{
"operation": "addOrReplace",
"field": "tags['environment']",
"value": "Test"
}
]
}
}
示例 2:删除 env
标记并添加 environment
标记,或将现有 environment
标记替换为参数化的值:
"then": {
"effect": "modify",
"details": {
"roleDefinitionIds": [
"/providers/Microsoft.Authorization/roleDefinitions/b24988ac-6180-42a0-ab88-20f7382dd24c"
],
"conflictEffect": "deny",
"operations": [
{
"operation": "Remove",
"field": "tags['env']"
},
{
"operation": "addOrReplace",
"field": "tags['environment']",
"value": "[parameters('tagValue')]"
}
]
}
}
示例 3:确保存储帐户不允许 blob 公共访问,仅在评估所用 API 版本大于或等于 2019-04-01
的请求时,才应用 modify
操作:
"then": {
"effect": "modify",
"details": {
"roleDefinitionIds": [
"/providers/microsoft.authorization/roleDefinitions/17d1049b-9a84-46fb-8f53-869881c3d3ab"
],
"conflictEffect": "audit",
"operations": [
{
"condition": "[greaterOrEquals(requestContext().apiVersion, '2019-04-01')]",
"operation": "addOrReplace",
"field": "Microsoft.Storage/storageAccounts/allowBlobPublicAccess",
"value": false
}
]
}
}
后续步骤
- 在 Azure Policy 示例中查看示例。
- 查看 Azure Policy 定义结构。
- 了解如何以编程方式创建策略。
- 了解如何获取符合性数据。
- 了解如何修正不符合的资源。
- 请查看 Azure 管理组。