EC2: API reference
Run EC2 instances as Docker containers locally. SSH in, run user data scripts, enforce security groups. Real containers, real networking, no AWS account needed.
Want a runnable walkthrough? See EC2: demo & walkthrough.
EC2 backend selector
# EC2_VM_MANAGER=docker is the default; this is just for clarity:
$ EC2_VM_MANAGER=docker localemu start
# Opt out of real containers for metadata-only mode:
$ EC2_VM_MANAGER=none localemu start EC2_VM_MANAGER=docker is the default; every run-instances call already launches a real Docker container. Set EC2_VM_MANAGER=none to switch to metadata-only mode (the AWS API surface still responds, but no container is created).
AMI IDs
LocalEmu ships a built-in AMI ID to Docker image map (services/ec2/docker/ami_mapping.py). Use any of these IDs with run-instances --image-id. Unknown AMI IDs fall back to localemu/ec2-base:v3; you can register a custom image by tagging it as localemu-ec2/<ami-id>.
| AMI ID | Docker image | Notes |
|---|---|---|
ami-ubuntu-22.04 | localemu/ec2-base:v3 | LocalEmu-managed Ubuntu base. sshd, iptables, curl, awscli, postgresql-client, mysql-client baked in. |
ami-localemu-ubuntu | localemu/ec2-base:v3 | Alias of ami-ubuntu-22.04. |
ami-ubuntu-24.04 | ubuntu:24.04 | Bare upstream image: no sshd, no LocalEmu tooling. |
ami-ubuntu-20.04 | ubuntu:20.04 | Bare upstream image. |
ami-amazon-linux-2023 (alias: ami-al2023) | amazonlinux:2023 | Bare upstream image. |
ami-amazon-linux-2 | amazonlinux:2 | Bare upstream image. |
ami-debian-12 | debian:12 | Bare upstream image. |
ami-debian-11 | debian:11 | Bare upstream image. |
ami-alpine-3.20 | alpine:3.20 | Bare upstream image. |
ami-alpine-3.18 | alpine:3.18 | Bare upstream image. |
ami-centos-9 | quay.io/centos/centos:stream9 | Bare upstream image. |
For SSH-driven workflows (the default for localemu ssh, the user-data demo, the transit-gateway tutorial) stick to ami-ubuntu-22.04: it boots with sshd already running. The bare upstream images do not include an SSH server and will not respond on port 22 without a custom user-data script.
Instance Types and Resource Limits
Each instance type maps to Docker container memory limits.
| Instance Type | Memory Limit |
|---|---|
t2.nano | 512 MB |
t2.micro | 1 GB |
t2.small | 2 GB |
t2.medium | 4 GB |
t2.large | 8 GB |
SSH Access
Create a key pair, launch an instance with it, then SSH in using the mapped port.
Create a key pair
$ awsemu ec2 create-key-pair --key-name my-key --query 'KeyMaterial' --output text > my-key.pem
$ chmod 400 my-key.pem Launch an instance
$ awsemu ec2 run-instances \
--image-id ami-ubuntu-22.04 \
--instance-type t2.micro \
--key-name my-key
InstanceId: i-abc123def456
State: pending Get the SSH port from the localemu:ssh-port tag
$ awsemu ec2 describe-tags \
--filters "Name=resource-id,Values=i-abc123def456" \
"Name=key,Values=localemu:ssh-port"
Tags:
- Key: localemu:ssh-port
Value: 22022 Connect via SSH
$ ssh -i my-key.pem -p 22022 root@localhost localemu ssh Command
The localemu ssh command provides a shortcut to connect to EC2 instances without manually looking up ports.
$ localemu ssh i-abc123def456
$ localemu ssh --list
i-abc123def456 running ami-ubuntu-22.04 t2.micro port:22022 SSM Session Manager
Start an interactive session using SSM. No SSH keys required.
$ awsemu ssm start-session --target i-abc123def456 User Data
Pass a startup script with --user-data. The script runs automatically when the container boots.
$ awsemu ec2 run-instances \
--image-id ami-ubuntu-22.04 \
--instance-type t2.small \
--key-name my-key \
--user-data file://setup.sh Instance Metadata Service (IMDS)
A per-VPC IMDS sidecar serves the full /latest/meta-data/ tree (instance-id, ami-id, instance-type, local hostname + IP, IAM credentials, ...) and is reachable from inside the container two ways: an iptables OUTPUT-chain DNAT rule rewrites every packet to the link-local 169.254.169.254:80 address that boto3 / awscli / the AWS SDKs hardcode, and the AWS_EC2_METADATA_SERVICE_ENDPOINT env var is also injected for the small set of clients that honour it. Both paths land on the same sidecar.
Security Groups
Security group rules are enforced via a TCP proxy. Rules are evaluated at connection time. Changes from AuthorizeSecurityGroupIngress take effect immediately.
$ awsemu ec2 create-security-group \
--group-name web-sg \
--description "Allow HTTP"
GroupId: sg-abc123
$ awsemu ec2 authorize-security-group-ingress \
--group-id sg-abc123 \
--protocol tcp \
--port 80 \
--cidr 0.0.0.0/0 Container Naming
Each EC2 instance runs in a Docker container named localemu-ec2-<instance-id>.
$ docker ps --filter "label=localemu.service=ec2"
CONTAINER ID IMAGE STATUS NAMES
a1b2c3d4e5f6 localemu/ec2-base:v3 Up 2 min localemu-ec2-i-abc123def456 Instance Lifecycle
EC2 instances follow the standard lifecycle. Each state maps to a Docker container state.