Dockerizing and Deploying a .NET Core Application to AWS ECS Fargate
In this post I’m going to explain how we can dockerize a dotnet core application and deploy it to AWS ECS Fargate.
First things first,
As a starting point it might be good to know what is Docker and what does a container mean.
If you are already familiar with those please just scroll down 😀
If not please take a look at my previous post Docker 101 from here.
The main question you should ask is what AWS ECS service is?
AWS ECS (Amazon Elastic Container Service) is a highly scalable, high-performance container orchestration service that supports Docker containers and allows you to easily run and scale containerized applications on AWS.
Sounds great, right? But what does that mean?
It’s easy; when you want to run an application inside a Docker container, you mainly need an environment which is the servers in most cases. Sounds cool but how can we manage containers in those servers? Yes! This is the right question to ask. AWS gives you ECS to help you manage/orchestrate your containers.
(Please be advised that another orchestration system is mighty Kubernetes aka k8s and AWS service that supports k8s is EKS which I’ll write a separate blog for it.)
All good but what is Fargate? The answer is one step further! Truly serverless! Oh sounds interesting isn’t it? Do you remember I’ve told you need a server to run the containers? Now with Fargate you actually don’t need a single server! AWS handles everything for you!
If you are interested in serverless or want to learn more about it, please be patient, there will be another post for it 😉
Let’s start to talk about ECS.
First of all you need a Dockerfile so you can tell Docker daemon how to create the Docker image.
After creating the Docker image we need to register it to a repository. It can be Docker Hub, Amazon ECR or even your private repository.
After registering the image with the repository we need to create a service and task definition.
A service is basically our application in ECS world. You need to define the service. It can be a service that will be ready to response any time (like web applications) or it can be an application that needs to be ran only once or we can set a schedule to run on specific times.
Deployment types for ECS
The task definition is the parameters for ECS to do the orchestration.
We can define the vCPU and memory amount here. How many tasks we want? Also we can define environment variables for our application.
When you create an EC2 Cluster, ECS spins up some EC2 instances so it can use them for orchestrating. But if you select Fargate, you will have no idea about any server. Truly serverless!
Comparison of EC2 and Fargate Clusters
The orange boxes on the left side of the image above are EC2 instances. ECS puts some information to the user data so it knows which instances are belong to which cluster. ECS distributes tasks (actually containers that have our application) to the instances. But as you can see on the right hand side, there are no EC2 instances just service and tasks. We don not need to think about virtual servers maintaining. In Fargate you will be billed per vCPU per second and per GB memory per second. With the classical saying you will pay what you use!
Now it’s time to explain how we can deploy a dotnet core application. Microsoft likes providing developer-friendly tools 😀
We can easily prepare our dotnet core application by using “Add Docker Support” option for containerization. Thanks Microsoft!
This option actually adds a Dockerfile and docker-compose files to the solution.
Please take a moment to read the sample Dockerfile. It is very simple. It uses aspnetcore:2.0 image to build & run the application, copies the solution and project files to the image, restores the packages, build the code and publishes the artifacts. Lastly creates and entrypoint which is running dotnet command with StarWars.dll argument.
When you run the application locally. Visual Studio automatically builds the image using the Dockerfile and docker-compose files. You can check the image using ‘docker images’ command on command line. You can also check the container with ‘docker ps’ command on command line.
Before moving on let’s create a cluster so we can deploy our application.
Step 1 is the place where we need to make a choice. Do we want to manage EC2 servers or do we want to go on fully serverless. Networking only option is the Fargate option (serverless) If you choose EC2 Linux or EC2 Windows, ECS will create EC2 instances to orchastrate the containers. Of course these options have a maintaining cost to us. So let’s move on with the Fargate.
We need to give our cluster a name and select our VPC in the next section. This is a very fast process to create the cluster. Be careful if you go with the EC2 clusters it will take some time to spin up EC2 instances.
Now we are ready to deploy our application from Visual Studio. We need to install AWS Toolkit for Visual Studio to be able to deploy our application using Visual Studio.
You can download the toolkit from this link.
Actually the best practice is creating a pipeline to do the deployment automatically but this is out of topic for now. Will be in the next posts as well 😀
We can right click to project that we want to deploy and choose “Publish Container to AWS” option.
First step is the selecting the AWS Region, build configuration (Debug/Release), image tag and deployment type.
We need to specify the cluster, vCPU, memory, subnet and security group options here in the launch configuration.
Then we need to define our service. Here we can select an existing service but now we are deploying for the first time because of that let ECS to create a new service for us. We also can define the number of tasks (for high-availability we have to set more than 1)
Minimum Healthy Percentage means at least that percentage of tasks have to be healthy so ECS can consider the service as healthy.
Maximum Percent means that at most that percentage of tasks can run at the same time.
As a best practice we need to create an load balancer. ECS uses Application Load Balancer (ALB) for containerized applications.
Last step is the creating the task definition. Security is everything for AWS, because if that we have to set some roles so ECS can execute necessary actions on your account.
When you click “Publish” Visual Studio will create the image register is to ECR, create the service & definition and run the application.
This is all we need to do to dockerize our dotnetcore application and deploy it to the AWS ECS Fargate.
As I told before deployment should be handled by a pipeline so it can be done automatically. Using AWS Console and Visual Studio tools are good for learning and testing but in production everything must be tested and automated.
You can check our web pages for detailed information as well;
If you have any questions please do not hesitate to ask.
Onur is a software developer & architect for 17+ years and has been working with AWS professionally for 5 years.