Search code examples
amazon-web-servicesamazon-ecsamazon-elb

ECS service with two Load Balancers for same port: internal and internet-facing


I'm having trouble while trying to apply a modification on a ECS cluster. Particularities of the environment:

  • Cluster has 2 services: blue and green.
  • Currently both services are associated to an Application Load Balancer that is exposed to the Internet.

What I want to do: add another ALB, in this case an internal one, to receive requests from private subnets in the VPC for the same service (same container, same port). When trying to apply those modifications I'm getting the following error:

CloudFormation cannot update a stack when a custom-named resource requires replacing. Rename [ClusterName|ServiceName] and update the stack again.

I'm describing these new entities using yml files. It's worth to mention that the new load balancer, its listeners and target groups were created successfully (even though the target group is not detecting the EC2 instances). The problem occurs when adding the LB to the the ECS service. Is this normal? Is it possible to have 2 LBs for the same ECS service for same port and same container name? Is there a workaround for doing this without renaming the cluster?

Edit: I tried creating a new ECS service with 2 load balancers associated to it and I got the following error (which is much more specific):

load balancers can have at most 1 items

So no, ECS services can't be associated to more than one ALB. The remaining question is: is there a workaround for this other than creating new ECS services for private subnet use?

Thanks.


Solution

  • On the 30th of July 2019, Amazon ECS released support for working with multiple load balancers / target groups in an ECS service. From their What's New blog post:

    Amazon ECS services now support multiple load balancer target groups

    You can now attach multiple target groups to your Amazon ECS services that are running on either Amazon EC2 or AWS Fargate. Target groups are used to route requests to one or more registered targets when using a load balancer. Attaching multiple target groups to your service allows you to simplify infrastructure code, reduce costs and increase manageability of your ECS services.

    As described in the docs, this enables different setups, including integration with internal and external load balancers as you mention in your question. From the docs (emphasis mine):

    Example: Having separate load balancers for internal and external traffic.

    In the following use case, a service uses two separate load balancers, one for internal traffic and a second for internet-facing traffic, for the same container and port.

    "loadBalancers":[
       //Internal ELB
       {  
          "targetGroupArn":"arn:aws:elasticloadbalancing:region:123456789012:targetgroup/target_group_name_1/1234567890123456",
          "containerName":"nginx",
          "containerPort":8080
       },
       //Internet-facing ELB
       {  
          "targetGroupArn":"arn:aws:elasticloadbalancing:region:123456789012:targetgroup/target_group_name_2/6543210987654321",
          "containerName":"nginx",
          "containerPort":8080
       }
    ]
    

    Related (and now closed) github issues from the public roadmap of the AWS container services are found here: