Terraform部署Azure Key Vault遇策略拒绝:已配置软删除仍报错
使用Terraform部署Azure密钥保管库时,已在配置中开启清除保护、设置软删除保留天数为90天,但仍触发Azure策略拒绝错误,提示需启用软删除、清除保护并将保留天数设为90天。
错误信息
错误:创建密钥保管库(订阅:"XXX"
资源组名称:"AZR-WHK-Appservice-POC"
密钥保管库名称:"kv-sctddi-poc"):执行CreateOrUpdate时出错:vaults.VaultsClient#CreateOrUpdate:发送请求失败:StatusCode=0 -- 原始错误:代码="RequestDisallowedByPolicy" 消息="资源'kv-sctddi-poc'被策略阻止。原因:'需启用软删除和清除保护,且保留天数应为90天'。查看错误详情获取策略资源ID。" 目标="kv-sctddi-poc" 附加信息=[{"info":{"evaluationDetails":{"evaluatedExpressions":[{"expression":"type","expressionKind":"Field","expressionValue":"Microsoft.KeyVault/vaults","operator":"Equals","path":"type","result":"True","targetValue":"Microsoft.KeyVault/vaults"},{"expression":"Microsoft.KeyVault/vaults/createMode","expressionKind":"Field","expressionValue":"default","operator":"Equals","path":"properties.createMode","result":"False","targetValue":"recover"},{"expression":"Microsoft.KeyVault/vaults/softDeleteRetentionInDays","expressionKind":"Field","operator":"NotEquals","path":"properties.softDeleteRetentionInDays","result":"True","targetValue":"90"}],"reason":"需启用软删除和清除保护,且保留天数应为90天"},"policyAssignmentDisplayName":"VPCx Landing Zone KeyVault","policyAssignmentId":"/providers/Microsoft.Management/managementGroups/Production/providers/Microsoft.Authorization/policyAssignments/vpcx-lzn-keyvault","policyAssignmentName":"vpcx-lzn-keyvault","policyAssignmentParameters":{},"policyAssignmentScope":"/providers/Microsoft.Management/managementGroups/Production","policyDefinitionDisplayName":"VPCx - 密钥保管库应启用软删除和清除保护,并将保留天数设为90天","policyDefinitionEffect":"拒绝","policyDefinitionId":"/providers/Microsoft.Management/managementGroups/Production/providers/Microsoft.Authorization/policyDefinitions/vpcx-lzn-keyvault-enable-soft-delete-purge-retention-days-90","policyDefinitionName":"vpcx-lzn-keyvault-enable-soft-delete-purge-retention-days-90","policyDefinitionReferenceId":"vpcx-lzn-keyvault-enable-soft-delete-purge-retention-days-90","policyExemptionIds":[],"policySetDefinitionDisplayName":"VPCx Landing Zone KeyVault Baseline","policySetDefinitionId":"/providers/Microsoft.Management/managementGroups/Production/providers/Microsoft.Authorization/policySetDefinitions/vpcx-landingzone-keyvault-baseline","policySetDefinitionName":"vpcx-landingzone-keyvault-baseline"},"type":"PolicyViolation"}]
关联资源:azurerm_key_vault.azure_key_vault,
位于main.tf第122行,resource "azurerm_key_vault" "azure_key_vault"中:
122: resource "azurerm_key_vault" "azure_key_vault"
Terraform配置
data "azurerm_client_config" "current" {} data "azuread_service_principal" "azure_service_app_principle" { client_id = "XXX" } resource "tls_private_key" "ssh" { algorithm = "RSA" rsa_bits = 4096 } resource "azurerm_key_vault_secret" "azure_key_vault" { name = "azure-key-vault-secret" value = "sctddi" key_vault_id = azurerm_key_vault.azure_key_vault.id depends_on = [azurerm_key_vault.azure_key_vault] } resource "azurerm_key_vault_secret" "ssh-private-key" { name = "ssh-private-key" value = tls_private_key.ssh.private_key_pem key_vault_id = azurerm_key_vault.azure_key_vault.id depends_on = [azurerm_key_vault.azure_key_vault] } resource "azurerm_key_vault_secret" "ssh-public-key-pem" { name = "ssh-public-key-pem" value = tls_private_key.ssh.public_key_pem key_vault_id = azurerm_key_vault.azure_key_vault.id depends_on = [azurerm_key_vault.azure_key_vault] } resource "azurerm_key_vault_secret" "ssh-public-key-openssh" { name = "ssh-public-key-openssh" value = tls_private_key.ssh.public_key_openssh key_vault_id = azurerm_key_vault.azure_key_vault.id depends_on = [azurerm_key_vault.azure_key_vault] } resource "azurerm_key_vault" "azure_key_vault" { depends_on = [data.azurerm_client_config.current, data.azuread_service_principal.azure_service_app_principle] enable_rbac_authorization = true purge_protection_enabled = true soft_delete_retention_days = 90 enabled_for_disk_encryption = true sku_name = "standard" public_network_access_enabled = false name = "kv-sctddi-poc" location = var.location resource_group_name = var.resourcegroupname tenant_id = data.azurerm_client_config.current.tenant_id network_acls { default_action = "Deny" bypass = "AzureServices" } access_policy { tenant_id = data.azurerm_client_config.current.tenant_id object_id = data.azurerm_client_config.current.object_id key_permissions = [ "Get", "List", "Update", "Create", "Import", "Delete", "Recover", "Backup", "Restore", "Decrypt", "Encrypt", "UnwrapKey", "WrapKey", "Verify", "Sign", "Purge", "Release", "Rotate", "GetRotationPolicy", "SetRotationPolicy" ] secret_permissions = ["Get", "List", "Set", "Delete", "Recover", "Backup", "Restore", "Purge"] storage_permissions = [ "Get", "Backup", "Delete", "DeleteSAS", "Get", "GetSAS", "List", "ListSAS", "Purge", "Recover", "RegenerateKey", "Restore", "Set", "SetSAS", "Update" ] } }
Azure策略定义
{ "properties": { "displayName": "VPCx - 密钥保管库应启用软删除和清除保护,并将保留天数设为90天", "policyType": "自定义", "mode": "全部", "description": "意外删除密钥保管库可能导致永久数据丢失。软删除允许在配置的保留期内恢复意外删除的密钥保管库。清除保护通过强制软删除密钥保管库的保留期来防范内部攻击,在此期间组织或微软都无法清除密钥保管库。", "metadata": { "category": "密钥保管库", "createdBy": "", "createdOn": "2024-04-05T12:25:59.6392467Z", "updatedBy": null, "updatedOn": null }, "version": "1.0.0", "parameters": { "effect": { "type": "字符串", "metadata": { "displayName": "效果", "description": "策略规则匹配时执行的操作" }, "allowedValues": [ "审核", "拒绝", "禁用" ], "defaultValue": "拒绝" } }, "policyRule": { "if": { "allOf": [ { "field": "type", "equals": "Microsoft.KeyVault/vaults" }, { "not": { "field": "Microsoft.KeyVault/vaults/createMode", "equals": "recover" } }, { "anyOf": [ { "field": "Microsoft.KeyVault/vaults/enableSoftDelete", "exists": "false" }, { "field": "Microsoft.KeyVault/vaults/enablePurgeProtection", "exists": "false" }, { "field": "Microsoft.KeyVault/vaults/enableSoftDelete", "equals": "false" }, { "field": "Microsoft.KeyVault/vaults/enablePurgeProtection", "equals": "false" }, { "field": "Microsoft.KeyVault/vaults/softDeleteRetentionInDays", "notEquals": "90" } ] } ] }, "then": { "effect": "[parameters('effect')]" } }, "versions": [ "1.0.0" ] }, "id": "/providers/Microsoft.Management/managementGroups/Production/providers/Microsoft.Authorization/policyDefinitions/vpcx-lzn-keyvault-enable-soft-delete-purge-retention-days-90", "type": "Microsoft.Authorization/policyDefinitions", "name": "vpcx-lzn-keyvault-enable-soft-delete-purge-retention-days-90", "systemData": { "createdBy": "daab", "createdByType": "应用程序", "createdAt": "2024-04-05T12:25:59.6005721Z", "lastModifiedBy": "aab", "lastModifiedByType": "应用程序", "lastModifiedAt": "2024-04-05T12:25:59.6005721Z" } }
问题原因及解决方案
原因分析
从错误详情的表达式评估结果可见,策略判定Microsoft.KeyVault/vaults/softDeleteRetentionInDays不等于90,同时策略会检查enableSoftDelete字段是否存在且为true。
Terraform的AzureRM提供程序中,soft_delete_retention_days参数默认启用软删除,但未显式生成enableSoftDelete资源属性,导致策略触发exists: false的判定条件,同时可能因隐式设置的保留天数未被策略识别为90,最终触发拒绝。
解决方案
修改Terraform的密钥保管库资源配置,显式添加soft_delete_enabled = true参数,确保Azure资源属性中包含enableSoftDelete字段,同时保留现有清除保护和保留天数配置。
修改后的密钥保管库核心配置片段:
resource "azurerm_key_vault" "azure_key_vault" { depends_on = [data.azurerm_client_config.current, data.azuread_service_principal.azure_service_app_principle] enable_rbac_authorization = true purge_protection_enabled = true soft_delete_enabled = true # 显式声明启用软删除 soft_delete_retention_days = 90 enabled_for_disk_encryption = true sku_name = "standard" public_network_access_enabled = false name = "kv-sctddi-poc" location = var.location resource_group_name = var.resourcegroupname tenant_id = data.azurerm_client_config.current.tenant_id # 其余配置保持不变 }
验证步骤
- 执行
terraform plan,确认配置变更会正确设置enableSoftDelete属性为true - 重新部署资源,验证策略拒绝错误是否消失
内容的提问来源于stack exchange,提问作者Nick

