Terraform三元运算符逻辑反向生效问题排查
Terraform多层模块dynamic块条件渲染问题
场景说明
存在三层模块调用链:第一层模块调用第二层,第二层调用第三层。目标是通过vpc_cidr参数控制第三层模块中aws_lambda_function资源的vpc_config dynamic块是否渲染——当vpc_cidr不为null时生成该块,为null时省略。
相关代码
第一层模块调用
module "foobar" { source = "./modules/foobar" ... vpc_cidr = "10.0.0.0/16" # 或设置为null,或省略(默认值为null) ... }
第二层模块(路径:./modules/foobar)
module "second_level" { source = "./modules/second_level" ... vpc_config = var.vpc_cidr == null ? {} : { "some" = "things" } ... }
第三层模块(路径:./modules/second_level)
locals { vpc_config = var.vpc_config == {} ? {} : { this = var.vpc_config } } resource "aws_lambda_function" "this" { ... dynamic "vpc_config" { for_each = local.vpc_config content { "some" = vpc_config.value["some"] } ... }
问题现象
- 当
vpc_cidr设为有效值时,dynamic块正常渲染,功能符合预期; - 当
vpc_cidr设为null时,触发错误:
│ 32: security_group_ids = vpc_config.value["some"] │ ├──────────────── │ │ vpc_config.value is empty map of dynamic
- 反转第三层模块中local变量的三元运算符逻辑(
vpc_config = var.vpc_config == {} ? { this = var.vpc_config } : {})后,功能反而符合预期。
优化方案
最初将非空map包装为单元素map是为了让for_each仅迭代一次。考虑到for_each可遍历任意集合类型,优化本地变量定义为:
locals { vpc_config = length(var.vpc_config) == 0 ? [] : [var.vpc_config] }
对应的dynamic块改为遍历列表:
dynamic "vpc_config" { for_each = local.vpc_config content { subnet_ids = var.vpc_config["subnet_ids"] security_group_ids = var.vpc_config["security_group_ids"] } }
这种将map转为单元素列表的方式,在模块调用链中逻辑更合理,能正确实现dynamic块的条件渲染。
内容的提问来源于stack exchange,提问作者Afraz
相关产品推荐
相关产品推荐

