A Comprehensive Guide AWS Fargate

Table of Contents

What is AWS Fargate?


AWS Fargate is a serverless compute engine designed to run containers without the need to manage servers or clusters. As part of Amazon Web Services (AWS), Fargate simplifies the deployment, scaling, and management of containerized applications by abstracting the underlying infrastructure.

With AWS Fargate, users can focus entirely on building and running their applications while AWS handles the provisioning and management of the compute resources. This eliminates the need to manage and scale clusters of virtual machines, offering a more streamlined approach to container orchestration.

AWS ECS with Fargate capacity provider (Fargate for future reference) is a go-to solution to run Dockerized applications.

While Fargate has some limitations that we’ll explore, it remains a highly suitable choice for most Dockerized applications used or developed by startups, regardless of size.

From industries like Crypto to Real Estate, many customers choose Fargate to power their infrastructure due to its high availability across multiple AWS Availability Zones, seamless auto-scaling with AWS Auto Scaling, and robust integrations with other AWS services.

In this guide
Container Registries | Provisioning an ECS cluster | Service Discovery (AWS Cloud Map) | Service Auto Scaling | Service Load Balancing | Working with secrets (AWS Secrets Manager) | Monitoring | Fargate Limitations | Learn More About Using AWS Fargate

Container Registries


Private Registries

One of the best features of Fargate is the ability to work seamlessly with images from various private registries, such as a private Docker Hub repository or AWS Elastic Container Registry (ECR). By leveraging the integration with AWS Secrets Manager, repository credentials can be securely stored and managed. These credentials can then be referenced directly in the Task Definition, allowing the ECS daemon to authenticate with the private registry effortlessly, as demonstrated below.

"containerDefinitions": [
    {
        "image": "private-repo/private-image",
        "repositoryCredentials": {
            "credentialsParameter": "arn:aws:secretsmanager:region:aws_account_id:secret:secret_name"
        }
    }
]

The Task Execution Role should also be extended with the following IAM Policy (as below).

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "kms:Decrypt",
        "ssm:GetParameters",
        "secretsmanager:GetSecretValue"
      ],
      "Resource": [
        "arn:aws:secretsmanager:<region>:<aws_account_id>:secret:secret_name",
        "arn:aws:kms:<region>:<aws_account_id>:key/key_id"     
      ]
    }
  ]
}

AWS ECR Integration


AWS Fargate offers seamless integration with AWS Elastic Container Registry (ECR) by default. To use ECR images, you simply need to extend the Task Execution Role with the managed AmazonECSTaskExecutionRolePolicy IAM policy. This eliminates the need for additional setup with AWS Secrets Manager or repository credentials, providing a straightforward solution for pulling Docker images from AWS ECR.

Provisioning an ECS cluster (for Fargate)


Setting up an AWS ECS Cluster in Networking Only mode is incredibly simple and can be completed in just a few clicks. From the AWS Console, select the Networking Only option after clicking the Create Cluster button in the ECS Console, and your cluster will be ready within a minute.

Alternatively, you can create an AWS ECS Cluster using Terraform with just a few lines of code. When doing so, it’s recommended to enable the Container Insights feature by default (discuss in detail later).

resource "aws_ecs_cluster" "best" { 
  name = "best-cluster" 
  setting { 
    name = "containerInsights" 
    value = "enabled" 
  } 
}

Service Discovery (AWS Cloud Map)


Ensuring seamless communication between services within an ECS cluster can be achieved in multiple ways, such as utilizing a messaging or queue system. However, if direct service-to-service communication is required, a static address is essential.

Relying on dynamic IP addresses is not feasible since they change when containers are created or removed by the orchestrator. This is where AWS Cloud Map provides an effective solution. By integrating smoothly with AWS ECS services, AWS Cloud Map allows you to create a namespace and enable service discovery integration, ensuring that services can address each other reliably.

Setting this up via the AWS Console is straightforward, but in this guide, we’ll demonstrate how to implement service discovery integration using Terraform resources.

resource "aws_service_discovery_private_dns_namespace" "bestnamespace" {
  name = "best.domain.com"  
  description = "best private dns namespace" 
  vpc = aws_vpc.example.id 
}

The next step regarding Terraform is to create a service discovery resource (“aws_service_discovery_service”), in which specify the private namespace we have already created and the DNS records.

resource "aws_service_discovery_service" "best" {
  name = "best"
  dns_config {
    namespace_id = "${aws_service_discovery_private_dns_namespace.bestnamespace.id}"
    routing_policy = "MULTIVALUE"
    dns_records {
      ttl = 10
      type = "A"
    }

    dns_records {
      ttl  = 10
      type = "SRV"
    }
  }
  health_check_custom_config {
    failure_threshold = 5
  }
}

Finally, we can configure the ECS Service’s service discovery option using the service_registries argument as the following.

resource "aws_ecs_service" "app" {
  name            = "best-service"



  service_registries {
    registry_arn = "${aws_service_discovery_service.best.arn}"
    port = "5001"
  }
}

