Terraform基于for_each的each.key计算资源变量报错解决
报错根因
报错本质是逻辑层级写反了:
- 你定义的
db_instance_identifier_key是根模块输入变量,Terraform执行plan时会优先校验所有根模块变量的赋值情况,这类全局变量必须在计划执行前就拿到确定值,根本等不到资源for_each迭代时再用each.key给它传值。 - 你写的全局
local块是模块加载阶段就计算的,同样拿不到资源迭代上下文里才存在的each.key,就算给变量加了默认值,算出来的结果也不是你要的每个迭代项对应的值。 - 额外语法问题:local块里的键名加了反引号,不符合HCL语法;
aws_cloudwatch_metric_alarm资源本身没有db_instance_identifier_key这个参数,你写的这行配置留着还会触发「不支持的参数」报错。
正确实现方式
不需要额外定义根模块变量,直接把动态计算逻辑放到迭代上下文里即可,推荐两种写法:
写法1:内联计算(逻辑简单时用)
直接在资源的dimensions块里基于each.key做判断,代码最简洁:
resource "aws_cloudwatch_metric_alarm" "example" { for_each = toset(var.myenvironments_map[var.environment]) # 保留你原有的其他alarm配置,删掉多余的db_instance_identifier_key参数行 dimensions = { DBInstanceIdentifier = each.key == "myKey" ? var.avariable : var.aMap[each.key].identifier } }
写法2:预生成映射表(逻辑复杂时用)
如果判断分支多、逻辑长,可以提前在local里生成所有迭代项对应的实例标识映射表,和for_each的键一一对应,再在资源里引用:
locals { # 注意这里不要给键名加反引号 alarm_db_identifier_map = { for env_key in var.myenvironments_map[var.environment] : env_key => env_key == "myKey" ? var.avariable : var.aMap[env_key].identifier } } resource "aws_cloudwatch_metric_alarm" "example" { for_each = toset(var.myenvironments_map[var.environment]) # 保留你原有的其他alarm配置,删掉多余的db_instance_identifier_key参数行 dimensions = { DBInstanceIdentifier = local.alarm_db_identifier_map[each.key] } }
校验方式
改完后直接执行terraform plan,原来的变量未赋值报错会消失,你可以在计划输出里看到每个告警对应的DBInstanceIdentifier维度值和each.key的匹配关系是否符合预期。
内容的提问来源于stack exchange,提问作者DeKekem
相关产品推荐
相关产品推荐

