Between the Clouds Newsletter

Between the Clouds Newsletter

Share this post

Between the Clouds Newsletter
Between the Clouds Newsletter
How to Run Containers on AWS with ECS and Fargate (No Servers, No Kubernetes)

How to Run Containers on AWS with ECS and Fargate (No Servers, No Kubernetes)

Master ECS and Fargate in Minutes—No Kubernetes Required

Between the Clouds Newsletter's avatar
Between the Clouds Newsletter
Jul 08, 2025
∙ Paid

Share this post

Between the Clouds Newsletter
Between the Clouds Newsletter
How to Run Containers on AWS with ECS and Fargate (No Servers, No Kubernetes)
1
Share

If you’ve been knee-deep in Docker and wondering how to scale those containers into the cloud without getting lost in Kubernetes YAML hell, Amazon ECS might be your next best friend.

And if you’re short on time or just hate managing infrastructure? Let me introduce you to Fargate.

In this post, I’ll walk you through what ECS is, how it compares to Kubernetes, how you can run your first container with Fargate, and a few insider tips I’ve picked up from real-world deployments.

🔒 Want the full ECS Cheat Sheet with CLI commands, IAM policies, task definitions, and deployment steps? It’s available as a premium download below.

This Substack is reader-supported. To receive new posts and support my work, consider becoming a free or paid subscriber.

What Is Amazon ECS?

Amazon ECS (Elastic Container Service) is AWS's container orchestration platform. Think of it as the "opinionated" alternative to Kubernetes: fewer knobs to turn, easier to get started, and deeply integrated into the AWS ecosystem.

ECS runs your Docker containers using two launch types:

  • EC2 launch type: You manage the EC2 infrastructure (virtual machines).

  • Fargate launch type: AWS manages the infrastructure—you just define the containers.

For most of us in the home lab or small team DevOps space, Fargate is the way to go.

What’s a Task in ECS?

One of the important parts of the ECS architecture to understand is tasks. What are these? A task is a single running copy of a defined group of containers. You define a task definition in JSON or YAML, which includes:

  • The Docker image(s)

  • CPU and memory requirements

  • Networking mode (like awsvpc)

  • IAM roles

  • Logging config

  • Environment variables

You can then run tasks one-off or attach them to a service to ensure they stay up (similar to a Kubernetes Deployment)

ECS Task Definition Example – JSON

Let’s look at a couple of examples of code that do the same thing, either JSON or YAML.

Let’s break it down:

1. Name and Launch Type

  • "family": "nginx-fargate-task" defines the logical name of the task definition.

  • "requiresCompatibilities": ["FARGATE"] tells ECS to run this on Fargate (no EC2 instances required).

  • "networkMode": "awsvpc" ensures the task gets its own ENI (Elastic Network Interface) with a private IP in your VPC.

2. Compute Resources

  • "cpu": "256" and "memory": "512" define how much CPU (0.25 vCPU) and RAM (512 MiB) this task will use.

3. IAM Execution Role

  • "executionRoleArn" is an IAM role ECS uses to:

    • Pull the container image from Amazon ECR or Docker Hub

    • Push logs to CloudWatch

    • Access other AWS services if needed

4. Container Definition

Inside containerDefinitions:

  • "image": "nginx:latest" runs the latest official NGINX Docker image.

  • "portMappings" exposes port 80 for HTTP traffic.

  • "environment" sets an environment variable ENV=production inside the container.

  • "logConfiguration" uses the awslogs driver to stream logs to CloudWatch Logs under the group /ecs/nginx-fargate-task.

{
  "family": "nginx-fargate-task",
  "networkMode": "awsvpc",
  "requiresCompatibilities": ["FARGATE"],
  "cpu": "256",
  "memory": "512",
  "executionRoleArn": "arn:aws:iam::123456789012:role/ecsTaskExecutionRole",
  "containerDefinitions": [
    {
      "name": "nginx",
      "image": "nginx:latest",
      "portMappings": [
        {
          "containerPort": 80,
          "hostPort": 80,
          "protocol": "tcp"
        }
      ],
      "essential": true,
      "environment": [
        {
          "name": "ENV",
          "value": "production"
        }
      ],
      "logConfiguration": {
        "logDriver": "awslogs",
        "options": {
          "awslogs-group": "/ecs/nginx-fargate-task",
          "awslogs-region": "us-east-1",
          "awslogs-stream-prefix": "nginx"
        }
      }
    }
  ]
}

ECS Task Definition Example – YAML

Here is the same example, except using YAML.

family: nginx-fargate-task
networkMode: awsvpc
requiresCompatibilities:
  - FARGATE
cpu: "256"
memory: "512"
executionRoleArn: arn:aws:iam::123456789012:role/ecsTaskExecutionRole
containerDefinitions:
  - name: nginx
    image: nginx:latest
    essential: true
    portMappings:
      - containerPort: 80
        hostPort: 80
        protocol: tcp
    environment:
      - name: ENV
        value: production
    logConfiguration:
      logDriver: awslogs
      options:
        awslogs-group: /ecs/nginx-fargate-task
        awslogs-region: us-east-1
        awslogs-stream-prefix: nginx

Both formats are valid and can be used depending on how you’re deploying:

  • JSON is required when registering the task via AWS CLI or API.

  • YAML is more human-readable and ideal for version control or documentation.

Would you like me to include both versions of this in your ECS Cheat Sheet download?

How to Run Your First Container(s) in ECS

Here’s the simplest flow to get a container up with Fargate:

  1. Create a Task Definition
    Define your container, resource requirements, and permissions.

  2. Create a Cluster
    ECS clusters are just logical groups—you don’t need to launch EC2 instances.

  3. Run a Task or Create a Service

    • One-off: “Run task”

    • Persistent: Create a service that maintains N tasks running

  4. Attach to a VPC and Subnet
    You’ll use an existing VPC and private/public subnets depending on access needs.

  5. Use the Application Load Balancer (optional)
    For HTTP-based services, attach a load balancer and configure target groups.

🔥 Pro Tip: ECS tasks require IAM roles! Make sure your task role and execution role have the right permissions to pull images and write logs.

Tips & Tricks that I have learned from the “field”

  • Use Fargate Spot for 70%+ savings on non-critical workloads.

  • Use awslogs driver for easy log aggregation in CloudWatch.

  • Use Parameters in Task Definitions to avoid hardcoding values.

  • Avoid placing stateful apps in ECS unless you're using EFS or S3 for persistence.

  • Don't forget security groups and service discovery - ECS integrates tightly with Route 53 and VPC networking.

When Should You Use ECS?

There are definitely some strong use cases for ECS. What are some of those or when you would want to choose ECS over something else?

✅ You want to stay within the AWS ecosystem
✅ You want simplicity over full-blown Kubernetes
✅ You don’t want to manage servers (thanks, Fargate)
✅ You want native IAM, CloudWatch, and ALB integrations

Get the Ultimate Amazon ECS Cheat Sheet

This printable 2-page PDF includes:

  • ECS CLI commands and examples

  • Fargate task definition template

  • VPC and IAM config checklist

  • Tips for autoscaling and blue/green deployments

  • Quick-troubleshooting guide for stuck or failing tasks

Keep reading with a 7-day free trial

Subscribe to Between the Clouds Newsletter to keep reading this post and get 7 days of free access to the full post archives.

Already a paid subscriber? Sign in
© 2025 Brandon Lee
Privacy ∙ Terms ∙ Collection notice
Start writingGet the app
Substack is the home for great culture

Share