如何在Terraform中合并两个本地变量并优化负载均衡器目标组关联配置
解决方案:合并实例与端口配置生成统一映射
要实现将实例信息和对应的端口配置合并,你可以通过嵌套的for循环结合merge函数创建一个新的本地变量,为每个实例的每个关联端口生成独立条目,完美适配aws_lb_target_group_attachment的for_each需求,彻底告别硬编码端口的冗余写法。
步骤1:创建合并后的本地变量
添加一个新的本地变量service_instance_port_map,它会自动遍历你的实例映射和端口配置,将两者信息无缝合并:
locals { # 保留原有的两个本地变量 test-svc = {for idx,svc in local.merged_lbport_svc : "${svc.service}-${svc.port}" => svc ...} service_instance_map = merge([for env, value in data.aws_instances.ecom-instances: { for id in value.ids: "${env}-${id}" => { "service" = env "id" = id } } ]...) # 核心:生成每个实例+对应服务端口的组合映射 service_instance_port_map = merge([ for instance_key, instance in local.service_instance_map : { # 筛选当前实例所属服务的所有端口配置 for port_config in [for pc in values(local.test-svc) : pc if pc.service == instance.service] : # 生成唯一键:服务名-实例ID-端口号(确保for_each的唯一性) "${instance.service}-${instance.id}-${port_config.port}" => merge(instance, port_config) } ]...) }
代码逻辑说明:
- 外层
for循环遍历service_instance_map中的每台EC2实例 - 内层
for循环只筛选出与当前实例所属服务匹配的端口配置,避免无效组合 - 用
merge(instance, port_config)把实例的id/service和端口的port/protocol合并成完整对象 - 最后通过
merge(...)把所有生成的键值对整合成一个统一的映射表
步骤2:更新负载均衡目标组关联资源
现在只需一个资源就能覆盖所有端口的实例关联,无需再为80/443单独写重复代码:
resource "aws_lb_target_group_attachment" "ecom-tga" { for_each = local.service_instance_port_map target_group_arn = aws_lb_target_group.ecom-nlb-tgp["${each.value.service}-${each.value.port}"].arn port = each.value.port target_id = each.value.id depends_on = [aws_lb_target_group.ecom-nlb-tgp] }
这种写法的优势:
- 扩展性拉满:后续新增服务或端口时,只需维护
test-svc的配置,无需修改资源定义 - 消除冗余代码:告别硬编码端口的重复资源块,代码更简洁易读
- 统一管理:所有实例-端口关联都在一处处理,排查问题更高效
验证合并后的结构
合并后的service_instance_port_map会生成你期望的完整结构,包含所有实例与80/443端口的组合,示例片段如下:
{ "test-i-038ff8f67582ef64d-80" = { "id" = "i-038ff8f67582ef64d" "service" = "test" "port" = 80 "protocol" = "TCP" }, "test-i-038ff8f67582ef64d-443" = { "id" = "i-038ff8f67582ef64d" "service" = "test" "port" = 443 "protocol" = "TCP" }, # 其他实例与端口的组合条目... }
内容的提问来源于stack exchange,提问作者JPNagarajan
相关产品推荐
相关产品推荐

