EC2
05 / 08

Instances, AMIs & Instance Types

AWS EC2: Instances, AMIs & Instance Types

EC2 (Elastic Compute Cloud) provides resizable virtual machines in the cloud. You choose the OS, CPU, memory, and storage. Unlike Lambda or Fargate, you manage the server.

AMIs (Amazon Machine Images)

An AMI is a template containing the OS, pre-installed software, and configuration used to launch an instance. AMIs are region-specific.

  • AWS-provided AMIs: Amazon Linux 2023, Ubuntu 22.04/24.04 LTS, Windows Server, RHEL, SUSE

  • AWS Marketplace: vendor AMIs (pre-configured Nginx, Bitnami stacks, SAP, etc.) — may have extra licensing cost

  • Custom AMIs: create from a running instance after installing your software — fastest way to launch identical instances

  • Community AMIs: public AMIs from the community — use with caution (verify publisher)

# Find latest Amazon Linux 2023 AMI
aws ssm get-parameter \
  --name /aws/service/ami-amazon-linux-latest/al2023-ami-kernel-default-x86_64 \
  --query Parameter.Value --output text

# Find Ubuntu 24.04 LTS
aws ec2 describe-images \
  --owners 099720109477 \
  --filters "Name=name,Values=ubuntu/images/hvm-ssd-gp3/ubuntu-noble-24.04-amd64-server-*" \
  --query 'sort_by(Images, &CreationDate)[-1].ImageId'

# Create AMI from running instance
aws ec2 create-image \
  --instance-id i-abc123 \
  --name "my-app-ami-v2" \
  --description "App server with Node.js 20 and nginx" \
  --no-reboot

Instance Type Naming

Format: <family><generation><attributes>.<size>

c7g.xlarge:
  c  = Compute-optimized family
  7  = 7th generation
  g  = Graviton (ARM) processor
  xl = xlarge (4 vCPU, 8 GB RAM)

Families:
  t  — Burstable general purpose (t3, t4g): dev/test, low baseline, burst CPU credits
  m  — General purpose (m6i, m7g): balanced CPU/RAM, most workloads
  c  — Compute optimized (c7g, c7i): CPU-intensive (ML inference, encoding, gaming)
  r  — Memory optimized (r7g, r7i): in-memory DBs, big data (up to 768 GB RAM)
  x  — Memory extreme (x2idn): SAP HANA, huge in-memory (up to 3 TB RAM)
  i  — Storage optimized (i4i): high IOPS NVMe SSDs, Cassandra, Redis
  g/p — GPU instances: ML training (p4), graphics rendering (g5)
  inf — AWS Inferentia: ML inference at low cost

Suffixes:
  a = AMD EPYC, g = Graviton (ARM), i = Intel Ice Lake
  d = local NVMe SSD, n = enhanced network, e = extra storage/RAM

Launching Instances

# Launch an instance
aws ec2 run-instances \
  --image-id ami-0abcdef1234567890 \
  --instance-type t3.medium \
  --key-name my-keypair \
  --security-group-ids sg-abc123 \
  --subnet-id subnet-private-1a \
  --iam-instance-profile Name=my-app-instance-profile \
  --block-device-mappings '[{
    "DeviceName": "/dev/xvda",
    "Ebs": {"VolumeSize": 30, "VolumeType": "gp3", "DeleteOnTermination": true}
  }]' \
  --user-data file://init.sh \
  --metadata-options "HttpTokens=required,HttpEndpoint=enabled" \
  --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=app-server},{Key=Env,Value=prod}]' \
  --count 1

# Wait until running
aws ec2 wait instance-running --instance-ids i-abc123

User Data (Cloud-Init)

#!/bin/bash
# user-data script — runs as root on first boot
set -euo pipefail

# Update and install
dnf update -y
dnf install -y nginx git

# Install Node.js via nvm
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash
source /root/.nvm/nvm.sh
nvm install 20
nvm use 20

# Start nginx
systemctl enable --now nginx

# Signal CloudFormation or ASG that init is complete
/opt/aws/bin/cfn-signal -e $? --stack my-stack --resource MyASG --region eu-west-1

Instance Metadata Service (IMDSv2)

# IMDSv2: token-based (required, more secure than v1)
# Get token
TOKEN=$(curl -X PUT "http://169.254.169.254/latest/api/token" \
  -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")

# Use token to query metadata
curl -H "X-aws-ec2-metadata-token: $TOKEN" \
  http://169.254.169.254/latest/meta-data/instance-id

curl -H "X-aws-ec2-metadata-token: $TOKEN" \
  http://169.254.169.254/latest/meta-data/iam/security-credentials/my-role

# Get region from metadata
REGION=$(curl -s -H "X-aws-ec2-metadata-token: $TOKEN" \
  http://169.254.169.254/latest/meta-data/placement/region)

Keep your own version of these notes — editable, searchable, and organised by your stack.

Start free