Terraform重构为for_each后导入资源仍被重建,如何保留现有secret_version
问题根因
- 你没有正确迁移Terraform状态:从
count索引式资源地址切换为for_each映射式地址时,直接导入资源没有关联原有状态,导致Terraform认为现有资源是未管理的外部资源,需要新建 random_password资源未显式声明所有可选参数的默认值:旧版本random provider生成的状态中没有存储这些默认值,代码和状态对比时触发强制重建标记
解决方案步骤
第一步:迁移状态关联原有资源
不要直接重新导入资源,先使用terraform state mv命令将原来count索引的资源地址迁移到for_each的新地址,示例以demo1为例(假设demo1原来在var.secrets列表的第0位,也就是索引0,按你自己的实际索引和secret对应关系替换):
# 迁移aws_secretsmanager_secret terraform state mv 'module.cluster.module.secrets.aws_secretsmanager_secret.secret[0]' 'module.cluster.module.secrets.aws_secretsmanager_secret.secret["demo1"]' # 迁移aws_secretsmanager_secret_version terraform state mv 'module.cluster.module.secrets.aws_secretsmanager_secret_version.secret_version[0]' 'module.cluster.module.secrets.aws_secretsmanager_secret_version.secret_version["demo1"]' # 迁移random_password terraform state mv 'module.cluster.module.secrets.random_password.passwords[0]' 'module.cluster.module.secrets.random_password.passwords["demo1"]'
如果有多个secret,按照列表索引和secret_name的对应关系,依次执行上面的mv命令即可。
第二步:补全random_password的所有显式参数
将plan输出里标记forces replacement的所有参数,全部显式加到random_password资源块里,和默认值保持一致即可:
resource "random_password" "passwords" { for_each = { for secret in var.secrets : secret.secret_name => secret if var.generate_password } length = 20 special = true override_special = "_%@" # 补全以下默认值参数,避免触发重建 lower = true upper = true number = true min_lower = 0 min_upper = 0 min_numeric = 0 min_special = 0 }
第三步:验证结果
执行terraform plan,此时应该不会再输出需要重建资源的提示。如果还有secret_version的secret_string强制替换提示,执行terraform refresh同步现有secret的实际值到状态中即可。
内容的提问来源于stack exchange,提问作者shadow
相关产品推荐
相关产品推荐

