Scalable Applications with AWS Fargate & ECS
When the number of users of an application increases, the system infrastructure must be designed to be scalable to handle high traffic volumes.
In recent years, Docker and container technology have made it much easier for us to manage containers using Docker Swarm or Kubernetes.
Now, let’s briefly discuss the products and terms in the Amazon ecosystem.
AMAZON ECR (Elastic Container Registry)
We can describe it as the Amazon equivalent of Docker Registry, which allows the storage, distribution, and sharing of Docker images. You can manage it according to the pipeline you created for Continuous Integration.
In my case, I manage CI/CD processes through GitHub Actions. When the release branch is merged into the master, the image is uploaded to ECR, and the Continuous Delivery process starts automatically. New containers are launched with the updated images, health checks are performed, and if they pass, the load balancer directs traffic to the new containers and deletes the old ones.
It is also possible to manage this scenario using different tools such as Jenkins or Amazon’s CodePipeline service.
AMAZON ECS (Elastic Container Service)
The applications that have been containerized run on ECS services, and you can manage your containers with Task Definitions. I will explain the details and share a practical example later in the article.
AMAZON EKS (Elastic Kubernetes Service)
If you want to run your containers in a Kubernetes environment, you can choose EKS. However, in this article, I will be sharing examples using Amazon’s container service, ECS.
AMAZON FARGATE
When you run containerized applications on an EC2 instance, scaling is based on the capacity of those servers, such as 16 GB RAM and 4 CPU. Additionally, the maintenance and management of those servers are your responsibility.
While it is possible to plan a configuration to scale EC2 machines, it is much more efficient to position containerized applications on ECS or EKS services if you already have them in container form.
Fargate allows us to run our services in a “serverless” manner without the need for servers. It provides significant convenience in terms of scaling and management. You can set container limits for each application, such as 8 GB RAM and 2 CPU, and the number of containers can automatically and quickly increase up to ’n’ based on the resource requirements. These containers are automatically shut down when the resource requirements decrease.
Let’s illustrate this with an example. Imagine that you have developed a news application that sends “Breaking News” notifications to users. You need to keep the system stable and operational, even if ’n’ or 20n users click on the notification. With Amazon Fargate, you can scale without any resource limitations. When ’n’ users click on the notification, the system responds with only one container. When 20n users click, the system increases the number of containers to 20. After ‘X’ minutes, it automatically shuts down the additional containers it created and doesn’t charge us for the unused resources. Users continue to use the system stably.
It is critical to note that Fargate only scales your container. If the microservices that your application depends on, such as databases, caches, queues, etc., are not scaled, the system will eventually become locked.
SCALABLE APPLICATIONS WITH FARGATE/ECS
So far, I have summarized the Amazon services that can be used to design a scalable architecture. In the continuation of this article, I will share how we can create a scalable structure using Fargate and ECS.
LET’S CREATE A DOCKER REGISTRY
First, we will create an ECR repository where we will upload the versions of our application. For this example, I have created a new repository named “demo-service”.
If desired, you can also use different registry services outside of the Amazon ecosystem (such as Docker Hub, Google Cloud Registry, etc.).
Now, you need to configure your Continuous Integration processes to send images to this repository.
For authentication, you can create a user in AWS’s IAM service. If you are using GitHub Actions, you can use Amazon’s official packages “aws-actions/configure-aws-credentials” and “aws-actions/amazon-ecr-login”.
LET’S CREATE A CLUSTER
You will run your containers within a cluster. We will create a serverless cluster with Fargate, so we will not have any EC2 instances to manage.
In the second step, we need to specify the name of our container. You can customize your network settings by creating a new VPC and subnet. I recommend enabling CloudWatch Container Insights to monitor metrics and logs.
And now our cluster is ready to use.
Here, I would like to point out a critical point regarding networking. We created the cluster in a new VPC, but if you want to access your applications in a different VPC from your containers via a private network, you need to configure the “Route Table” to define the rules for inter-VPC access.
CREATE A TASK DEFINITION
The containers are managed according to the rules defined in the task definitions. We will define the rules to be followed when a new container is launched.
We are creating a task that will run in Fargate type.
In the second step, we need to enter the task definition name. I generally use the task-{serviceName}-service-{environment} template.
task-device-service-production task-device-service-staging etc.
In the Task Size section, you specify the limits of your container. If you are creating a demo application for testing purposes, I recommend keeping the specifications low and then deleting the cluster. The specifications you choose here will be reflected on your AWS bill.
And now it’s time to create the container. We click on the “Add Container” button and start configuring our container settings.
I prefer to name the container using the template of “{serviceName}-container-{environment}”.
In the first step, we created an image repository on ECR. You need to enter the address of this repository in the “image” field to run the container using that image.
If authentication is required for the image, you can define it using “private repository authentication”.
In the “Port Mapping” section, you should enter the port number that your application is running on inside the container. For example, if you have a Java application running on port 8080, you should enter that port number here.
In the advanced settings section, you do not need to change anything for the start. However, there is a critical point to mention in the “health check” settings.
If your application’s base URL does not return a “200” HTTP response code, the container marks itself as “problematic.” Shortly thereafter, it starts a new container and shuts itself down. In this case, you constantly include your containers in an open/closed loop.
If your application has a health check URL, you can change this field. In case of any problem, the system will automatically prepare a new container and add it to the load balancer.
CREATE CLUSTER SERVICE
And now we’ve reached the final step. We’ll create our cluster service to make our application available.
We specify that we’ll create a Fargate type service. We select the task definition we created earlier and specify that it should be active under the cluster we created before. Finally, we write the service name. In the “Number of tasks” section, you can set the replica count and limits.
If you are using Amazon’s CodeDeploy service, you can proceed with the blue/green deployment option. For now, let’s continue with “Rolling Update”.
We are defining our network settings.
If you have created a new VPC, you need to define a load balancer in this network that is linked to your container by creating a new “Application” type load balancer.
There are 2 important points to consider here:
- The port mapping of the load balancer should be configured the same as the port on which your container is running.
- The health check URL must be defined correctly. Otherwise, the load balancer will see that the container is not working or has failed and will not route traffic to the container.
Finally, if you want to configure auto-scaling settings, you can set your limits. If you are creating an application for testing purposes, you can proceed without configuring auto-scaling.
Your application is now up and running on AWS Fargate and ready to use. By following these steps, you have learned how to create and deploy an application on AWS Fargate. 🚀
I hope you found this article informative and useful. If you have any questions or feedback, please don’t hesitate to let me know. 👋