Terraform部署AWS ECS Fargate NLB多目标组配置问题
问题解答
1. ECS服务是否支持绑定多个目标组ARN?
支持。aws_ecs_service资源的load_balancer字段是可重复声明的块集合,并非仅支持单个配置。你可以为同一个ECS服务绑定多个目标组,每个目标组对应容器的一个暴露端口,由负载均衡器按端口转发规则把流量路由到对应目标组。
2. 是否可以为单个目标组配置多端口?
不可以。单个目标组仅支持配置一个监听端口、一个四层/七层协议。你在控制台看到的同个目标组下的多个注册条目,是不同后端IP/ENI上的同端口实例,并非单目标组支持多端口监听。单目标组无法实现多端口流量的转发承载,强行混用会导致流量路由错乱。
配置修正方案
你当前的配置存在一处逻辑错误:循环创建的NLB监听器全部将流量转发到了默认目标组,没有关联你循环生成的对应端口目标组,需要先修正这部分逻辑,再通过动态块给ECS服务绑定多目标组。
修正后的核心配置示例
变量定义(无需调整)
variable "sftp_ports" { type = map default = { test1 = { port = 50003 } test2 = { port = 50004 } } }
目标组配置
# 原有默认目标组,不需要可删除 resource "aws_lb_target_group" "default-target-group" { name = local.name port = var.sftp_test_port protocol = "TCP" target_type = "ip" vpc_id = data.aws_vpc.default.id } # 多端口对应目标组 resource "aws_lb_target_group" "sftp_tg" { for_each = var.sftp_ports name = "sftp-target-group-${each.key}" port = each.value.port protocol = "TCP" target_type = "ip" vpc_id = data.aws_vpc.default.id }
注:
aws_alb_target_group是旧版别名资源,和aws_lb_target_group功能完全一致,建议统一命名规范。原配置中目标组和LB的depends_on属于冗余配置,Terraform会自动识别资源间引用关系处理部署顺序,可以删除。
监听器配置(修正转发逻辑)
# 默认端口监听器,不需要可删除 resource "aws_lb_listener" "default_listener" { load_balancer_arn = aws_lb.proxypoc.id port = var.sftp_test_port protocol = "TCP" default_action { type = "forward" target_group_arn = aws_lb_target_group.default-target-group.arn } } # 多端口对应监听器,转发到对应端口的目标组 resource "aws_lb_listener" "sftp_multi_port_listener" { for_each = var.sftp_ports load_balancer_arn = aws_lb.proxypoc.id port = each.value.port protocol = "TCP" default_action { type = "forward" target_group_arn = aws_lb_target_group.sftp_tg[each.key].arn } }
ECS服务多目标组绑定
通过dynamic块循环生成多个load_balancer配置块,实现多目标组和容器端口的绑定:
resource "aws_ecs_service" "sftp_service" { name = "sftp-nginx-service" cluster = aws_ecs_cluster.main.id task_definition = aws_ecs_task_definition.sftp.arn desired_count = 2 launch_type = "FARGATE" network_configuration { subnets = data.aws_subnets.private.ids security_groups = [aws_security_group.ecs_sg.id] assign_public_ip = false } # 绑定多端口对应目标组 dynamic "load_balancer" { for_each = var.sftp_ports content { target_group_arn = aws_lb_target_group.sftp_tg[load_balancer.key].arn container_name = "nginx-sftp" # 替换为你任务定义中SFTP容器的实际名称 container_port = load_balancer.value.port } } # 如需保留默认目标组,取消下方注释即可 /* load_balancer { target_group_arn = aws_lb_target_group.default-target-group.arn container_name = "nginx-sftp" container_port = var.sftp_test_port } */ }
注意事项
- 确保ECS任务定义的
port_mappings段已经声明了所有sftp_ports中定义的端口,否则目标组绑定会失败。 - ECS任务关联的安全组需要放通所有SFTP端口的入方向流量,源段根据你的实际访问控制需求配置。
- Fargate启动类型的目标组必须使用
ip目标类型,你当前的配置符合要求,无需调整。
内容的提问来源于stack exchange,提问作者Rick
相关产品推荐
相关产品推荐

