In this module, you will use Amazon Elastic Container Service (Amazon ECS) to instantiate a managed cluster of Amazon EC2 compute instances and deploy your image as a container running on the cluster. Start Building

architecture overview

a. Client
The client makes a request over port 80 to the load balancer.

b. Load Balancer
The load balancer distributes requests across all available ports.

c. Target Groups
Instances are registered in the application's target group.

d. Container Ports
Each container runs a single application process which binds the node.js cluster parent to port 80 within its namespace.

e. Containerized node.js Monolith
The node.js cluster parent is responsible for distributing traffic to the workers within the monolithic application. This architecture is containerized, but still monolithic because each container has all the same features of the rest of the containers.

Amazon Elastic Container Service (Amazon ECS) is a highly scalable, high performance container management service that supports Docker containers and allows you to easily run applications on a managed cluster of Amazon EC2 instances. With simple API calls, you can launch and stop Docker-enabled applications, query the complete state of your cluster, and access many familiar features like security groups, Elastic Load Balancing, EBS volumes, and IAM roles.

You can use Amazon ECS to schedule the placement of containers across your cluster based on your resource needs and availability requirements. You can also integrate your own scheduler or third-party schedulers to meet business or application specific requirements.

There is no additional charge for Amazon Elastic Container Service. You pay for the Amazon Web Services resources (e.g. Amazon EC2 instances or Amazon EBS volumes) you create to store and run your application.

Follow the step-by-step instructions below to deploy the node.js application using Amazon ECS. Click on each step number to expand the section.

  • Step 1. Launch an ECS Cluster using Amazon Web Services CloudFormation

    First, you will create a an Amazon ECS cluster, deployed behind an Application Load Balancer.

    1. Navigate to the Amazon CloudFormation console.
    2. Select Create Stack.
    3. Select 'Upload a template to Amazon S3' and choose the ecs.yml file from the GitHub project at amazon-ecs-nodejs-microservice/2-containerized/infrastructure/ecs.yml Select Next.
    4. For stack name, enter BreakTheMonolith-Demo. Keep the other parameter values the same:
      1. Desired Capacity = 2
      2. InstanceType = t2.micro
      3. MaxSize = 2
    5. Select Next.
    6. It is not necessary to modify any options on this page. Select Next.
    7. Check the box at the bottom of the next page and select Create. You will see your stack with the orange CREATE_IN_PROGRESS. You can select the refresh button at the top right of the screen to check on the progress. This process typically takes under 5 minutes.
    create stack

    ⚐ NOTE: You can also use the Amazon CLI to deploy Amazon CloudFormation Stacks. Just add in your region to this code and run in the terminal from the folder amazon-ecs-nodejs-microservices/3-microservices on your computer.

    $ aws cloudformation deploy \
       --template-file infrastructure/ecs.yml \
       --region <region> \
       --stack-name Nodejs-Microservices \
       --capabilities CAPABILITY_NAMED_IAM
  • Step 2. Check your Cluster is Running

    check your cluster
    • Clicking into the cluster, select the 'Tasks' tab, no tasks will be running.
    • Select the 'ECS Instances' tab, you will see the two Amazon EC2 Instances the Amazon CloudFormation template created.
    ECS instances
  • Step 3. Write a Task Definition

    The task definition tells Amazon ECS how to deploy your application containers across the cluster.

    • Navigate to the 'Task Definitions' menu on the left side of the Amazon ECS console.
    • Select Create new Task Definition.
    • Task Definition Name = api.
    • Select Add Container.
    • Specify the following parameters.
      • If a parameter is not defined, leave it blank or with the default settings: Container name = api image = [account-id].dkr.ecr.[region] (this is the URL of your ECR repository image from the previous step).
      • Be sure the tag :v1 matches the value you used in module 1 to tag and push the image. Memory = Hard limit: 256 Port mappings = Host port:0, Container port:3000 CPU units = 256
    • Select Add.
    • Select Create.
    • Your Task Definition will now show up in the console.
    task definition
  • Step 4. Configure the Application Load Balancer: Target Group

    The Application Load Balancer (ALB) lets your service accept incoming traffic. The ALB automatically routes traffic to container instances running on your cluster using them as a target group.

    Check your VPC Name: If this is not your first time using this Amazon Web Services account, you may have multiple VPCs. It is important to configure your Target Group with the correct VPC.

    • Navigate to the Load Balancer section of the Amazon EC2 Console.
    • You should see a Load Balancer already exists named demo.
    • Select the checkbox to see the Load Balancer details.
    • Note the value for the VPC attribute on the details page.
    vpc attribute

    Configure the ALB Target Group

    • Navigate to the Target Group section of the Amazon EC2 Console.
    • Select Create target group.
    • Configure the Target Group (do not modify defaults if they are not specified here):
      • Name = api
      • Protocol = HTTP
      • Port = 80
      • VPC = select the VPC that matches your Load Balancer from the previous step. This is most likely NOT your default VPC.
      • Advanced health check settings: Healthy threshold = 2 Unhealthy threshold = 2 Timeout = 5 Interval = 6.
    • Select Create.
    create target groups
  • Step 5. Configure the Application Load Balancer: Listener

    The listener checks for incoming connection requests to your ALB.

    Add a Listener to the ALB

    • Navigate to the Load Balancer section of the Amazon EC2 Console.
    • You should see a Load Balancer already exists named demo.
    • Select the checkbox to see the Load Balancer details.
    • Select the Listeners tab.
    • Select Create Listener:
      • Protocol = HTTP
      • Port = 80
      • Default target group = api
    • Click Create.
    listener to ALB
  • Step 6. Deploy the Monolith as a Service

    Now, you will deploy the monolith as a service onto the cluster.

    • Navigate to the 'Clusters' menu on the left side of the Amazon ECS console.
    • Select your cluster: BreakTheMonolith-Demo-ECSCluster.
    • Under the services tab, select Create.
    • Configure the service (do not modify any default values): Service name = api Number of tasks = 1
    • Select Configure ELB:
      • ELB Type = Application Load Balancer.
      • For IAM role, select BreakTheMonolith-Demo-ECSServiceRole.
      • Select your Load Balancer ELB name = demo.
      • Select Add to ELB.
    • Add your service to the target group:
      • Listener port = 80:HTTP
      • Target group name = select your group: api.
    • Select Save.
    deploy your service
    • Select Create Service.
    • Select View Service.
    optional configure

    Nice work! You now have a running service. It may take a minute for the container to register as healthy and begin receiving traffic.

  • Step 7. Test your Monolith

    Validate your deployment by checking if the service is available from the internet and pinging it.

    To Find your Service URL:

    • Navigate to the Load Balancers section of the Amazon EC2 Console.
    • Select your load balancer demo.
    • Copy and paste the value for DNS name into your browser.
    • You should see a message 'Ready to receive requests'.

    See Each Part of the Service:
    The node.js application routes traffic to each worker based on the URL. To see a worker, simply add the worker name api/[worker-name] to the end of your DNS Name like this:

    • http://[DNS name]/api/users
    • http://[DNS name]/api/threads
    • http://[DNS name]/api/posts

    You can also add a record number at the end of the URL to drill down to a particular record. Like this: http://[DNS name]/api/posts/1 or http://[DNS name]/api/users/2

    user demo