Simple DotNet Core API with AWS ECS Fargate using Terraform
AWS Fargate is a serverless compute engine for containers that work with both Amazon Elastic Container Service (ECS) and Amazon Elastic Kubernetes Service (EKS). Fargate makes it easy for you to focus on building your applications. Fargate removes the need to provision and manage servers, lets you specify and pay for resources per application, and improves security through application isolation by design. (refer)
In this article, we will use Terraform to provision DotNet container API to ECS using Fargate Launch Type. To make things simpler, I remove all the optional attributes; only fill in the required attribute that helps us to deploy into ECS using Fargate. If you are interested in the details of implementation, feel free to refer here.
To get started, we will need to plan what we need for these stacks.
A basic API in AWS Fargate requires the following component:-
- Application Load Balancer: To accept public request and route to your sample-service
- ECS Cluster: To manage all your Fargate service
- ECR: To store your image artifact
- Sample-Service: Your application run in ECS Service with Fargate launch type
Pre-requsites
In order to follow the setup, you require the following:-
- AWS Account With Access Key, Secret Key ready
- Docker desktop installed
- Visual Studio Code installed (Optional)
- Makefile tool installed
We will run and test everything in docker environment and all the commands to refer to the Makefile. Although this project runs in Mac environment, but it is possible to make minimal changes to Makefile to run in Window environment.
Environment Setup
To make environment identical to everyone, we will use docker to run and test our project. We also use makefile to store all the command we need.
Makefile setup
Create new folder and create Makefile as below:-
Makefile will keep all the commands to build our lab environment, create DotNet project, plan, apply and kill terraform state.
Setup Lab Environment in docker
Create a Dockerfile in root project with the following content so we can create our lab environment in docker:-
We will use aws-cli image as base image, and include terraform and dotnet dependencies.
Run make lab
command in the root project to build lab image as below:-
Run make login-lab
to build docker lab environment, and you should run with interactive mode.
Create Sample Project
In the same docker interactive terminal, run make sample-project
in root folder, and a new webapi project will create inside src/SampleApi
as below:-
Test run your API
Run make run-project
command to test your api, and you will able to trigger it from localhost:5000/WeatherForecast
.
Add healthcheck support to API Project
Application Load Balancer requires destination ECR Service to have healthcheck endpoint in order to understand your service health. Add services.AddHealthChecks()
in ConfigureServices
, and app.UseHealthCheck("/")
in Configure
section in Startup.cs
file as below:-
Dockerize Your API Project
Add new Dockerfile into src/SampleApi
folder with the following content:-
Push image to ECR
Now that we have our DotNet API project ready, it is time to create image and push to our ECR.
Setup AWS CLI Credential
In your interactive terminal, run aws configure
to setup your AWS Credential. Alternatively, you can use command export AWS_ACCESS_KEYID=<your access key> && export AWS_SECRET_ACCESS_KEY=<your secret access key>
. If you are using AWS SSO, you are required to fill in AWS_SESSION_TOKEN
.
Test your AWS CLI
Run command aws sts get-caller-identity
to verify your AWS Account setup. If your credential setup is successful, you should be able to see the correct account number.
Create ECR New Repository
Run command make repo
to create your new repo into your AWS Account as below:-
You can login your AWS Console to verify your repository.
Login ECR
In order to push your local image to ECR, you need to login ECR. Run command make login
to login your ECR.
Push your image
Run make image
to push your image to ECR.
Setup Terraform script
We are done on the application side. Now, we need to build our infrastructure. Create folder infra
on the project root, and setup the following.
Data resource
Terraform resource allow us to read existing infrastructure attribute such as VPC and subnet. In our case, we reuse existing default VPC.
Create file data.tf
in infra folder with the following content:-
Application Load Balancer
Create file alb.tf
in infra folder with the following content:-
We setup ALB with default static content and a routing rule for path
/WeatherForecast*
to our ECS resource.
ECS Cluster
Create file cluster.tf
in infra folder with the following content:-
Security Group
We will create one Security Group to share for ALB and Service, create sg.tf
in infra folder with following content:-
The Security Group we create will allow internal traffic and public traffic for port 80
ECS Service
We create one ECS Service my-api
to run in our ECS cluster. Create file service.tf
in infra folder with following content:-
The ECS Service will use basic setup for 1 runing task and route traffic from ALB
Task Definition
Task definition is used to describe what container configuration and image we need to run. Create file task-def.tf
in infra folder with the following content:-
We use the image that we pushed earlier for this task definition
Task Role and Task Execution Role
ECS has two permission models to manage the resources. One is Task Role
to assume role access for container and another is Task Execution Role
for ECS cluster to run on behalf of us, such as pulling image. To make this simpler, we will use one role for both permissions. Create file task_role.tf
in infra folder with following content:-
The role only provides basic ECSTaskExecution role policy and CreateLogGroup permission. You can add more if you need other permission.
Output file
Lastly we need to print out our ALB information so we can trigger it. Create output.tf
in infra folder with following content:-
Deploy your infrastructure
Great! You had completed all your infrastructure with terraform script setup. In reality, most of the component can be setup as reusable component to simplify new service setup. Now, let’s go back to your docker interactive terminal.
Init Terraform
Run make init
to initialize all the require plugin and provider.
Plan Terraform
Run make plan
to verify all the terraform setup is correct.
Apply Terraform
Run make apply
to apply changes to ours AWS Account.
After successful in apply the script above, you will be able to find your ALB url in the output.
Test API
Run make test
to test your api, or open browser with {url}/WeatherForecast
. You might need to try few times until all are integrated together.
Clear Resource
You can login into your AWS Account to verify ECS cluster, ALB, and cloudwatch. After you are satisfied, run make kill
to clear all the resource.
Conclusion
In this article, we learn about how to use terraform script to setup entire ECS Service in Fargate launch type in AWS. Beside that, we also learn to use docker environment for all our steps, and wrap all the command into Makefile. You can refer here for all the source code.