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

Terraform中用for_each替代count并按需忽略Secret读取

Terraform环境隔离:解决live环境下忽略dev密钥读取问题

现有配置情况

用count控制多环境Glue Connector模块(main.tf)

最初通过count条件判断,分别为dev和live环境创建Glue Connector模块:

module "glue_connection_component_anon" {
  count = var.environment == "dev" ? 1 : 0
  source           = "../../modules/glue_connector"
  connector_config = local.glue_connectors_config_anon
  default_tags     = local.default_tags
}
    

module "glue_connection_component_live" {
  count = var.environment == "live" ? 1 : 0
  source           = "../../modules/glue_connector"
  connector_config = local.glue_connectors_config_live
  default_tags     = local.default_tags
}

尝试改用for_each优化(未达预期)

为避免count的索引问题,尝试改用for_each,但效果不理想:

module "glue_connection_component_anon" {
  for_each          = var.environment == "dev" ? { "dev" : 1 } : {}
  source            = "../../modules/glue_connector"
  connector_config  = local.glue_connectors_config_anon
  default_tags      = local.default_tags
}

遇到的错误

在live环境执行时,Terraform尝试读取不存在的dev环境密钥,报错如下:

Error: Secrets Manager Secret "arn:aws:secretsmanager:eu-west-1:596459206669:secret:dev/rds/replica-SfiJXX" not found
│ 
│   with data.aws_secretsmanager_secret.secret_rds_dev,
│   on data_secret_rds.tf line 16, in data "aws_secretsmanager_secret" "secret_rds_dev":
│   16: data "aws_secretsmanager_secret" "secret_rds_dev" {

当前密钥读取配置(secrets.tf)

目前的密钥读取代码未做环境判断,不管什么环境都会尝试读取dev密钥:

data "aws_secretsmanager_secret" "secret_rds_dev" {
  arn = local.secret_rds_dev_arn
}

data "aws_secretsmanager_secret_version" "secret_rds_dev" {
  secret_id = data.aws_secretsmanager_secret.secret_rds_dev.id
}

解决方案

1. 给密钥数据资源添加环境判断条件

通过count或for_each,让Terraform只在dev环境下读取dev密钥:

方案A:用count实现

data "aws_secretsmanager_secret" "secret_rds_dev" {
  count = var.environment == "dev" ? 1 : 0
  arn   = local.secret_rds_dev_arn
}

data "aws_secretsmanager_secret_version" "secret_rds_dev" {
  count      = var.environment == "dev" ? 1 : 0
  secret_id  = data.aws_secretsmanager_secret.secret_rds_dev[0].id
}

当处于live环境时,count值为0,Terraform会跳过这两个数据资源的创建与读取。

方案B:用for_each实现(更清晰)

data "aws_secretsmanager_secret" "secret_rds_dev" {
  for_each = var.environment == "dev" ? { "dev" = local.secret_rds_dev_arn } : {}
  arn      = each.value
}

data "aws_secretsmanager_secret_version" "secret_rds_dev" {
  for_each  = data.aws_secretsmanager_secret.secret_rds_dev
  secret_id = each.value.id
}

version资源的for_each直接依赖secret资源的实例,当secret资源因环境不匹配未创建时,version资源也会自动跳过。

2. 优化Glue Connector模块的多环境管理

可以将两个环境的模块合并为一个,用for_each根据当前环境选择对应的配置,避免重复代码:

module "glue_connection_component" {
  for_each = var.environment == "dev" ? { dev = local.glue_connectors_config_anon } : 
             var.environment == "live" ? { live = local.glue_connectors_config_live } : {}
  source           = "../../modules/glue_connector"
  connector_config = each.value
  default_tags     = local.default_tags
}

这样只需要维护一个模块定义,根据环境自动创建对应实例,同时避免count带来的索引问题。

内容的提问来源于stack exchange,提问作者arooz

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 10:42:52