如何避免Terraform Plan在GCP密钥轮换时误报变更?
问题分析
- Plan报虚假变更的原因:
time_rotating的rfc3339属性在每次Plan时会被重新计算(即使未到轮换时间),导致google_service_account_key的keepers值与状态文件中存储的不一致。Terraform因此误判需要销毁旧密钥并创建新密钥,但Apply时会校验实际轮换条件(是否到达轮换时间),最终判定无变更。 - Refresh创建重复密钥的原因:当Plan的虚假变更触发状态文件与实际资源的不一致时,执行
terraform refresh会将GCP上已存在的密钥当作未被跟踪的资源,错误地将其加入状态,进而触发重复创建。
解决方案
1. 修正keepers的取值逻辑
将google_service_account_key的keepers从基于rfc3339时间戳改为基于time_rotating的id属性。id是一个哈希值,仅在轮换条件满足时(当前时间超过上次轮换时间+轮换天数)才会更新,避免每次Plan都触发变更检测。
修改后的完整配置:
resource "time_rotating" "gcp_sa_private_key_rotation" { rotation_days = var.private_key_rotation_days } resource "google_service_account_key" "gcp_sa_private_key" { service_account_id = var.gcp_service_account_id keepers = { rotation_id = time_rotating.gcp_sa_private_key_rotation.id } } resource "gitlab_group_variable" "gcp_sa_private_key" { group = var.gitlab_group_id key = var.gitlab_variable_key value = google_service_account_key.gcp_sa_private_key.private_key protected = true masked = true }
2. 清理异常状态(若已出现重复密钥)
如果之前执行refresh导致状态中存在重复的密钥资源,执行以下命令移除多余条目:
terraform state rm module.my_list_of_accounts["my_service_account"].google_service_account_key.gcp_sa_private_key
执行后重新运行terraform apply,确保状态与实际资源一致。
3. 验证效果
修改配置后执行terraform plan:
- 未到轮换时间:Plan会显示
No changes. Your infrastructure matches the configuration. - 到达轮换时间:Plan会正确显示密钥替换的变更,执行
apply后完成轮换并自动更新GitLab变量。
内容的提问来源于stack exchange,提问作者AndrewM
相关产品推荐
相关产品推荐

