Fargate cost optimisation with Terraform
Natalia talks through how to make sure you don't overspend on Fargate instances.
AWS Fargate is pay as you go serveless compute for containers. You can use Fargate if you have small, batch, or burst workloads or if you want zero maintenance overhead of your containers, as this is all taken care of by AWS. In this post I will be talking about how to cost optimise your Fargate workloads and utilise Fargate Spot using Terraform.
Fargate Cost Optimisation
Let's start with general overview on how we can make sure that we do not overspend on our Fargate instances:
- Right-sizing tasks. Rightsizing is probably one of the first and most important tasks to ensure that you are not over provisioning your tasks, which can lead to unnecessary spending. You can specify value for CPU and Memory in your task definition - however make sure to specify a valid value for both of them.
- Utilise auto scaling. Auto-scaling can help you ensure that you are only running the necessary number of tasks, which can help to reduce costs. There are two types of scaling policies: Target Tracking and Step Scaling, and they can be scaled based on Memory and CPU utilisation. Here is more information about ECS autoscaling.
- Utilise AWS Savings Plans. To reduce Fargate cost you can use Compute Savings Plans. By purchasing Savings Plan you commit to using a certain amount of compute resources over a period of time. With Compute Savings you commit to 1 or 3 year plans, and you can save up to 66% on your EC2, Fargate, and Lambda costs.
- Fargate Spot. You can use spot instances with Fargate to further reduce your costs, which could mean up to 70% discount compared to Fargate On-Demand pricing, and there is no up-front commitment which is an advantage for more unpredictable or new workloads over Compute Savings Plan. However you can also utilise both at the same time to maximise your savings. It is important to note that spot instances can be terminated at any time, so you need to make sure that your application can handle this.
Additionally, you can use cost allocation tags to track your AWS costs. You can use tags to group your costs together so that you can see how much you are spending on different parts of your application.
Implementing Fargate Spot with Terraform
As mentioned before, when using Fargate Spot you have to be prepared that Spot instances can be terminated at any time, which makes it a good candidate for dev and test environments. However if you configure it correctly you can also utilise it on production, by setting base and weight on your capacity provider strategy to ensure availability of your application.
When creating a Fargate cluster via AWS Console it will have both Fargate and Fargate Spot capacity providers by default. However when creating it via Terrafrom you need to make sure to list them both in "capacity-providers" attribute. Here is example:
resource "aws_ecs_cluster" "ecs" {
name = "my_ecs_cluster"
}
resource "aws_ecs_cluster_capacity_providers" "ecs" {
cluster_name = aws_ecs_cluster.ecs.name
capacity_providers = ["FARGATE_SPOT", "FARGATE"]
default_capacity_provider_strategy {
base = 1
weight = 100
capacity_provider = "FARGATE"
}
}
Here we are creating ECS cluster, setting capacity providers to be Fargate spot and Fargate and setting the default capacity provider strategy to be just Fargate, which we will can later set for each service by defining capacity_provider_strategy on "aws_ecs_service" resource.
Next we will create a service for our ECS cluster with both FARGATE_SPOT and FARGATE set as capacity providers.
resource "aws_ecs_service" "main_service" {
name = "my_service"
cluster = aws_ecs_cluster.ecs.id
capacity_provider_strategy {
capacity_provider = "FARGATE"
weight = 4
base = 3
}
capacity_provider_strategy {
capacity_provider = "FARGATE_SPOT"
weight = 2
}
}
We are setting both base and weight of each capacity provider here. Weight of 4 for FARGATE means that for every 6 tasks, 4 will be running on FARGATE and 2 will be running on FARGATE_SPOT. For dev and test environments we can increase the weight of FARGATE_SPOT utilisation or remove FARGATE all together. BASE set to 3 on FARGATE capacity provider means that we will always have 3 tasks running on FARGATE - this is the configuration that would be important when considering using FARGATE_SPOT on production environments.
Last but not least when using CodeDeploy with Blue/Green deployments for existing ECS service make sure to add CapacityProviderStrategy in the resource section to the appspec.yml file. You can find more information about it over here.
Here is an example of appspec.yml file
version: 0.0
Resources:
- TargetService:
Type: AWS::ECS::Service
Properties:
TaskDefinition: <TASK_DEFINITION>
LoadBalancerInfo:
ContainerName: my_container
ContainerPort: 80
CapacityProviderStrategy:
- Base: 0
CapacityProvider: FARGATE_SPOT
Weight: 2
- Base: 1
CapacityProvider: FARGATE
Weight: 4
Base: 3
Further reading about Fargate Spot: