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
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.