DEV Community

Emiliano Roberti
Emiliano Roberti

Posted on

AWS ECS and Fargate for Building and Deploying Containers

When I started out with cloud development it took me some times to understand the various deployment strategies, how they differ and when to use a Lambda or a container. ( have a article on lambdas https://dev.to/emiroberti/aws-lambda-and-its-invocation-models-4406 ).

In this article I will focus on AWS Elastic Container Service (ECS) and AWS Fargate as its a powerful solutions for running containers in the cloud. However, developers often compare them with alternatives such as Amazon EC2, AWS Lambda, and AWS App Runner. This article explores why ECS and Fargate are excellent choices, and how they compare to these other services.

Understanding ECS and Fargate

Amazon ECS is a fully managed container orchestration service that enables you to deploy, manage, and scale containerised applications. It supports two launch types:

  • EC2 Launch Type: Uses Amazon EC2 instances as the underlying compute infrastructure for running containers.
  • Fargate Launch Type: A serverless option that eliminates the need to manage EC2 instances, allowing AWS to handle provisioning and scaling.

Fargate is particularly useful for teams looking for a simplified way to run containers without worrying about underlying infrastructure.

Differentiating ECS and Fargate from Other AWS Compute Services

1. ECS vs EC2

Feature ECS (with Fargate) EC2
Infrastructure Management Fully managed User-managed
Scaling Automatic, serverless Manual or Auto Scaling Groups
Security IAM-based role per task Requires EC2 security group configuration
Cost Efficiency Pay per vCPU and memory Pay per EC2 instance
  • ECS with EC2 gives more control over the underlying infrastructure but requires additional management.
  • Fargate simplifies deployment by abstracting infrastructure concerns, making it easier to manage at scale.

2. ECS vs Lambda

Feature ECS (with Fargate) AWS Lambda
Best for Long-running containerised apps Event-driven, short-lived functions
Execution Time Unlimited Limited to 15 minutes per execution
Cold Start Delay Minimal Potential delays due to cold starts
Pricing Model Pay for provisioned CPU/memory Pay per execution time and requests
  • Lambda is excellent for serverless event-driven applications but unsuitable for persistent container workloads.
  • ECS (with Fargate) is ideal for microservices that need continuous availability.

3. ECS vs App Runner

Feature ECS (with Fargate) AWS App Runner
Best for Complex container orchestration Simple web app deployment
Customisation Highly configurable Abstracted service
Deployment Method Task definitions, services, ALBs Git-based deployment
Scaling Fine-grained autoscaling Managed autoscaling
  • AWS App Runner is designed for developers looking for a hands-off approach to running web applications.
  • ECS and Fargate offer more flexibility and control over networking, security, and performance.

Why Choose ECS and Fargate?

1. Simplified Management

With AWS Fargate, you do not need to provision, manage, or scale EC2 instances. This is ideal for teams focused on application development rather than infrastructure maintenance.

2. Scalability and Flexibility

ECS with Fargate allows dynamic scaling based on workload demand, ensuring optimal resource utilisation without manual intervention.

3. Security and Isolation

ECS integrates seamlessly with AWS IAM for granular permissions. Fargate tasks run in isolated compute environments, reducing security risks.

4. Cost Efficiency

Fargate follows a pay-as-you-go model where you only pay for the vCPU and memory consumed by running containers. This eliminates the need to provision excess capacity upfront.

5. Deep AWS Integration

ECS and Fargate work seamlessly with AWS services like IAM, VPC, CloudWatch, and ALB, offering a unified ecosystem for building cloud-native applications.

Amazon ECS and Fargate provide ascalabl e, and cost-effective solutions for container orchestration. While EC2, Lambda, and App Runner each have their use cases, ECS and Fargate strike a balance between flexibility and ease of use.

Here is a sample code for a cdk project.

AWS CDK Code

This AWS CDK script provisions an ECS Fargate service using AWS resources, including a VPC, security groups, ECS cluster, and an Application Load Balancer (ALB). The service runs a container from a specified Docker image repository, making it publicly accessible over port 8000.

Key Features

  • VPC Creation: The script creates a VPC with two public subnets and no NAT gateways to keep costs low.
  • ECS Cluster: An ECS cluster is created within the VPC.
  • Security Group Configuration: Ingress rules allow traffic on ports 8000 (application) and 443 (HTTPS).
  • Fargate Task Definition: Defines the container settings, including memory, CPU, and IAM permissions.
  • Application Load Balancer: Used to distribute traffic to the running container instances.
  • Health Check Configuration: Ensures the service is considered healthy before routing traffic.

Prerequisites

Before deploying this stack, ensure:

  • AWS CDK is installed (npm install -g aws-cdk)
  • AWS credentials are configured (aws configure)
  • Environment variables are set in a .env file:
  STAGE=dev
  PREFIX=server-image-process
  DOCKER_REPO=your-docker-image-repo
  STREAM_PREFIX=server-stream
Enter fullscreen mode Exit fullscreen mode

Code Breakdown

VPC Setup

const vpc = new ec2.Vpc(this, prefix + "-vpc", {
  maxAzs: 2,
  natGateways: 0,
  subnetConfiguration: [
    {
      cidrMask: 24,
      name: "public",
      subnetType: ec2.SubnetType.PUBLIC,
    },
  ],
});
Enter fullscreen mode Exit fullscreen mode

This creates a VPC with two availability zones and public subnets.

ECS Cluster

const cluster = new ecs.Cluster(this, prefix + "-cluster", {
  vpc,
});
Enter fullscreen mode Exit fullscreen mode

Creates an ECS cluster to manage the containerised application.

Security Group

const securityGroup = new ec2.SecurityGroup(this, prefix + "-sg", {
  vpc,
  allowAllOutbound: true,
});

securityGroup.addIngressRule(ec2.Peer.anyIpv4(), ec2.Port.tcp(8000), "Allow HTTP traffic");
securityGroup.addIngressRule(ec2.Peer.anyIpv4(), ec2.Port.tcp(443), "Allow HTTPS");
Enter fullscreen mode Exit fullscreen mode

Allows inbound traffic on ports 8000 and 443.

Fargate Task Definition

const taskDefinition = new ecs.FargateTaskDefinition(
  this, prefix + "-task-definition",
  {
    memoryLimitMiB: 1024 * 3,
    cpu: 256 * 4,
  }
);
Enter fullscreen mode Exit fullscreen mode

Defines the Fargate task with 3GB RAM and 1 CPU.

Container Definition

const container = taskDefinition.addContainer(prefix + "-container", {
  image: ecs.ContainerImage.fromRegistry(repo),
  logging: ecs.LogDriver.awsLogs({
    streamPrefix: streamPrefix,
    logRetention: logs.RetentionDays.ONE_WEEK,
  }),
});

container.addPortMappings({ containerPort: 8000 });
Enter fullscreen mode Exit fullscreen mode

Specifies the container image and logging configuration.

Deploying with a Load Balancer

const fargateService = new ecs_patterns.ApplicationLoadBalancedFargateService(
  this, prefix + "-service",
  {
    cluster,
    taskDefinition,
    desiredCount: 1,
    assignPublicIp: true,
    publicLoadBalancer: true,
    securityGroups: [securityGroup],
    healthCheckGracePeriod: cdk.Duration.seconds(60),
  }
);
Enter fullscreen mode Exit fullscreen mode

Creates an Application Load Balancer (ALB) for the service.

Health Check Configuration

fargateService.targetGroup.configureHealthCheck({
  path: "/api/health",
  port: "8000",
  healthyThresholdCount: 2,
  unhealthyThresholdCount: 5,
  timeout: cdk.Duration.seconds(5),
  interval: cdk.Duration.seconds(30),
});
Enter fullscreen mode Exit fullscreen mode

Ensures that the application is only routed to healthy instances.

Deployment

To deploy the stack, run:

cdk deploy
Enter fullscreen mode Exit fullscreen mode

To delete the stack, use:

cdk destroy
Enter fullscreen mode Exit fullscreen mode

Author: Emi Roberti

Top comments (0)