如何配置Azure Policy以仅检测资源组级别的CanNotDelete锁?
Great question! The issue you're hitting is that your current policy only checks the lock level (CanNotDelete) but doesn't verify where the lock is applied—it's matching locks on individual resources (like your KeyVault) just as easily as locks on the resource group itself.
To fix this, you need to update the existenceCondition to confirm the lock is directly scoped to the resource group, not a child resource. Here's how to adjust your policy:
Modified Policy Code
{ "mode": "All", "policyRule": { "if": { "field": "type", "equals": "Microsoft.Resources/subscriptions/resourceGroups" }, "then": { "effect": "deployIfNotExists", "details": { "type": "Microsoft.Authorization/locks", "existenceCondition": { "allOf": [ { "field": "Microsoft.Authorization/locks/level", "equals": "CanNotDelete" }, { "field": "id", "like": "[concat(field('id'), '/providers/Microsoft.Authorization/locks/*')]" } ] }, "roleDefinitionIds": [ "/providers/Microsoft.Authorization/roleDefinitions/18d7d88d-d35e-4fb5-a5c3-7773c20a72d9", "/providers/Microsoft.Authorization/roleDefinitions/b24988ac-6180-42a0-ab88-20f7382dd24c" ], "deployment": { "properties": { "mode": "incremental", "template": { "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json", "contentVersion": "1.0.0.0", "resources": [ { "type": "Microsoft.Authorization/locks", "apiVersion": "2017-04-01", "name": "ResourceLock", "properties": { "level": "CanNotDelete", "notes": "Prevent accidental deletion of resources" } } ] } } } } } }, "parameters": {} }
Key Changes Explained
The critical update is in the existenceCondition block, using allOf to combine two checks:
- Lock Level: Ensures the lock is set to
CanNotDelete(same as your original policy). - Lock Scope: Uses
field('id')to reference the resource group's ID, then checks if the lock's ID starts with that resource group ID followed by/providers/Microsoft.Authorization/locks/. This guarantees the lock is applied directly to the resource group, not a child resource (like a KeyVault, whose lock ID would include the resource's own path before the lock reference).
With this change, your policy will only mark a resource group as compliant if it has a direct CanNotDelete lock applied to it—resource-level locks won't trigger a false positive anymore.
内容的提问来源于stack exchange,提问作者Alex

