AWS Fargate vs EC2: How to Run Docker Containers Without Managing Servers

Running Docker containers in production forces an immediate architectural decision: do you manage the underlying servers yourself, or do you let AWS handle that entirely? AWS Fargate eliminates the EC2 instance management burden, but understanding exactly what that trade-off means — in terms of cost, control, and operational overhead — is what separates a well-architected system from an expensive mistake.

TL;DR — Fargate vs EC2 for Containers

DimensionAWS FargateEC2 (Self-Managed)
Server ManagementNone — AWS owns the hostYou patch, scale, and maintain instances
Pricing ModelPer vCPU/memory per second (task-level)Per instance-hour (regardless of utilization)
Scaling GranularityTask-level (individual container)Instance-level (entire EC2 node)
Kernel / OS AccessNo access to host OSFull root access to the instance
Startup TimeSlightly slower (cold provisioning)Faster if instance is already running
Spot / Savings PlansFargate Spot + Compute Savings PlansEC2 Spot, Reserved, Savings Plans
Best ForMicroservices, event-driven, bursty workloadsGPU workloads, high-density, custom AMIs

What Is AWS Fargate?

Fargate is a serverless compute engine for containers. It works as a launch type for both Amazon ECS (Elastic Container Service) and Amazon EKS (Elastic Kubernetes Service). When you use Fargate, AWS provisions, configures, and scales the underlying compute infrastructure invisibly. You define your container's CPU and memory requirements, and Fargate runs it — full stop.

Think of it this way: with EC2, you rent a warehouse and arrange the shelves yourself. With Fargate, you hand AWS a box and say "store this" — you never see the warehouse.

Analogy: EC2 is like leasing a physical office — you control the layout, furniture, and maintenance schedule. Fargate is like using a co-working space — you just show up with your laptop (container), and the infrastructure is already handled. You pay for the desk you use, not the entire floor.

How Fargate Works Internally

Understanding Fargate's architecture clarifies why it behaves differently from EC2-hosted containers.

sequenceDiagram participant Dev as Developer participant ECS as ECS Control Plane participant FG as Fargate Fleet participant VPC as Your VPC Dev->>ECS: Register Task Definition Dev->>ECS: Run Task / Create Service ECS->>FG: Schedule Task on Micro-VM FG->>FG: Pull Container Image from ECR FG->>VPC: Inject ENI with Private IP FG->>FG: Start Container FG-->>Dev: Task Running (RUNNING state)
  1. Task Definition: You declare your container image, CPU units, memory (MB), IAM role, networking mode, and logging config in an ECS Task Definition.
  2. ECS Scheduler: When a task is launched, the ECS control plane sends the task spec to the Fargate fleet.
  3. Micro-VM Isolation: Fargate provisions a dedicated, single-tenant micro-VM (using AWS Firecracker technology) for each task. No two customer tasks share a host kernel.
  4. ENI Injection: An Elastic Network Interface (ENI) is injected directly into your VPC, giving the task a private IP address within your subnet — this is the awsvpc network mode, mandatory for Fargate.
  5. Task Execution: Your container runs. AWS manages the host OS, hypervisor patches, and capacity.
  6. Billing Starts/Stops: You are billed from when the task starts downloading your container image to when it stops — measured in vCPU-seconds and GB-seconds.

Fargate on ECS vs EKS

Fargate integrates with both orchestrators, but the operational model differs slightly.

graph TD subgraph ECS_Fargate[ECS + Fargate] TD1[Task Definition] --> Svc1[ECS Service] Svc1 --> T1[Task A - Micro-VM] Svc1 --> T2[Task B - Micro-VM] end subgraph EKS_Fargate[EKS + Fargate] FP[Fargate Profile] --> Pod1[Pod A - Fargate Node] FP --> Pod2[Pod B - Fargate Node] K8s[K8s Control Plane] --> FP end
  • ECS + Fargate: AWS-native orchestration. Simpler setup, tighter AWS service integration (ALB, Service Discovery, CloudMap). No Kubernetes knowledge required.
  • EKS + Fargate: Uses Fargate Profiles to route specific pods (matched by namespace/label selectors) to Fargate. The Kubernetes control plane still runs on managed EC2 nodes (the EKS control plane itself). Daemonsets are not supported on Fargate nodes in EKS.

EC2 Launch Type: When You Keep Control

With the EC2 launch type on ECS, you manage a cluster of EC2 instances. The ECS agent runs on each instance and registers it with the cluster. The scheduler then places containers (tasks) onto instances based on available CPU/memory.

graph LR Cluster[ECS Cluster] --> EC2_1[EC2 Instance 1] Cluster --> EC2_2[EC2 Instance 2] EC2_1 --> C1[Container A] EC2_1 --> C2[Container B] EC2_2 --> C3[Container C] EC2_2 --> C4[Container D] EC2_1 --> Agent1[ECS Agent] EC2_2 --> Agent2[ECS Agent]

This model gives you:

  • Access to GPU instances (e.g., p3, g4dn) — Fargate does not support GPU workloads.
  • Custom AMIs with pre-installed agents, kernel modules, or compliance tooling.
  • Higher container density per dollar at sustained, predictable load (Reserved Instances).
  • Support for ECS Daemonsets (one task per instance) for log shippers, monitoring agents, etc.

Networking Deep-Dive: awsvpc Mode

Fargate mandates the awsvpc network mode. Each Fargate task gets its own ENI and a private IP from your VPC subnet. This has critical implications:

  • Security Groups: Applied at the task level, not the instance level — fine-grained control.
  • ENI Limits: Your subnet and account have ENI limits. High task counts require subnet CIDR planning. Check the VPC limits documentation for current quotas.
  • No Host Networking: You cannot use host or bridge network modes with Fargate.

