You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 23:36:08