When you deploy microservices on to ECS, handling internal communication between containers is a challenging task. However, AWS has provided few options to address this concern such as using service discovery, internal load balancer, or using a service mesh.
In this article, I will show you how we can use an internal load balancer for handling the communication between containers in a VPC. This example uses ECS Fargate for running the containers.
Note that I use AWS CDK for creating all the resources in this example.
Architecture
As shown in the above diagram, we have three microservices running in the VPC. Accounts and Customers containers run in private subnets. Frontend app containers run in public subnets. These services communicate with each other using REST endpoints.
Example Scenario
The frontend-app wants to display customer information with their account information. When the app calls the customer-service API, that request flows to the downstream services as follows.
- Frontend App calls the customer-service API /customers/{customerId}.
- customer-service calls the account-service API /accounts/{customerId} to get account information.
customer-service returns the below response back to the frontend-app.
Steps
- Setup ECR with docker images
- Setup VPC
- Setup ECS cluster
- Setup internet-facing load balancer
- Setup internal load balancer
- Setup ECS services and register with load balancers
- Setup a user friendly URL in Route 53
- Running the project
You can find the complete project from this link.
Setup ECR with Docker Images
In this example, I use Amazon Elastic Container Registry (ECR) as the docker container registry for our services. The following code creates the repository in ECR.
Once you created the repositories, you have to build and push the docker images to the repositories. You can follow the below commands for that.
Login to ECR
aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin <your AWS account no>.dkr.ecr.us-east-1.amazonaws.com
Build your Docker image
docker build -t account-service .
Tag the Docker image
docker tag account-service:latest <your AWS account no>.dkr.ecr.us-east-1.amazonaws.com/account-service:latest
Push the Docker image
docker push <your AWS account no>.dkr.ecr.us-east-1.amazonaws.com/account-service:latest
Setup VPC
In this step, I create a VPC with two public and private subnets. Since resources in the private subnet need to communicate with the outside, we need to add a NAT Gateway or NAT instance into the public subnet.
By default, AWS CDK adds a NAT Gateway in each public subnet. NAT Gateway will cost you some dollars, so don’t forget to delete the stack after testing.
Setup ECS Cluster
Setup Internet-Facing Load Balancer
In this step, we create the Internet-Facing load balancer for routing traffic from users to the Frontend app.
Setup Internal Load Balancer
In this step, we create the internal load balancer for inter-communication between services in the VPC. Services can call respective REST endpoints via the internal load balancer.
Setup ECS Services and Register with Internal Load Balancer
In this step, we create the ECS services and register them with an internal load balancer. I have used a config object to keep all the required parameters for ECS tasks, services, and load balancer configurations.
Configuration Object
Setup a User Friendly URL in Route 53
It’s good to have a friendly URL instead of using the internal load balancer URL for calling REST endpoints. We can you Route 53 for creating an alias record that points to the internal load balancer.
As shown in the below code, zoneName is the internal URL that services use to call API. For example,
http://service.internal/customers/1
Complete Code
Running the Project
You can clone the complete code from here. Go to the root folder of the project and run the following commands.
npm run build
cdk deploy
References
https://docs.aws.amazon.com/AmazonECS/latest/bestpracticesguide/networking-connecting-services.html
https://docs.aws.amazon.com/AmazonECS/latest/developerguide/service-load-balancing.html
https://docs.aws.amazon.com/cdk/v2/guide/ecs_example.html
https://docs.aws.amazon.com/cdk/api/v1/docs/aws-ecs-patterns-readme.html
https://docs.aws.amazon.com/AmazonECR/latest/userguide/getting-started-cli.html