Break a Monolithic Application Into Microservices With AWS Migration Hub Refactor Spaces, AWS Copilot
AWS lets you decompose a monolith and focus on innovation.
Step 2: Download and Open the Project
Module Two: Containerize and Deploy the Monolith
Dependency Control and Improved Pipeline
Density and Resource Efficiency
What You Will Accomplish in Module Two
Step 1: Create an AWS Copilot Application
Step 2: Create the Environment
Step 3: Deploy the Environment
Step 4: Create the Monolith AWS Copilot Service
Step 5: Confirm the Deployment
Module Three: Deploy the Refactor Environment
What You Will Accomplish in Module Three
Step 2: Deploy Refactor Spaces
Module Four: Break the Monolith
What You Will Accomplish in Module Four
Step 1: Create the Environments
Step 3: Edit the Path in the for Each Microservice
Module Five: Deploy Microservices
What You Will Accomplish in Module Five
Step 1: Deploy the Microservices
Step 2: Register Your Microservice With Refactor Spaces
Step 3: Shut Down the Monolith
Step 4: Test Your Microservices
What You Will Accomplish in Module Six
Step 1: Delete the Application
strangler fig
pattern, leave and layer
pattern, or refactor using a multi-account strategy
. Each of these approaches helps your business to improve the application efficacy by reducing the change risk for the application consumers.About | |
---|---|
✅ AWS Level | Intermediate - 200 |
⏱ Time to complete | 140 minutes |
🧩 Prerequisites | - An AWS account: If you don't already have an account, follow the Setting Up Your AWS Environment tutorial for a quick overview. - Install and configure the AWS CLI. - Install and configure AWS Copilot. - Install and configure Docker. - A text editor. For this tutorial, we will use VS Code, but you can use your preferred IDE. |
💻 Code Sample | - Code sample for application on GitHub - AWS CloudFormation scripts for Refactor Services on AWS Samples |
📢 Feedback | Any feedback, issues, or just a 👍 / 👎 ? |
⏰ Last Updated | 2023-11-16 |
- An AWS account: If you don't already have an account, follow the Setting Up Your AWS Environment tutorial for a quick overview.
- Install and configure the AWS CLI.
- Install and configure AWS Copilot.
- Install and configure Docker.
- A text editor. For this tutorial, we will use VS Code, but you can use your preferred IDE.
- Check that sufficient quota is available for all required services. For example, this tutorial uses five Virtual Private Clouds (VPCs) and there is a default quota of five VPCs per Region.
- Setup (20 minutes): In this module, you will install and configure the AWS CLI, install AWS Copilot, and install Docker.
- Containerize and deploy the monolith (30 minutes): In this module, you will containerize the application. You will instantiate a managed cluster of Fargate on Amazon ECS compute instances using AWS Copilot. You will also deploy your image as a container running on the cluster.
- Deploy the refactor environment (20 minutes): In this module, you will deploy a Refactor Spaces environment. This will set up the infrastructure to incrementally refactor your application. You will then register the monolith from the previous step as a default route in Refactor Spaces.
- Break the monolith (20 minutes): In this module, you will break the Node.js application into several interconnected services. Then you will push each service's image to an Amazon Elastic Container Registry (Amazon ECR) repository.
- Deploy microservices (30 minutes): In this module, you will deploy your Node.js application as a set of interconnected services behind an Application Load Balancer. Then, you will use Refactor Spaces to re-route traffic from the monolith to the microservices.
- Clean up (10 minutes): In this module, you will terminate the resources you created during the tutorial. You will stop the services running on Amazon ECS, delete the Application Load Balancer, and delete the AWS CloudFormation stack to terminate all underlying resources.
- ⏱ Time to complete: 20 minutes
- An AWS account: If you don't have an account with AWS, sign up here. All the exercises in this tutorial are designed to be covered under the AWS Free Tier. Note: Some of the services you will be using may require your account to be active for more than 12 hours. If you have a newly created account and encounter difficulty provisioning any services, wait a few hours and try again.
- Docker: You will use Docker to build the image files that will run as containers. Docker is an open-source project. You can download it for macOS or for Windows. After Docker is installed, verify it is running by entering Docker --version in the terminal. The version number should display, for example: Docker version 19.03.5, build 633a0ea.
- AWS CLI:
- You will use the AWS Command Line Interface (AWS CLI) to push the images to Amazon ECR. To learn about and download the AWS CLI, see Getting started with the AWS CLI.
- After AWS CLI is installed, verify it is running by entering aws --version in the terminal. The version number should display, for example:
aws-cli/1.16.217 Python/2.7.16 Darwin/18.7.0 botocore/1.12.207
. - If you already have AWS CLI installed, run the following command in the terminal to validate you are using the latest version:
pip install awscli --upgrade --user
. - If you have not used AWS CLI before, you can configure your credentials.
- AWS Copilot: AWS Copilot is an open-source command line interface that helps developers to build, release, and operate production-ready containerized applications. This can be done on AWS App Runner, Amazon ECS, and AWS Fargate. On macOS, you can use brew to install AWS Copilot.
1
brew install aws/tap/copilot-cli
1
curl -Lo copilot https://github.com/aws/copilot-cli/releases/latest/download/copilot-darwin && chmod +x copilot && sudo mv copilot /usr/local/bin/copilot && copilot --help
- Developers build and run the container locally.
- Continuous integration server runs the same container and runs integration tests to make sure it passes expectations.
- The same container is shipped to a staging environment where its runtime behavior can be checked using load tests or manual QA.
- The same container is shipped to production.
- Client The client makes a request over port 443 to the refactor proxy URL.
- Elastic Load Balancer (ELB) AWS Copilot creates an ELB and registers the monolith to the target group.
- 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.
- ⏱ Time to complete: 30 minutes
1
2
cd ./amazon-ecs-nodejs-microservices/
copilot app init
1
2
3
4
5
6
Application name: monolith
✔ Proposing infrastructure changes for stack monolith-infrastructure-roles
- Creating the infrastructure for stack monolith-infrastructure-roles [create complete] [46.2s]
- A StackSet admin role assumed by CloudFormation to manage regional stacks [create complete] [18.9s]
- An IAM role assumed by the admin role to create ECR repositories, KMS keys, and S3 buckets [create complete] [20.5s]
✔ The directory copilot will hold service manifests for application monolith.
copilot env init
and choose profile default
. Name the Environment monolith
.1
2
3
4
5
6
7
$ copilot env init
Environment name: monolith
Which credentials would you like **to** use **to** create api? [Use
arrows **to** move, type **to** filter, ? **for** more help]
Enter temporary credentials
> [profile default]
Yes, use default
.1
2
3
4
5
6
7
8
9
10
11
Environment name: monolith
Credential source: [profile default]
Would you like to use the default configuration for a new environment?
- A new VPC with 2 AZs, 2 public subnets and 2 private subnets
- A new ECS Cluster
- New IAM Roles to manage services and jobs in your environment
[Use arrows to move, type to filter]
> Yes, use default.
Yes, but I'd like configure the default resources (CIDR ranges, AZs).
No, I'd like to import existing resources (VPC, subnets).
manifest.yml
that is used to configure the environment. Once the creation is done, you should see similar output to this:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Environment name: monolith
Credential source: [profile default]
Default environment configuration? Yes, use default.
✔ Wrote the manifest for environment api at copilot/environments/api/manifest.yml
- Update regional resources with stack set "api-infrastructure" [succeeded] [0.0s]
- Update regional resources with stack set "api-infrastructure" [succeeded] [130.8s]
- Update resources in region "us-east-1" [create complete] [130.4s]
- ECR container image repository for "monolith" [create complete] [2.5s]
- KMS key to encrypt pipeline artifacts between stages [create complete] [124.5s]
- S3 Bucket to store local artifacts [create complete] [2.4s]
✔ Proposing infrastructure changes for the api-api environment.
- Creating the infrastructure for the api-api environment. [create complete] [56.0s]
- An IAM Role for AWS CloudFormation to manage resources [create complete] [22.4s]
- An IAM Role to describe resources in your environment [create complete] [25.0s]
✔ Provisioned bootstrap resources for environment api in region us-east-1 under application api.
copilot env deploy --name monolith
in the terminal.1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ copilot env deploy --name monolith
✔ Proposing infrastructure changes for the api-api environment.
- Creating the infrastructure for the api-api environment. [update complete] [78.3s]
- An ECS cluster to group your services [create complete] [7.5s]
- A security group to allow your containers to talk to each other [create complete] [1.4s]
- An Internet Gateway to connect to the public internet [create complete] [16.0s]
- Private subnet 1 for resources with no internet access [create complete] [1.7s]
- Private subnet 2 for resources with no internet access [create complete] [1.7s]
- A custom route table that directs network traffic for the public subnets [create complete] [10.9s]
- Public subnet 1 for resources that can access the internet [create complete] [3.1s]
- Public subnet 2 for resources that can access the internet [create complete] [6.0s]
- A private DNS namespace for discovering services within the environment [create complete] [46.3s]
- A Virtual Private Cloud to control networking of your AWS resources [create complete] [11.6s]
copilot svc init
and choose Load Balanced Web Service
.1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ copilot svc init
Note: It's recommended to run this command in the root of your Git repository.
Welcome to the Copilot CLI! We're going to walk you through some questions
to help you get set up with a containerized application on AWS. An application is a collection of
containerized services that operate together.
Which workload type represents your architecture? [Use arrows to move, type to filter, ? for more help]
Request-Driven Web Service (App Runner)
> Load Balanced Web Service (Internet to ECS on Fargate)
Backend Service (ECS on Fargate)
Worker Service (Events to SQS to ECS on Fargate)
Scheduled Job (Scheduled event to State Machine to Fargate)
monolith
.1
2
3
4
5
6
7
8
9
10
11
Workload type: Load Balanced Web Service
What do you want to name this service? [? for help] monolith
Choose Enter custom path for your Dockerfile.
Workload type: Load Balanced Web Service
Service name: monolith
Which Dockerfile would you like to use for monolith? [Use arrows to move, type to filter, ? for more help]
> Enter custom path for your Dockerfile
2-containerized/services/api/Dockerfile
1
2
3
4
5
6
Service type: Load Balanced Web Service
Service name: monolith
Dockerfile: Enter custom path for your Dockerfile
Dockerfile: 2-containerized/services/api/Dockerfile
✔ Wrote the manifest for service monolith at copilot/monolith/manifest.yml
./amazon-ecs-nodejs-microservices/copilot/monolith
and examine manifest.yml
to see how the service is configured. Note that the parameter http
defines the path for the app. The Node.js application, server.js
, defines the base route as /
.1
2
3
4
5
6
7
8
9
10
11
12
13
14
The manifest for the "monolith" service.
Read the full specification for the "Load Balanced Web Service" type at:
https://aws.github.io/copilot-cli/docs/manifest/lb-web-service/
Your service name will be used in naming your resources like log groups, ECS services, etc.
name: monolith
type: Load Balanced Web Service
Distribute traffic to your service.
http:
# Requests to this path will be forwarded to your service.
# To match all requests you can use the "/" path.
path: '/'
# You can specify a custom health check path. The default is "/".
# healthcheck: '/'
copilot svc deploy --name monolith
in the terminal. When you deploy the service, the container is built locally by Docker and pushed to your Elastic Container Registry. The service pulls the container from the registry and deploys it in the environment. The monolith
application is running when the deployment is complete.1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
$ copilot svc deploy --name monolith
Only found one service, defaulting to: monolith
Only found one environment, defaulting to: monolith
Building your container image: docker build -t 837028011264.dkr.ecr.us-east-1.amazonaws.com/api/monolith --platform linux/x86_64 /Users/sparaaws/github/spara/amazon-ecs-nodejs-microservices/2-containerized/services/api -f /Users/sparaaws/github/spara/amazon-ecs-nodejs-microservices/2-containerized/services/api/Dockerfile
[+] Building 43.3s (10/10) FINISHED
=> [internal] load build definition from Dockerfile 0.0s
=> => 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 5.6s
=> [auth] mhart/alpine-node:pull token for registry-1.docker.io 0.0s
=> [internal] load build context 0.0s
=> => transferring context: 392B 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
=> [3/4] ADD . . 0.0s
=> [4/4] RUN npm install 37.1s
=> exporting to image 0.3s
=> => exporting layers 0.2s
=> => writing image sha256:26ea1872922a12bd3a297c2dd003d1fc71de93e0e5895d2264acca4db3963fbb 0.0s
=> => naming to 837028011264.dkr.ecr.us-east-1.amazonaws.com/api/monolith 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/monolith]
bc590299ddf7: Pushed
947736d9bac9: Pushed
5f70bf18a086: Pushed
3e893534526a: Pushed
040fd7841192: Pushed
latest: digest: sha256:721adc83096c12f21d61bb73d7ea6d296269cce607178676492aaa1f6cdad6bc size: 1365
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
✔ Proposing infrastructure changes for stack api-api-monolith
- Creating the infrastructure for stack api-api-monolith [create complete] [360.8s]
- Service discovery for your services to communicate within the VPC [create complete] [0.0s]
- Update your environment's shared resources [update complete] [149.9s]
- A security group for your load balancer allowing HTTP traffic [create complete] [5.9s]
- An Application Load Balancer to distribute public traffic to your services [create complete] [123.0s]
- A load balancer listener to route HTTP traffic [create in progress] [198.5s]
- An IAM role to update your environment stack [create complete] [23.5s]
- An IAM Role for the Fargate agent to make AWS API calls on your behalf [create complete] [19.9s]
- A HTTP listener rule for forwarding HTTP traffic [create complete] [3.5s]
- A custom resource assigning priority for HTTP listener rules [create complete] [5.1s]
- A CloudWatch log group to hold your service logs [create complete] [1.5s]
- An IAM Role to describe load balancer rules for assigning a priority [create complete] [23.5s]
- An ECS service to run and maintain your tasks in the environment cluster [create complete] [117.0s]
Deployments
Revision Rollout Desired Running Failed Pending
PRIMARY 1 [completed] 1 1 0 0
- A target group to connect the load balancer to your service [create complete] [15.0s]
- 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] [23.5s]
✔ Deployed service monolith.
Recommended follow-up action:
- You can access your service at http://api-a-Publi-DU44D9VOSXLA-792918025.us-east-1.elb.amazonaws.com over the internet.
1
{"id":3,"username":"pb","name":"Bonnibel Bubblegum","bio":"Scientist, bearer of candy power, ruler of the candy kingdom"}
1
{"id":2,"title":"Party at the candy kingdom tomorrow","createdBy":3}
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},{"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}]
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}]
- Reducing the time to set up a refactor environment.
- Reducing the complexity for iteratively extracting capabilities as new microservices and re-routing traffic.
- Simplifying management of existing apps and microservices as a single application with flexible routing control, isolation, and centralized management.
- Helping dev teams achieve and accelerate tech and deployment independence by simplifying development, management, and operations while apps are changing.
- Simplifies refactoring to multiple AWS accounts. Refer to the following architecture reference for additional details.
- Client The client makes a request over port 443 to the refactor proxy URL.
- AWS Migration Hub Refactor Spaces Refactor Spaces provides an application that models the Strangler Fig pattern for incremental refactoring.
- Elastic Load Balancer (ELB) AWS Copilot creates an ELB and registers the monolith to the target group.
- 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.
- ⏱ Time to complete: 30 minutes
rs.yaml
and rs-service-op.yaml
files into the repository that you downloaded in Module 1. You can also do this with curl
/ Invoke-WebRequest
without cloning the whole repository:1
2
curl -O https://raw.githubusercontent.com/aws-samples/aws-migration-hub-refactor-spaces-samples/main/rs-tutorial/rs-copilot-tutorial/rs-service-op.yaml
curl -O https://raw.githubusercontent.com/aws-samples/aws-migration-hub-refactor-spaces-samples/main/rs-tutorial/rs-copilot-tutorial/rs.yaml
- Run the following command at the root directory for this project to deploy a refactor environment. Replace the
<<Stack Name>>
with a name of your choice, and<<MonolithUrl>>
with the Copilot CLI output from the last module with/api
appended since the monolith listens on the/api
. For example,[http://api-m-Publi-5SPO2C-558916521.us-east-1.elb.amazonaws.com/api](http://api-m-Publi-5SPOLPJTUB2C-558916521.us-east-1.elb.amazonaws.com/api)
1
aws cloudformation deploy --template-file rs.yaml --stack-name <<Stack Name>> --parameter-override MonolithUrl=<<MonolithUrl>>
1
2
3
4
o6rvhiz-1055935381.us-west-2.elb.amazonaws.com/api
Waiting for changeset to be created..
Waiting for stack create/update to complete
Successfully created/updated stack - monolith-tutorial
.1
aws cloudformation describe-stacks --stack-name <<Stack Name>> --query "Stacks[].Outputs"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
[
[
{
"OutputKey": "rsProxyURL",
"OutputValue": "https://zx8lisag1a.execute-api.us-east-1.amazonaws.com/prod",
"Description": "The API Gateway Proxy URL for the Refactor Spaces Application"
},
{
"OutputKey": "VPCId",
"OutputValue": "vpc-05d73902a4d92",
"Description": "The ID of the VPC that this stack is deployed in"
},
{
"OutputKey": "appId",
"OutputValue": "env-xA8QIyk4|app-1b8Omyo2",
"Description": "The ID of Refactor Spaces App"
},
{
"OutputKey": "envId",
"OutputValue": "env-xA8QIyk4",
"Description": "The ID of Refactor Spaces Env"
},
{
"OutputKey": "rsServiceId",
"OutputValue": "svc-3yXgDEnW9",
"Description": "The ID of Refactor Spaces Monolith"
}
]
]
rsProxyURL
value from the output above, append /users
, or /threads
, or /posts
and paste into a web browser. The following screenshot is from Firefox optimized to see JSON format.- Client The client makes traffic requests over port 80.
- Load Balancer The Application Load Balancer routes external traffic to the correct service. The Application Load Balancer inspects the client request and uses routing rules to direct the request to an instance and port for the target group.
- Target Groups Each service has a target group that tracks the instances and ports of each container running for that service.
- Microservices Amazon ECS deploys each service into a container across an EC2 cluster. Each container only handles a single feature.
- ⏱ Time to complete: 20 minutes
api
Application. You can reuse the application to deploy new environments for the microservices. In this module, the code for the application has been divided into three microservices: posts, threads, and users. Each one will be deployed as a service in a new environment. The monolith
environment and service was deployed using the CLI menu. In this module, you can deploy services by specifying the flags for the copilot env init
command. Create the posts
microservice first.1
2
3
4
5
6
7
8
9
10
$ copilot env init --name posts --profile default
Would you like to use the default configuration for a new environment?
- A new VPC with 2 AZs, 2 public subnets and 2 private subnets
- A new ECS Cluster
- New IAM Roles to manage services and jobs in your environment
[Use arrows to move, type to filter]
> Yes, use default.
Yes, but I'd like configure the default resources (CIDR ranges, AZs).
No, I'd like to import existing resources (VPC, subnets).
Yes, use default
.1
2
3
4
5
6
7
8
9
10
11
Default environment configuration? Yes, use default.
✔ Wrote the manifest for environment posts at copilot/environments/posts/manifest.yml
- Update regional resources with stack set "api-infrastructure" [succeeded] [10.7s]
✔ Proposing infrastructure changes for the api-posts environment.
- Creating the infrastructure for the api-posts environment. [create complete] [35.5s]
- An IAM Role for AWS CloudFormation to manage resources [create complete] [14.3s]
- An IAM Role to describe resources in your environment [create complete] [15.2s]
✔ Provisioned bootstrap resources for environment posts in region us-east-1 under application api.
Recommended follow-up actions:
- Update your manifest copilot/environments/posts/manifest.yml to change the defaults.
- Run `copilot env deploy --name posts` to deploy your environment.
copilot env deploy —-name posts
, you will see similar output to this:1
2
3
4
5
6
7
8
9
10
11
12
✔ Proposing infrastructure changes for the api-posts environment.
- Creating the infrastructure for the api-posts environment. [update complete] [74.2s]
- An ECS cluster to group your services [create complete] [2.7s]
- A security group to allow your containers to talk to each other [create complete] [4.1s]
- An Internet Gateway to connect to the public internet [create complete] [14.4s]
- Private subnet 1 for resources with no internet access [create complete] [1.3s]
- Private subnet 2 for resources with no internet access [create complete] [1.3s]
- A custom route table that directs network traffic for the public subnets [create complete] [8.6s]
- Public subnet 1 for resources that can access the internet [create complete] [1.3s]
- Public subnet 2 for resources that can access the internet [create complete] [1.3s]
- A private DNS namespace for discovering services within the environment [create complete] [48.9s]
- A Virtual Private Cloud to control networking of your AWS resources [create complete] [12.8s]
users
, threads
environments.1
2
3
4
5
6
7
copilot env init --name users
copilot env deploy --name users
copilot env init --name threads
copilot env deploy --name threads
Posts
using the flags.1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ copilot svc init --name posts --app api --dockerfile 3-microservices/services/posts/Dockerfile --svc-type "Load Balanced Web Service"
Note: It's best to run this command in the root of your workspace.
Note: Architecture type arm64 has been detected. We will set platform 'linux/x86_64' instead. If you'd rather build and run as architecture type arm64, please change the 'platform' field in your workload manifest to 'linux/arm64'.
✔ Wrote the manifest for service posts at copilot/posts/manifest.yml
Your manifest contains configurations like your container size and port (:3000).
- Update regional resources with stack set "api-infrastructure" [succeeded] [9.1s]
- Update resources in region "us-east-1" [update complete] [6.8s]
- ECR container image repository for "posts" [create complete] [4.1s]
Recommended follow-up actions:
- Update your manifest copilot/posts/manifest.yml to change the defaults.
- Run `copilot svc deploy --name posts --env test` to deploy your service to a test environment.
users
, threads
microservices.1
2
3
copilot svc init --app api --dockerfile 3-microservices/services/users/Dockerfile --name users --svc-type "Load Balanced Web Service"
copilot svc init --app api --dockerfile 3-microservices/services/threads/Dockerfile --name threads --svc-type "Load Balanced Web Service"
server.js
is api/<<service name>>
. Edit the path in each microservice manifest, and add api/
to the path.1
2
3
4
5
# Distribute traffic to your service.
http:
# Requests to this path will be forwarded to your service.
# To match all requests you can use the "/" path.
path: 'api/posts'
- Switch the Traffic This is the starting configuration. The monolithic Node.js app running in a container on Amazon ECS.
- Deploy Microservices Using the three container images built and pushed to Amazon ECR by AWS Copilot, you will deploy three microservices.
- Register with Refactor Spaces Register the microservices' load balancer DNS with Refactor Spaces to route traffic from the monolith transparently.
- Shut down the Monolith Shut down the monolith by deleting the Copilot environment. Refactor Spaces routes traffic to the running microservices for the respective endpoints.
- ⏱ Time to complete: 20 minutes
copilot svc deploy --name <microservice> --env <microservice>
. Similar to the monolith service
, AWS Copilot builds a container for the microservice, pushes to a repository, and deploys on an Amazon ECS cluster running on Fargate.1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
$ copilot svc deploy --name posts --env posts
Building your container image: docker build -t 929897017989.dkr.ecr.us-east-1.amazonaws.com/api/posts:latest --platform linux/x86_64 --label com.aws.copilot.image.builder=copilot-cli --label com.aws.copilot.image.container.name=posts --label com.aws.copilot.image.version=v1.27.0 /Users/theheman/Library/CloudStorage/WorkDocsDrive-Documents/Downloads/amazon-ecs-nodejs-microservices-master/3-microservices/services/posts -f /Users/theheman/Library/CloudStorage/WorkDocsDrive-Documents/Downloads/amazon-ecs-nodejs-microservices-master/3-microservices/services/posts/Dockerfile
[+] Building 16.5s (9/9) FINISHED docker:desktop-linux
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 238B 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.2s
=> [1/4] FROM docker.io/mhart/alpine-node:7.10.1@sha256:d334920c966d440676ce9d1e6162ab544349e4a4359c517300391c877bcffb8c 0.0s
=> [internal] load build context 0.0s
=> => transferring context: 617B 0.0s
=> CACHED [2/4] WORKDIR /srv 0.0s
=> [3/4] ADD . . 0.0s
=> [4/4] RUN npm install 15.2s
=> exporting to image 0.0s
=> => exporting layers 0.0s
=> => writing image sha256:c31c780560d4ab8e347fac4671e56731ee5dd1065936a4bfbf5f161bf633fed3 0.0s
=> => naming to 929897017989.dkr.ecr.us-east-1.amazonaws.com/api/posts:latest 0.0s
What's Next?
View summary of image vulnerabilities and recommendations → docker scout quickview
Login Succeeded
The push refers to repository [929897017989.dkr.ecr.us-east-1.amazonaws.com/api/posts]
1ea095e3a223: Pushed
9918c01046a5: Pushed
5f70bf18a086: Pushed
3e893534526a: Pushed
040fd7841192: Pushed
latest: digest: sha256:fbf6aa25561868de53b06421b68350561d36f3dfe230e5ed51189f6262bbf60a size: 1365
✔ Proposing infrastructure changes for stack api-posts-posts
- Creating the infrastructure for stack api-posts-posts [create complete] [370.0s]
- Service discovery for your services to communicate within the VPC [create complete] [2.5s]
- Update your environment's shared resources [update complete] [146.1s]
- A security group for your load balancer allowing HTTP traffic [create complete] [3.8s]
- An Application Load Balancer to distribute public traffic to your services [create complete] [123.4s]
- A load balancer listener to route HTTP traffic [create in progress] [197.9s]
- An IAM role to update your environment stack [create complete] [13.0s]
- An IAM Role for the Fargate agent to make AWS API calls on your behalf [create complete] [13.0s]
- An HTTP listener rule for path `posts` that forwards HTTP traffic to your tasks [create complete] [1.3s]
- A custom resource assigning priority for HTTP listener rules [create complete] [3.7s]
- A CloudWatch log group to hold your service logs [create complete] [0.0s]
- An IAM Role to describe load balancer rules for assigning a priority [create complete] [13.0s]
- An ECS service to run and maintain your tasks in the environment cluster [create complete] [163.7s]
Deployments
Revision Rollout Desired Running Failed Pending
PRIMARY 1 [completed] 1 1 0 0
- A target group to connect the load balancer to your service on port 3000 [create complete] [15.8s]
- 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] [15.9s]
✔ Deployed service posts.
Recommended follow-up action:
- You can access your service at http://api-p-Publi-YINASE2asgfadgYW-659747790.us-east-1.elb.amazonaws.com/posts over the internet.
Users
and Threads
microservices1
2
copilot svc deploy --name threads --env threads
copilot svc deploy --name users --env users
- To register service and create a route in Refactor Spaces, replace the
ApplicationID
andEnvironmentId
parameters with appropriate values from the output of Module 3. Then pass theApplication Load Balancer URLs
for all three services from the Copilot commands in the previous step. - This command registers all three microservices deployed previously and registers them as services with Refactor Spaces.
1
2
3
4
5
aws cloudformation deploy \
--template-file rs-service.yaml \
--stack-name <<stackname>>
--parameter-override EnvironmentId=<<14 digit envID env-xxxxxxxxxx>> ApplicationID=<<14 digit appId app-xxxxxxxxxx>> PostsUrl=http://<<PostsUrl>>.elb.amazonaws.com UsersUrl=http://<<UsersUrl>>.elb.amazonaws.com ThreadsUrl=http://<<ThreadsUrl>>.elb.amazonaws.com \
--output table
monolith
Service. Enter copilot svc delete --name monolith
in the terminal.1
2
3
4
5
6
7
8
9
10
$ copilot svc delete --name monolith
Sure? Yes
✔ Delete stack api-monolith-monolith
- Update regional resources with stack set "api-infrastructure" [succeeded] [8.7s]
- Update resources in region "us-east-1" [update complete] [8.5s]
✔ Deleted service monolith from application api.
Recommended follow-up action:
- Run `copilot pipeline deploy` to update the corresponding pipeline if it exists.
- ⏱ Time to complete: 20 minutes
1
copilot app delete --name api
<<stackname>>
to the following command.1
aws cloudformation delete-stack --stack-name <<stackname>>
Any opinions in this post are those of the individual author and may not reflect the opinions of AWS.