Search code examples
aws-cloudformationamazon-elbamazon-ecs

ECS and Application Load Balancer


Ive been looking for some information on Cloud Formation with regards to creating a stack with ECS and ELB (Application Load Balancer) but unable to do so.

I have created two Docker images each containing a Node.js microservice that listens on ports 3000 and 4000. How do I go about creating my stack with ECS and ELB as mentioned ? I assume the Application Load Balancer can be configured to listen to both these ports ?

A sample Cloud Formation template would really help.


Solution

  • The Application Load Balancer can be used to load traffic across the ECS tasks in your service(s). The Application Load Balancer has two cool features that you can leverage; dynamic port mapping (port on host is auto-assigned by ECS/Docker) allowing you to run multiple tasks for the same service on a single EC2 instance and path-based routing allowing you to route incoming requests to different services depending on patterns in the URL path.

    To wire it up you need first to define a TargetGroup like this

    "TargetGroupService1" : {
      "Type" : "AWS::ElasticLoadBalancingV2::TargetGroup",
      "Properties" : {
        "Port": 10,
        "Protocol": "HTTP",
        "HealthCheckPath": "/service1",
        "VpcId": {"Ref" : "Vpc"}
      }
    }
    

    If you are using dynamic port mapping, the port specified in the target group is irrelevant since it will be overridden by the dynamically allocated port for each target.

    Next you define a ListenerRule that defines the path that shall be routed to the TargetGroup:

    "ListenerRuleService1": {
      "Type" : "AWS::ElasticLoadBalancingV2::ListenerRule",
      "Properties" : {
        "Actions" : [
          {
            "TargetGroupArn" : {"Ref": "TargetGroupService1"},
            "Type" : "forward"
          }
        ],
        "Conditions" : [
          {
            "Field" : "path-pattern",
            "Values" : [ "/service1" ]
          }
        ],
        "ListenerArn" : {"Ref": "Listener"},
        "Priority" : 1
      }
    }
    

    Finally you associate your ECS Service with the TargetGroup. This enable ECS to automatically register your task containers as targets in the target group (with the host port that you have configured in your TaskDefinition)

    "Service1": {
      "Type" : "AWS::ECS::Service",
      "DependsOn": [
        "ListenerRuleService1"
      ],
      "Properties" : {
        "Cluster" : { "Ref" : "ClusterName" },
        "DesiredCount" : 2,
        "Role" : "/ecsServiceRole",
        "TaskDefinition" : {"Ref":"Task1"},
        "LoadBalancers": [
          {
            "ContainerName": "Task1",
            "ContainerPort": "8080",
            "TargetGroupArn" : { "Ref" : "TargetGroupService1" }
          }
        ]
      }
    }  
    

    You can find more details in a blog post I have written about this, see Amazon ECS and Application Load Balancer