IAM Security Model

Fargate uses two distinct IAM roles — a common source of confusion:

RolePurposeExample ARN
Task Execution Role Used by the Fargate agent to pull ECR images, write CloudWatch logs arn:aws:iam::123456789012:role/ecsTaskExecutionRole
Task Role Used by your application code inside the container to call AWS APIs (S3, DynamoDB, etc.) arn:aws:iam::123456789012:role/MyAppTaskRole

Always follow least privilege: the Task Execution Role should only have ecr:GetAuthorizationToken, ecr:BatchGetImage, and logs:CreateLogStream / logs:PutLogEvents permissions at minimum.

Practical Implementation: ECS Fargate Task Definition

Below is a minimal but production-ready ECS Task Definition for Fargate. It defines a single container, assigns CPU/memory, configures CloudWatch logging, and references both IAM roles.

🔽 Click to expand — ECS Fargate Task Definition (JSON)
{
  "family": "my-api-task",
  "networkMode": "awsvpc",
  "requiresCompatibilities": ["FARGATE"],
  "cpu": "512",
  "memory": "1024",
  "executionRoleArn": "arn:aws:iam::123456789012:role/ecsTaskExecutionRole",
  "taskRoleArn": "arn:aws:iam::123456789012:role/MyAppTaskRole",
  "containerDefinitions": [
    {
      "name": "my-api",
      "image": "123456789012.dkr.ecr.us-east-1.amazonaws.com/my-api:latest",
      "portMappings": [
        {
          "containerPort": 8080,
          "protocol": "tcp"
        }
      ],
      "logConfiguration": {
        "logDriver": "awslogs",
        "options": {
          "awslogs-group": "/ecs/my-api-task",
          "awslogs-region": "us-east-1",
          "awslogs-stream-prefix": "ecs"
        }
      },
      "essential": true
    }
  ]
}

Deploying the Service via AWS CLI

🔽 Click to expand — ECS Service Creation (CLI)
# Register the task definition
aws ecs register-task-definition \
  --cli-input-json file://task-definition.json \
  --region us-east-1

# Create the ECS Service with Fargate launch type
aws ecs create-service \
  --cluster my-cluster \
  --service-name my-api-service \
  --task-definition my-api-task \
  --desired-count 2 \
  --launch-type FARGATE \
  --network-configuration "awsvpcConfiguration={subnets=[subnet-0abc1234,subnet-0def5678],securityGroups=[sg-0123456789abcdef0],assignPublicIp=DISABLED}" \
  --region us-east-1

Cost Optimization: Fargate Spot

Fargate Spot runs tasks on spare AWS capacity at a significant discount compared to standard Fargate pricing. AWS can interrupt Fargate Spot tasks with a 2-minute warning (via a SIGTERM signal to your container). This makes it ideal for:

  • Batch processing jobs
  • CI/CD pipeline runners
  • Non-critical background workers

You can mix standard Fargate and Fargate Spot using ECS Capacity Provider Strategies — for example, run 70% on Fargate Spot and 30% on standard Fargate for resilience.

Pricing and discount percentages vary. Always check the official Fargate pricing page for current rates.

Decision Framework: Fargate or EC2?

graph TD Start([New Container Workload]) --> Q1{Need GPU?} Q1 -->|Yes| EC2[Use EC2 Launch Type] Q1 -->|No| Q2{Need privileged mode or custom kernel?} Q2 -->|Yes| EC2 Q2 -->|No| Q3{Predictable high-density sustained load?} Q3 -->|Yes| Q4{Cost-optimized with Reserved Instances?} Q4 -->|Yes| EC2 Q4 -->|No| Fargate[Use Fargate] Q3 -->|No| Fargate Fargate --> Q5{Fault-tolerant or batch?} Q5 -->|Yes| FSpot[Use Fargate Spot] Q5 -->|No| FStd[Use Standard Fargate]

Key Limitations of Fargate to Know

  • No GPU support: GPU-accelerated workloads (ML inference, video encoding) require EC2 instances.
  • No privileged containers: You cannot run containers in privileged mode on Fargate.
  • No host volume mounts: Only EFS (Elastic File System) and ephemeral storage are supported for persistent data. Bind mounts to the host are not available.
  • EKS Daemonsets: Not supported on Fargate nodes — use EC2 node groups for cluster-wide agents.
  • Ephemeral storage: Each Fargate task gets a default amount of ephemeral storage. You can configure additional ephemeral storage up to a documented maximum — check the ECS Fargate storage documentation for current limits.

Glossary

TermDefinition
Task DefinitionA blueprint (JSON) describing your container image, CPU, memory, networking, and IAM roles for ECS.
awsvpc Network ModeECS network mode that assigns each task its own ENI and VPC IP — mandatory for Fargate.
Fargate SpotInterruptible Fargate capacity at reduced cost, suitable for fault-tolerant workloads.
Task Execution RoleIAM role used by the Fargate agent (not your app) to pull images and write logs.
FirecrackerAWS open-source VMM (Virtual Machine Monitor) that provides lightweight micro-VM isolation for Fargate tasks.

Next Steps

Comments

Popular posts from this blog

EC2 No Internet Access in Custom VPC: Attaching an Internet Gateway and Fixing Route Tables

EC2 SSH Connection Timeout: The Exact Security Group Rules You Need to Fix It

IAM User vs. IAM Role: Why Your EC2 Instance Should Never Use a User