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
相关产品推荐
相关产品推荐

