ECS Fargate Deep Dive Part 2: Firecracker in Action

2025-09-02

Introduction

In Part 1, we pulled back the curtain on how ECS Fargate works: Firecracker microVMs, ENIs, IAM, and the hidden host fleet.

Now it’s time to get hands-on. We’ll spin up Firecracker locally, boot a microVM, and even simulate the ENI networking model.

Why Should You Care?

Running Firecracker yourself helps you:

  • See how AWS runs each Fargate task inside its own VM.
  • Understand boot performance and why Fargate cold starts take 30–60s.
  • Learn how ENIs map to VPC-level isolation.
  • Debug networking limits by replicating them locally.

Scenario Overview

We’ll simulate a Fargate task locally:

  • Launch a Firecracker microVM.
  • Attach a minimal Linux root filesystem.
  • Configure a TAP interface for networking (like an ENI).
  • Map this setup back to ECS Fargate’s architecture.

Goal: see how isolation and networking work in practice.


Deep Dive: Step-by-Step Setup

Prerequisites

Run this on a Linux host (Ubuntu VM, EC2, or Multipass).

sudo apt-get update
sudo apt-get install -y git curl wget build-essential \
    unzip cmake pkg-config libseccomp-dev

# Download Firecracker

curl -LOJ https://github.com/firecracker-microvm/firecracker/releases/download/v1.8.0/firecracker-v1.8.0-x86_64.tgz
tar -xvf firecracker-v1.8.0-x86_64.tgz
sudo mv release-v1.8.0-x86_64/firecracker /usr/local/bin/

### Kernel & RootFS

curl -LO https://s3.amazonaws.com/spec.ccfc.min/img/hello/kernel/vmlinux.bin
curl -LO https://s3.amazonaws.com/spec.ccfc.min/img/hello/fsfiles/x86_64/rootfs.ext4


### Launching a MicroVM

rm -f /tmp/firecracker.socket
firecracker --api-sock /tmp/firecracker.socket &

# VM config + boot source
curl --unix-socket /tmp/firecracker.socket -i \
  -X PUT 'http://localhost/machine-config' \
  -H 'Content-Type: application/json' \
  -d '{"vcpu_count":1,"mem_size_mib":512,"ht_enabled":false}'

# Kernel
curl --unix-socket /tmp/firecracker.socket -i \
  -X PUT 'http://localhost/boot-source' \
  -H 'Content-Type: application/json' \
  -d '{"kernel_image_path":"./vmlinux.bin","boot_args":"console=ttyS0 reboot=k panic=1 pci=off"}'

# RootFS
curl --unix-socket /tmp/firecracker.socket -i \
  -X PUT 'http://localhost/drives/rootfs' \
  -H 'Content-Type: application/json' \
  -d '{"drive_id":"rootfs","path_on_host":"./rootfs.ext4","is_root_device":true,"is_read_only":false}'

## Start the VM

curl --unix-socket /tmp/firecracker.socket -i \
  -X PUT 'http://localhost/actions' \
  -H 'Content-Type: application/json' \
  -d '{"action_type":"InstanceStart"}'

## You’ll see a minimal Linux VM booting instantly.

###Networking Simulation

### Fargate gives each task its own ENI. We’ll mimic this with a TAP device:

sudo ip tuntap add tap0 mode tap
sudo ip addr add 172.16.0.1/24 dev tap0
sudo ip link set tap0 up


### Attach it to Firecracker:

curl --unix-socket /tmp/firecracker.socket -i \
  -X PUT 'http://localhost/network-interfaces/eth0' \
  -H 'Content-Type: application/json' \
  -d '{"iface_id":"eth0","host_dev_name":"tap0","guest_mac":"02:FC:00:00:00:01"}'


### Inside the VM, bring up eth0 and assign an IP. Now the microVM talks to the host — exactly how a Fargate task talks to your VPC.

Mapping Back to Fargate

  • Firecracker VM → Your Fargate task’s isolated runtime.

  • RootFS → Base container environment + ECS runtime + your container image.

  • TAP device → Equivalent of a VPC ENI.

  • API config → ECS Scheduler telling Fargate what to run.

Architecture

flowchart TD
    subgraph LocalLab["Local Firecracker Lab"]
        subgraph Firecracker["MicroVM"]
            Kernel[Linux Kernel]
            RootFS[RootFS + Container Runtime]
            IF1[eth0 (TAP)]
        end
        Host["Linux Host"] --> Tap[tap0]
        Tap --> IF1
    end

    subgraph AWSFargate["AWS Fargate Analogy"]
        subgraph Task1["Fargate Task"]
            MVM1[Firecracker microVM]
            ENI1[ENI (VPC IP)]
        end
        VPC1[VPC Subnet + Security Group]
    end

    Tap -. maps to .-> ENI1
    Firecracker -. maps to .-> MVM1
    Host -. maps to .-> VPC1

Takeaways

  • Each Fargate task is a microVM, not just a container.

  • ENI-per-task makes tasks first-class citizens in your VPC.

  • Running Firecracker locally shows why Fargate cold starts exist.

  • Debugging ENIs locally helps anticipate VPC IP exhaustion issues.


Conclusion

By running Firecracker locally, you’ve just recreated the core of ECS Fargate. Every time you launch a task in AWS, the same steps happen — at massive scale, across AWS’s hidden fleet.

In Part 3, we’ll dive into real-world gotchas: ENI scaling limits, cold start tuning, and how observability works when you don’t control the host.