Terraform动态规则中ipv6_cidr_blocks不生效问题求助
问题:Terraform安全组动态Egress规则中ipv6_cidr_blocks不生效
场景复现
我配置了带有动态Ingress和Egress规则的安全组模块,其中Egress规则代码如下:
dynamic "egress" { for_each = var.egress_rules_app_layer content { from_port = egress.value["from_port"] to_port = egress.value["to_port"] protocol = egress.value["protocol"] cidr_blocks = try((egress.value["cidr_blocks"]),[]) ipv6_cidr_blocks = try((egress.value["ipv6_cidr_blocks"]),[]) description = egress.value["description"] } }
通过tfvars传入规则配置:
egress_rules_app_layer = [ { from_port = 443 to_port = 443 protocol = "tcp" description = "https" cidr_blocks = [ "47.60.187.70/32" ] }, { from_port = 443 to_port = 443 protocol = "tcp" description = "https" cidr_blocks = [] ipv6_cidr_blocks = [ "2686:4721:4422::6812:2a7a/128" ] } ]
执行terraform plan后,发现ipv6_cidr_blocks未被正确识别,第二条规则的该字段始终为空数组:
+ { + cidr_blocks = [ + "47.60.187.70/32" ] + description = "https" + from_port = 443 + ipv6_cidr_blocks = [] + prefix_list_ids = [] + protocol = "tcp" + security_groups = [] + self = false + to_port = 443 }, + { + cidr_blocks = [] + description = "https" + from_port = 443 + ipv6_cidr_blocks = [] + prefix_list_ids = [] + protocol = "tcp" + security_groups = [] + self = false + to_port = 443 },
已排除语法问题、隔离测试场景并尝试最新Terraform版本,仅当直接在安全组规则内硬编码配置时ipv6_cidr_blocks才生效,求原因及解决办法。
原因及解决办法
核心原因:变量类型约束缺失
问题出在var.egress_rules_app_layer的变量定义上——你大概率没有为这个变量明确声明包含ipv6_cidr_blocks字段的类型约束。
Terraform处理未明确类型的复杂变量时,会根据列表第一个元素的结构推断整个列表的元素类型。你的第一个规则对象里没有ipv6_cidr_blocks字段,Terraform就会推断该变量的元素类型不包含这个字段,导致后续元素中的ipv6_cidr_blocks被自动忽略。
解决步骤
- 明确变量类型约束:在模块的
variables.tf中,为egress_rules_app_layer定义完整的对象类型,确保包含ipv6_cidr_blocks字段:
variable "egress_rules_app_layer" { type = list(object({ from_port = number to_port = number protocol = string description = string cidr_blocks = list(string) ipv6_cidr_blocks = list(string) # 必须明确声明该字段 })) default = [] }
- 优化取值逻辑(可选):由于已明确变量类型,每个元素都会包含所有声明的字段,
try函数可以简化为直接取值:
dynamic "egress" { for_each = var.egress_rules_app_layer content { from_port = egress.value.from_port to_port = egress.value.to_port protocol = egress.value.protocol cidr_blocks = egress.value.cidr_blocks ipv6_cidr_blocks = egress.value.ipv6_cidr_blocks description = egress.value.description } }
验证
修改后重新执行terraform plan,第二条规则的ipv6_cidr_blocks会正确显示传入的IPv6地址段。
内容的提问来源于stack exchange,提问作者Vlad Cenan
相关产品推荐
相关产品推荐

