如何避免Terraform azurerm_key_vault的access_policy删除手动配置的访问策略
根本原因
你当前将access_policy作为内嵌块写在azurerm_key_vault资源声明中时,Terraform会将代码内定义的访问策略作为该Key Vault的唯一标准配置,执行apply时会删除所有不在代码内声明的访问策略(包括手动新增的策略)。
推荐解决方案:使用独立的azurerm_key_vault_access_policy资源管理策略
将内嵌的access_policy块从azurerm_key_vault资源中移除,改为用独立的azurerm_key_vault_access_policy资源管理你需要Terraform管控的策略。这种方式下Terraform只会处理你单独声明的策略,不会修改或删除其他手动创建的策略。
代码示例
- 修改原有Key Vault资源定义,删除内嵌
access_policy块:
resource "azurerm_key_vault" "key_vault" { name = "example" location = var.location resource_group_name = azurerm_resource_group.resource_group.name sku_name = "standard" tenant_id = var.tenant_id }
- 新增独立的访问策略资源管理需要Terraform管控的规则:
resource "azurerm_key_vault_access_policy" "uami_policy" { key_vault_id = azurerm_key_vault.key_vault.id tenant_id = var.tenant_id object_id = azurerm_user_assigned_identity.user_assigned_identity.principal_id secret_permissions = [ "get", ] }
迁移注意事项
如果已经通过内嵌方式部署过Key Vault,修改代码后首次执行plan时会提示要删除原有内嵌策略,你可以先将已存在的策略导入到新的独立资源状态中,避免意外删除原有有效策略:terraform import azurerm_key_vault_access_policy.uami_policy /subscriptions/你的订阅ID/resourceGroups/你的资源组名/providers/Microsoft.KeyVault/vaults/你的Key Vault名/objectId/对应托管标识的principal ID
备选方案:使用ignore_changes忽略策略变更
如果你不需要Terraform管控任何访问策略的变更,可以在azurerm_key_vault资源中添加生命周期规则忽略access_policy的变化,这样Terraform执行apply时不会修改任何访问策略配置。
代码示例
resource "azurerm_key_vault" "key_vault" { name = "example" location = var.location resource_group_name = azurerm_resource_group.resource_group.name sku_name = "standard" tenant_id = var.tenant_id access_policy { tenant_id = var.tenant_id object_id = azurerm_user_assigned_identity.user_assigned_identity.principal_id secret_permissions = [ "get", ] } lifecycle { ignore_changes = [access_policy] } }
局限性
添加该规则后,后续你在代码中修改access_policy块的任何配置,Terraform都不会感知和生效,所有访问策略的变更完全需要手动管理。
内容的提问来源于stack exchange,提问作者Raspberry

