如何用Terraform的for_each基于嵌套变量生成Azure LB NAT规则
解决Terraform遍历嵌套变量创建Azure LB NAT规则的问题
方案一:基于原有嵌套变量结构处理
如果想保留现有var.test的嵌套结构(map包含t1/t2,每个条目下有top数组),可以通过flatten函数将嵌套结构转为一维列表,再用for_each遍历生成资源。
1. 变量定义(保持原有结构)
variable "test" { type = map(object({ top = list(object({ port = number name = string })) })) default = { t1 = { top = [ { port = 12, name = "port12" }, { port = 123, name = "port123" } ] }, t2 = { top = [ { port = 12, name = "port12" }, { port = 123, name = "port123" } ] } } }
2. 生成扁平规则列表
通过flatten把嵌套的map+list结构转为一维,确保每个NAT规则对应一个独立的元素:
locals { nat_rules_flat = flatten([ for prefix, group in var.test : [ for item in group.top : { unique_key = "${prefix}-${item.name}" prefix = prefix port = item.port name_part = item.name } ] ]) }
3. 创建NAT规则资源
用for_each遍历扁平后的列表,生成符合要求的资源:
resource "azurerm_lb_nat_rule" "example" { for_each = { for rule in local.nat_rules_flat : rule.unique_key => rule } name = "ELB-${upper(each.value.prefix)}-${each.value.name_part}" loadbalancer_id = azurerm_lb.example.id # 替换为你的负载均衡器ID frontend_ip_configuration_id = azurerm_lb.example.frontend_ip_configuration[0].id # 替换为你的前端IP配置ID protocol = "Tcp" frontend_port = each.value.port backend_port = each.value.port }
方案二:调整变量为扁平结构(更易维护)
如果可以调整变量结构,直接定义成一维列表会更简洁,避免嵌套遍历的复杂度:
1. 调整后的变量定义
variable "nat_rules" { type = list(object({ prefix = string # 对应原有的t1/t2 port = number name_suffix = string # 对应原有的port12/port123 })) default = [ { prefix = "T1", port = 12, name_suffix = "port12" }, { prefix = "T2", port = 12, name_suffix = "port12" }, { prefix = "T1", port = 123, name_suffix = "port123" }, { prefix = "T2", port = 123, name_suffix = "port123" } ] }
2. 直接创建NAT规则资源
resource "azurerm_lb_nat_rule" "example" { for_each = { for rule in var.nat_rules : "${rule.prefix}-${rule.name_suffix}" => rule } name = "ELB-${each.value.prefix}-${each.value.name_suffix}" loadbalancer_id = azurerm_lb.example.id frontend_ip_configuration_id = azurerm_lb.example.frontend_ip_configuration[0].id protocol = "Tcp" frontend_port = each.value.port backend_port = each.value.port }
关键说明
- 两种方案都会生成符合要求的NAT规则名称:
ELB-T1-port12、ELB-T2-port12等 for_each使用唯一键(如T1-port12)确保资源实例唯一,避免Terraform重复创建或报错frontend_port和backend_port直接引用变量中的端口值,满足需求
内容的提问来源于stack exchange,提问作者Wanexa
相关产品推荐
相关产品推荐

