In this module, you will break the node.js application into several interconnected services and push each service's image to an Amazon ECR repository. Start Building

The final application architecture uses Amazon Elastic Container Service and the Application Load Balancer. 

architecture overview

a. Client
The client makes traffic requests over port 80.

b. Load Balancer
The Application Load Balancer (ALB) routes external traffic to the correct service. The ALB inspects the client request and uses the routing rules to direct the request to an instance and port for the target group matching the rule.

c. Target Groups
Each service has a target group that keeps track of the instances and ports of each container running for that service.

d. Containerized Services
Amazon Elastic Container Service (Amazon ECS) deploys each service into a container across an EC2 cluster. Each container only handles a single feature.

Isolation of Crashes
Even the best engineering organizations can and do have fatal crashes in production. In addition to following all the standard best practices for handling crashes gracefully, one approach that can limit the impact of such crashes is building microservices. Good microservice architecture means that if one micro piece of your service is crashing, then only that part of your service will go down. The rest of your service can continue to work properly.

Isolation for Security
In a monolithic application if one feature of the application has a security breach, for example a vulnerability that allows remote code execution, then you must assume that an attacker could have gained access to every other feature of the system as well. This can be dangerous if, for example, your avatar upload feature has a security issue which ends up compromising your database with user passwords. Separating features into microservices using Amazon ECS allows you to secure access to AWS resources by giving each service its own IAM role. When microservice best practices are followed, the result is that if an attacker compromises one service, they only gain access to the resources of that service, and cannot horizontally access other resources from other services without breaking into those services as well.

Independent Scaling
When features are broken out into microservices, then the amount of infrastructure and number of instances used by each microservice class can be scaled up and down independently. This makes it easier to measure the cost of particular feature, identify features that may need to be optimized first, as well as keep performance reliable for other features if one particular feature is going out of control on its resource needs.

Development Velocity
Microservices lower the risks in development, which can enable a team to build faster. In a monolith, adding a new feature can potentially impact every other feature that the monolith contains. Developers must carefully consider the impact of any code they add, and ensure that they do not break anything. On the other hand, a proper microservice architecture has new code for a new feature going into a new service. Developers can be confident that any code they write will actually not be able to impact the existing code at all unless they explicitly write a connection between two microservices.

Time to Complete: 20 minutes

Services Used:

Follow the step-by-step instructions below to break the monolith. Click on each step number to expand the section.

  • Step 1. Provision the ECR Repositories

    In the previous two steps, you deployed your application as a monolith using a single service and a single container image repository. To deploy the application as three microservices, you will need to provision three repositories (one for each service) in Amazon ECR.

    Our three services are:

    1. users
    2. threads
    3. posts

    Create the repository:

    • Navigate to the Amazon ECR Console.
    • Select Create Repository
    • Repository name:
      • users
      • threads
      • posts
    • Record the repositories information: [account-id].dkr.ecr.[region][service-name]

    Repeat these steps for each microservice.

    You should now have four repositories in Amazon ECR.

  • Step 2. Authenticate Docker with AWS (optional)

    You may skip this step if you recently completed Module 1 of this workshop.

    • Run aws ecr get-login --no-include-email --region [region]
      Example: aws ecr get-login --no-include-email --region us-west-2
    • You are going to get a massive output starting with docker login -u AWS -p ... Copy this entire output, paste, and run it in the terminal.

    • You should see Login Succeeded

      ⚐ NOTE: If this login does not succeed, it may be because you have a newer version of Docker that has depreciated the -e none flag. To correct this, paste the output into your text editor, remove -e none from the end of the output, and run the updated output in the terminal.

  • Step 3. Build and Push Images for Each Service

    In the project folder amazon-ecs-nodejs-microservices/3-microservices/services, you will have folders with files for each service. Notice how each microservice is essentially a clone of the previous monolithic service.

    You can see how each service is now specialized by comparing the file db.json in each service and in the monolithic api service. Previously posts, threads, and users were all stored in a single database file. Now, each is stored in the database file for its respective service.

    Open your terminal, and set your path to the 3-microservices/services section of the GitHub code. ~/amazon-ecs-nodejs-microservices/3-microservices/services

    Build and Tag Each Image

    • In the terminal, run docker build -t [service-name] ./[service-name] Example: docker build -t posts ./posts
    • After the build completes, tag the image so you can push it to the repository: docker tag [service-name]:latest [account-id].dkr.ecr.[region][service-name]:v1 example: docker tag posts:latest [account-id]
    • Run docker push to push your image to ECR: docker push [account-id].dkr.ecr.[region][service-name]:v1

    If you navigate to your ECR repository, you should see your images tagged with v1. 

    ♻ Repeat these steps for each microservice image.  

    ⚐ NOTE: Be sure to build and tag all three images.