Break a Monolithic Application into Microservices with AWS Copilot, Amazon ECS, Docker, and AWS Fargate

TUTORIAL

Module Four: Deploy Microservices

Overview

This is the process to deploy the microservices and safely transition the application's traffic away from the monolith.

1. Switch the Traffic – This is the starting configuration. The monolithic Node.js app is running in a container on Amazon ECS.

2. Start Microservices – Using the three container images built and pushed to Amazon ECR by AWS Copilot, you will start up three microservices on your existing Amazon ECS cluster.

3. Shut Down the Monolith – Deleting the monolith services routes traffic to the running microservices. 

What you will accomplish

In this module, you will deploy your Node.js application as a set of interconnected services behind an Application Load Balancer (ALB). Then, you will delete the monolith service to seamlessly shift traffic from the monolith to the microservices.

 Minimum time to complete

30 minutes

 Services used

  • Amazon Elastic Container Service
  • Amazon Elastic Container Registry
  • Elastic Load Balancer

Implementation

Follow these step-by-step instructions to deploy the microservices. 

Step 1: Deploy the microservices

For each microservice, enter copilot svc deploy --name <microservice> . As with the monolith  service, AWS Copilot builds a container for the microservice, pushes it to a repository, and deploys it on an Amazon ECS cluster running on Fargate.

copilot svc deploy --name posts
Only found one environment, defaulting to: api
Building your container image: docker build -t 837028011264.dkr.ecr.us-east-1.amazonaws.com/api/posts --platform linux/x86_64 /Users/sparaaws/github/spara/amazon-ecs-nodejs-microservices/3-microservices/services/posts -f /Users/sparaaws/github/spara/amazon-ecs-nodejs-microservices/3-microservices/services/posts/Dockerfile
[+] Building 1.6s (10/10) FINISHED
 => [internal] load build definition from Dockerfile                                                                                      0.1s
 => => transferring dockerfile: 36B                                                                                                       0.0s
 => [internal] load .dockerignore                                                                                                         0.0s
 => => transferring context: 2B                                                                                                           0.0s
 => [internal] load metadata for docker.io/mhart/alpine-node:7.10.1                                                                       1.0s
 => [auth] mhart/alpine-node:pull token for registry-1.docker.io                                                                          0.0s
 => [internal] load build context                                                                                                         0.0s
 => => transferring context: 147B                                                                                                         0.0s
 => [1/4] FROM docker.io/mhart/alpine-node:7.10.1@sha256:d334920c966d440676ce9d1e6162ab544349e4a4359c517300391c877bcffb8c                 0.0s
 => => resolve docker.io/mhart/alpine-node:7.10.1@sha256:d334920c966d440676ce9d1e6162ab544349e4a4359c517300391c877bcffb8c                 0.0s
 => CACHED [2/4] WORKDIR /srv                                                                                                             0.0s
 => CACHED [3/4] ADD . .                                                                                                                  0.0s
 => CACHED [4/4] RUN npm install                                                                                                          0.0s
 => exporting to image                                                                                                                    0.1s
 => => exporting layers                                                                                                                   0.0s
 => => writing image sha256:b97d6e203a072a0ed3885414d5cc1f35baa9bbd46f74f122c4a3154a36e5e6a4                                              0.0s
 => => naming to 837028011264.dkr.ecr.us-east-1.amazonaws.com/api/posts                                                                   0.0s

Use 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them
Login Succeeded

Logging in with your password grants your terminal complete access to your account.
For better security, log in with a limited-privilege personal access token. Learn more at https://docs.docker.com/go/access-tokens/
Using default tag: latest
The push refers to repository [837028011264.dkr.ecr.us-east-1.amazonaws.com/api/posts]
8b3af4325a20: Pushed
9b446d573a92: Pushed
5f70bf18a086: Pushed
3e893534526a: Pushed
040fd7841192: Pushed
latest: digest: sha256:82749ddab70e1657feaa97134150e6d39abe32b3710538b37398996dc546e442 size: 1365
✔ Proposing infrastructure changes for stack api-api-posts
- Creating the infrastructure for stack api-api-posts                         [create complete]  [216.9s]
  - Service discovery for your services to communicate within the VPC         [create complete]  [3.6s]
  - Update your environment's shared resources                                [create complete]  [38.0s]
  - An IAM role to update your environment stack                              [create complete]  [19.5s]
  - An IAM Role for the Fargate agent to make AWS API calls on your behalf    [create complete]  [19.5s]
  - A HTTP listener rule for forwarding HTTP traffic                          [create complete]  [2.5s]
  - A custom resource assigning priority for HTTP listener rules              [create complete]  [3.8s]
  - A CloudWatch log group to hold your service logs                          [create complete]  [3.6s]
  - An IAM Role to describe load balancer rules for assigning a priority      [create complete]  [19.5s]
  - An ECS service to run and maintain your tasks in the environment cluster  [create complete]  [111.3s]
    Deployments
               Revision  Rollout      Desired  Running  Failed  Pending
      PRIMARY  2         [completed]  1        1        0       0
  - A target group to connect the load balancer to your service               [create complete]  [12.5s]
  - An ECS task definition to group your containers and run them on ECS       [create complete]  [0.0s]
  - An IAM role to control permissions for the containers in your tasks       [create complete]  [37.0s]
✔ Deployed service posts.
Recommended follow-up action:
  - You can access your service at http://api-a-Publi-7HVMVCJEP59-1269931118.us-east-1.elb.amazonaws.com/api/posts over the internet.
Deploy the threads and users microservices.

Deploy the threads and users microservices.

$ copilot svc deploy --name threads

$ copilot svc deploy --name users

Step 2: Shut down the monolith

To shut down the monolith service, delete the monolith Service. Enter copilot svc delete --name monolith in the terminal. 

Step 3: Verify the deployment

You can use the previous requests to verify that the microservices are deployed and working correctly.

http://.us-east-1.elb.amazonaws.com/api/users/3 (http://api-a-publi-du44d9vosxla-792918025.us-east-1.elb.amazonaws.com/api/users/3)

{"id":3,"username":"pb","name":"Bonnibel Bubblegum","bio":"Scientist, bearer of candy power, ruler of the candy kingdom"}
{"id":2,"title":"Party at the candy kingdom tomorrow","createdBy":3}
[{"thread":1,"text":"Has anyone checked on the lich recently?","user":4},{"thread":1,"text":"I'll stop by and see how he's doing tomorrow!","user":2},{"thread":2,"text":"Come party with the candy people tomorrow!","user":3},{"thread":2,"text":"Mathematical!","user":2},{"thread":2,"text":"I'll bring my guitar","user":1},{"thread":3,"text":"I need a new guitar to play the most savory licks in Ooo","user":1}]
[{"thread":1,"text":"Has anyone checked on the lich recently?","user":4},{"thread":1,"text":"I'll stop by and see how he's doing tomorrow!","user":2}]

Up Next: Clean Up

Was this page helpful?