Search code examples
amazon-web-servicesamazon-ecsserverlessamazon-elbaws-fargate

Exposing to public more than 1 port with AWS ECS service and Elastic LoadBalancer


I have service that exposes multiple ports and it worked fine with kubernetes but now we move it to AWS ECS. It seems I can only expose ports via Load Balancer and I am limited to 1 port per service/tasks even when docker defines multiple ports I have to choose one port

enter image description here

Add to load balancer button allows to add one port. Once added there is no button to add second port.

Is there any nicer workarround than making second proxy service to expose second port?

UPDATE: I use fargate based service.


Solution

  • Update: I was able to configure target group using Terraform but did not find so far this option on AWS console.

    resource "aws_ecs_service" "multiple_target_example" {
      name            = "multiple_target_example1"
      cluster         = "${aws_ecs_cluster.main.id}"
      task_definition = "${aws_ecs_task_definition.with_lb_changes.arn}"
      desired_count   = 1
      iam_role        = "${aws_iam_role.ecs_service.name}"
    
      load_balancer {
        target_group_arn = "${aws_lb_target_group.target2.id}"
        container_name   = "ghost"
        container_port   = "3000"
      }
    
      load_balancer {
        target_group_arn = "${aws_lb_target_group.target2.id}"
        container_name   = "ghost"
        container_port   = "3001"
      }
    
      depends_on = [
        "aws_iam_role_policy.ecs_service",
      ]
    }
    

    Version note: Multiple load_balancer configuration block support was added in Terraform AWS Provider version 2.22.0.

    ecs_service_terraform

    I can't say that this will be a nice workaround but I was working on a project where I need to run Ejabberd using AWS ECS but the same issue happened when its come to bind port of the service to the load balancer.

    I was working with terraform and due to this limitation of AWS ECS, we agree to run one container per instance to resolve the port issue as we were supposed to expose two port.

    If you do not want to assign a dynamic port to your container and you want to run one container per instance then the solution will definitely work.

    1. Create a target group and specify the second port of the container.

    2. Go to the AutoScalingGroups of your ECS cluster

    3. Edit and add the newly created target group of in the Autoscaling group of the ECS cluster

    So if you scale to two containers it's mean there will be two instances so the newly launch instance will register to the second target group and Autoscaling group take care of it. This approach working fine in my case, but few things need to be consider.

    Do not bind the primary port in target, better to bind primary port in ALB service. The main advantage of this approach will be that if your container failed to respond to AWS health check the container will be restart automatically. As the target groupe health check will not recreate your container.

    This approach will not work when there is dynamic port expose in Docker container.

    AWS should update its ECS agent to handle such scenario.