Deploying Asp.net core Microservices in AWS ECS using Fargate -Part I

In recent years Microservices got lot of popularity and most of the systems are adopting this new architecture to develop Line of business applications. However Microservices might not be a single solution for everyone or every problem. Let’s say if you got independent team to build and mange independent modules in your system, then it might be an ideal approach Having said that , it could be a better architecture even for single team projects to develop complex distributed applications and deploy it in any cloud environment.

You can find good resources to learn more about Microservices here. https://microservices.io

In this series I am going to take you a ride, how to deploy dotnet core Microservices in AWS using ECS Fargate. I love serverless frameworks. Fargate has come to help us deploy apps into Containers without require us to maintain Host machine.

Prerequisites

  • I am assuming you have already worked with ASP.Net core apps.
  • Also got some basic understanding of AWS services such as EC2, ECS, ELB, ECR, IAM and AWS configuration.
  • Dotnet core SDK, AWS CLI, Docker and Visual studio code or any IDE should be installed in the development machine.

Application Architecture

  • I created one application for Vehicle insurance use case. Any client can make REST calls to Metadata service to create/update customer , vehicles information and requests for vehicle insurance quotations . Quote will be generated on server and sent back to clients. Once your picks a quote, client should call policy service to process and create policy .
  • I created two simple ASP.Net core webapi projects for these services, one to mange basic info like customer, vehicle and quotes . And other one to manage policies.
  • Each service will interact with its own database to make these service purely independent.
  • Data between these databases can be synced or changed using Event patterns , which will be out of scope for this demo.

AWS Infrastructure Architecture

We will deploy this simple micro-services to AWS ECS cluster using fargate.

  • Every request from clients can come to a single Application load balancer and then the request will be forward to respective target groups by matching URL pattern.
  • Idea is to create a unique Target group for each service, so that they will forward the requests to service Containers, that are launched in ECS cluster using Fargate.
  • APIs running in ECS containers should be able to communicate with database services such as SQL Server RDS , Elasticache and DynamoDB in the same VPC.

Readiness of Asp.Net Core WebAPI

Lets first understand the necessary parts in ASP.Net Core webapi services to be able to deploy in ECS cluster.

  1. All lookup data and session related data should be stored in a single instance redis cache or some common database, so that all service instances should be able to access data from single repository.
services.AddStackExchangeRedisCache(options =>
{
options.Configuration = Configuration["Cache:AWSRedisEndPoint"];
});

2. Every service should have a health check route configured, to check service is running in container from ELB. I used built in middle ware to configure this.

//this line in ConfigureServices method of Startup.cs
services.AddHealthChecks();
//this line in Configure method of Startup.cs
app.UseHealthChecks(“/health”);

3. All routes in a service should have a common base route path, so that requests from ELB should be able to send to this service target group by matching the base route path.

[Route(“metadataapi/[controller]”)]
public class CustomersController : ControllerBase
[Route(“metadataapi/[controller]”)]
public class VehiclesController : ControllerBase

4. I used swagger for API discovery documentation. This swagger configuration should also consider using base route path.

app.UseSwagger(c =>
{
c.RouteTemplate=”policyapi/swagger/{documentName}/swagger.json”;\
});
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint(“/policyapi/swagger/v1/swagger.json”,”APIdoc”);
c.RoutePrefix = “policyapi/swagger”;
});

Docker Image to run container on ECS

  • Docker is a plotform to create and deploy application containers on Host machine. If you have not worked on Docker earlier, please consider going through some basics. I loved this pluralsight corce.
  • I created docker file for each service with basic instructions to build API image.
  • Also created a docker-compose file to build and run these containers in local host machine.
  • You will require to create a .env file setup environment varibles to service
  • Build and run images in containers by using this command in terminal
docker-compose up -d --build
aws ecr create-repository --repository-name metadata-api
  • You can also create repository by logging into AWS ECR console.
  • Tag running service images with ECR repository URIs with
docker tag metadataapi:latest
875373411184.dkr.ecr.us-west1.amazonaws.com/insurancemetadata:latest
  • Login to ECR to push this mage to cloud . We need to run this command to generate login command.
aws ecr get-login --no-include-email --region us-west-2
  • Copy and paste the output from above command in the terminal to perform actual login.
  • Once the login successfully. Push these service images to Cloud
docker push 
875373411184.dkr.ecr.us-west-1.amazonaws.com/insurancemetadata

Deploy Service Images in ECS Cluster using Cloudformation.

Once docker images are pushed to ECR repository, then we can deploy the services using the following two cloud-formation templates.

  • First one to create common resources like Load balancer, secutirygroups and Cluster.
  • Second one to configure service in containers using Fargate and also creates necessary IAM roles, target groups, Task definition and ECS Service.

We need create one stack for each service in our application by passing necessary parameters.

  • You can use either AWS console to create stacks for these cloudformation templates or execute them from command line.
aws cloudformation deploy --template-file /path_to_template/microservice-cluster-elb.yaml 
--stack-name my-new-stack
--parameter-overrides EnvironmentName=mycluster vpcid=<vpcid> ...
  • Once the first stack completed successfully, we need to create stack for each service. This time, we need to find output from first stack to pass to the service stack like elbruleid, securitygroupname and clustername.
  • Before creating service, make sure all necessary environment varibles are defined in the template.
  • Once the second stack created , you can find the ELB load balancer DNS entry in AWS console.
  • Browse each service swagger url to make sure apis are deployed sucussfully.
  • These cloud-formation templates are reusable for CI/CD tool integration as well.
  • Other option to deploy these microservices is to use AWS Web console. Please visit next part of this article to understand each AWS service.

Refferences: