A few months ago I had heard about AWS Fargate as a serverless computing platform for containers. I had good experiences with AWS's other serverless offerings and I wanted to get into containers more so Fargate seemed like a good next learning opportunity. I remember trying to spin a few resources up just to start messing around with the platform. At the end of the day, I ended up with an ECS cluster and some misconfigured services. I didn't realize that there were multiple different resources needed just to get a simple API container up and running. I recently worked through creating an ECS cluster, load balancer, Fargate service, and task definition with CloudFormation. I also made a video out of building the template and debugging along the way here's part 1 and here's part 2 (I apologize for the quiet audio). In the end, I created one template for the ECS cluster, load balancer, and other shared resources that could be shared across multiple Fargate services, one template for the Fargate service, task definition, and load balancer listener, and a tiny Dockerized hello world app.
I created the shared resources template with reusability across an application in mind. In addition to a shared ECS cluster and load balancer, a baseline IAM role, a baseline security group, and an ECR repository are included in that template. The load balancer sits in two public subnets, and I put the Fargate service in private subnets. The motivation for this was to allow public access to the service through the load balancer but not directly to the container. All of the relevant information is exported from that template too with the intention of the Fargate service's template importing that information. It's worth noting that both the ECS cluster stack and the Fargate service stack take a parameter for a VPC stack, which is also a template from my CloudFormation reference repo.
The Fargate service template defines a service, task definition, load balancer listener, load balancer target group, and a CloudWatch log group. The service and task definition are necessary resources that tell the ECS cluster that we want to launch a service, how many instances of the service we want to launch, networking configuration, and some other configuration for the service. The task definition defines what the service will be running. Configuration for container definitions in the task definition includes where to find the Docker image, logging configuration, environment configuration, and other container level configuration that could be found in a
docker-compose file. The task definition also includes some compute level configuration and defines IAM roles to be used. The load balancer listener tells the load balancer what port to listen on and to forward that traffic on to the target group, which finally forwards traffic to our container. It's worth mentioning that there is much more logic that can be built into load balancer listeners, and my configuration is simple by design.
After spinning up the VPC, ECS cluster, and Fargate service, it is possible to make requests to the URL that is given to the load balancer and receive responses from the container. I was super excited to get this working in part two of my video series because I wasn't satisfied with the way I left things in the first video. I hope this has helped someone out there looking for a baseline Fargate service to get them off the ground. I plan to continue updating my
aws-cloudformation-reference GitHub repo with other templates in the future to serve as a jumping-off point for various AWS architectures and service. Thanks for reading!