EBS
Elastic Block Store (EBS) is the persistent block storage attached to EC2 instances. Picking the right volume type — gp3 (general-purpose SSD, default), io2 (high-IOPS SSD), st1 (throughput HDD for streams), sc1 (cold) — is one of the biggest single levers on AWS cost. Default new fleets to gp3 with explicit IOPS and throughput targets.
gp3/io2 patterns: create, snapshot, resize, encrypt
EXAMPLE
# 1) gp3 is the modern default — independent IOPS + throughput, cheaper than gp2
aws ec2 create-volume \
--availability-zone ap-southeast-2a \
--volume-type gp3 \
--size 100 \
--iops 6000 \
--throughput 250 \
--encrypted \
--tag-specifications 'ResourceType=volume,Tags=[{Key=Name,Value=app-data},{Key=env,Value=prod}]'
# Why gp3 wins over gp2
# - gp2 ties IOPS to size (3 IOPS/GB). To get 12k IOPS on gp2, you buy 4 TB.
# - gp3 lets you buy 100 GB AND ask for 12k IOPS, paying separately.
# - gp3 baseline (3000 IOPS / 125 MB/s) is free; the rest scales linearly.
# 2) io2 / io2 Block Express — for databases that need sustained high IOPS
aws ec2 create-volume --availability-zone ap-southeast-2a \
--volume-type io2 --size 200 --iops 12000 --encrypted
# 3) Encryption — set a default at the account level so new volumes are encrypted
aws ec2 enable-ebs-encryption-by-default
aws ec2 modify-ebs-default-kms-key-id --kms-key-id alias/aws/ebs
# 4) Snapshot for backup / DR
aws ec2 create-snapshot --volume-id vol-0abc1234 \
--description 'pre-migration snapshot 2026-06-18' \
--tag-specifications 'ResourceType=snapshot,Tags=[{Key=app,Value=shop-db}]'
# Copy across regions (for DR)
aws ec2 copy-snapshot --source-region ap-southeast-2 --source-snapshot-id snap-abc \
--destination-region us-west-2 --encrypted
# 5) Restore — create a new volume from a snapshot
aws ec2 create-volume --availability-zone ap-southeast-2a --snapshot-id snap-abc \
--volume-type gp3
# 6) Online resize — gp3 / io2 volumes can grow without detach
aws ec2 modify-volume --volume-id vol-0abc1234 --size 300 --iops 8000 --throughput 250
# Then on the instance:
# sudo growpart /dev/xvdf 1 # repartition
# sudo resize2fs /dev/xvdf1 # ext4 (or xfs_growfs / for XFS)
# 7) Attach / detach
aws ec2 attach-volume --volume-id vol-0abc1234 --instance-id i-0xyz --device /dev/xvdf
aws ec2 detach-volume --volume-id vol-0abc1234
# 8) Lifecycle Manager — automatic snapshot schedule
# Console: EBS -> Lifecycle Manager -> Create policy
# Or via the CLI:
aws dlm create-lifecycle-policy \
--description 'daily-snapshots' \
--state ENABLED \
--execution-role-arn arn:aws:iam::123456789012:role/AWSDataLifecycleManagerDefaultRole \
--policy-details file://dlm.json
# dlm.json: keep 7 daily + 4 weekly + 3 monthly, tag-targeted
# 9) Monitor what really matters
# CloudWatch metrics: VolumeQueueLength (saturation), VolumeReadOps / WriteOps, BurstBalance (gp2 only).
# Alert on:
# - VolumeQueueLength > 1 for 10m -> volume is the bottleneck
# - BurstBalance < 10% (gp2) -> move to gp3 yesterday
# 10) Cost tip — kill the cruft
# Detached volumes still bill. Periodic sweep:
aws ec2 describe-volumes --filters Name=status,Values=available \
--query 'Volumes[].{Id:VolumeId,Size:Size,Created:CreateTime}' --output table
Why it matters
Almost every gp2 volume in your account is a free upgrade waiting for a sweep. gp3 is cheaper for the same baseline performance and lets you ask for more IOPS without paying for extra storage. A morning of `aws ec2 modify-volume --volume-type gp3` calls on the right volumes is one of the highest ROI maintenance afternoons available.
Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.
Discussion
Loading…