Service Auto Scaling


One of the standout features of AWS Fargate is its integrated auto-scaling capability, which eliminates the need for custom scripts to manage scaling operations. AWS ECS Service leverages the AWS Application Auto Scaling service, allowing users to scale tasks using Target Tracking Scaling policies, Step Scaling policies, or Scheduled Scaling.

For those getting started, the Target Tracking Scaling policy is the simplest option. This policy adjusts the number of service tasks based on a single metric, automatically scaling up or down as needed.

Curious about how this works with Terraform? Let’s explore an example implementation.

# ECS Service Resource -> Scaling Configuration property
scaling_configuration {
    role_arn               = "<ECSService Role - arn:aws:iam::000000000000:role/ecsAutoscaleRole>"
    minimum_scaling_step_size = 1
    maximum_scaling_step_size = 2
    target_tracking_configuration {
      predefined_metric_specification {
        predefined_metric_type = "ECSServiceAverageCPUUtilization"
      }
      target_value = 70.0
    }
  }

Service Load Balancing


 

Managing the entry point for applications hosted on AWS Fargate is seamless with AWS Application Load Balancers (ALB). ALB not only integrates smoothly with Fargate services but also supports applications using the EC2 capacity provider. With built-in TLS termination and support for AWS Certificate Manager (ACM) managed certificates, securing data in transit to Fargate services is straightforward and efficient.

To optimize performance and reliability, adjustments to the health check grace period and health check settings are essential. This ensures that ECS tasks are not prematurely terminated while they are still initializing and becoming available.

For added security, the ALB can be placed in public/DMZ subnets, while Fargate tasks remain in private subnets, creating a secure and isolated environment for the applications. This configuration enhances security while maintaining high availability and scalability.

# ECS Service Resource -> Load Balancer propery
load_balancer {
  target_group_arn = aws_alb_target_group.example.arn
  container_name   = "example"
  container_port   = 80
}

Working with secrets (AWS Secrets Manager)


One of the key advantages of the integration between AWS Secrets Manager and ECS is the ability to avoid hardcoding sensitive information in plaintext. For external services, database connections, or third-party APIs, you can securely store secret values in AWS Secrets Manager and reference them directly in the container definition.

During container initialization, the ECS daemon uses the assigned IAM Task Execution Role to retrieve the secret value from Secrets Manager and injects it into the container as an environment variable. This ensures secure and seamless handling of sensitive data without compromising security or requiring manual intervention.

# ECS Task Definition Secret property

...
{
  "containerDefinitions": [{
    "secrets": [{
      "name": "environment_variable_name",
      "valueFrom": "arn:aws:secretsmanager:<region>:<account_id>:secret:<secret-id>:<secret-key>::"
    }]
  }]
}
...

Monitoring


While opinions may differ, we find that third-party monitoring tools are unnecessary for managing our Fargate services. AWS CloudWatch Container Insights and AWS CloudWatch Logs, combined with CloudWatch Logs Insights, provide all the monitoring and querying capabilities we need.

Container Insights offers detailed metrics for ECS services, tasks, and the containers running within them. It also provides visualizations of services and tasks, enabling easy navigation to specific services of interest. Activating Container Insights is straightforward and can be done during the creation or update of an ECS cluster. (Refer to the Terraform example in the section above, Provisioning an ECS Cluster for Fargate.)

For log analysis, Logs Insights uses a unique CloudWatch query syntax, which may feel different from SQL at first but becomes intuitive over time. Additionally, Container Insights metrics are accessible through CloudWatch Logs Insights, making it easy to extract meaningful data.

To enable log delivery from containers to CloudWatch, you can extend the task definition with the logConfigurationproperty, ensuring seamless integration and monitoring of your Fargate workloads.

{
    "containerDefinitions": [
        {
            "name": "best-app",
            …….
            "logConfiguration": {
                "logDriver": "awslogs",
                "options": {
                    "awslogs-create-group": "true",
                    "awslogs-group": "ecs",
                    "awslogs-region": "eu-central-1",
                    "awslogs-stream-prefix": "best"
                }
            },
            ….
        },

Also, don’t forget to extend the ECS Task Execution IAM Role with the required permissions (suggested AmazonECSTaskExecutionRolePolicy IAM policy can be used).

Fargate Limitations


As of January 2023, AWS Fargate has certain compute and resource limitations:

  • Compute Resources: Fargate supports up to 16 vCPUs and 120GB of RAM per task. This is sufficient for most web service use cases.
  • Containers per Task Definition: A maximum of 10 containers can be defined per task. Again, this limit is adequate for the majority of web service applications.
  • Tasks per Service: Fargate allows up to 5,000 tasks per service, which is more than sufficient for most scenarios.

It’s worth noting that the task limit is a soft limit, meaning it can be increased upon request through the AWS service quota management system if your workload requires higher capacity.

See More AWS Guides and Insights