Are your EC2 instances actually backed up? How to check
Last reviewed
Ask a small team whether their servers are backed up and the answer is usually yes.
Ask when the last snapshot was taken and the room goes quiet.
When we pointed our own scanner at a real production account, 6 of 8 running
servers had at least one disk with no snapshot — none of them could be fully
restored. One production server's newest snapshot was 295 days old. Nobody had decided that. It had just never
been set up — or been set up once and quietly stopped.
What "backed up" means for EC2
An EC2 instance doesn't get backed up. Its EBS volumes do, as snapshots. AWS
does not snapshot anything automatically — no snapshot exists unless you, a
script, Data Lifecycle Manager or AWS Backup created one.
Two things people miss:
A server is only as protected as its least-protected disk. If an instance has
a root disk with daily snapshots and a data disk with none, you cannot restore that
server. You can restore its operating system, with none of its data.
An old snapshot is a partial backup. A 30-day-old snapshot restores a server
as it was 30 days ago. Everything since is lost.
How to check every running instance
For each running instance in a region, this lists every attached disk and the date
of its newest completed snapshot:
r=us-east-1
for i in $(aws ec2 describe-instances --region "$r" \
--filters Name=instance-state-name,Values=running \
--query 'Reservations[].Instances[].InstanceId' --output text); do
echo "== $i"
for v in $(aws ec2 describe-volumes --region "$r" \
--filters Name=attachment.instance-id,Values="$i" \
--query 'Volumes[].VolumeId' --output text); do
latest=$(aws ec2 describe-snapshots --region "$r" --owner-ids self \
--filters Name=volume-id,Values="$v" Name=status,Values=completed \
--query 'sort_by(Snapshots, &StartTime)[-1].StartTime' --output text)
echo -e " $v\t$latest"
done
doneHow to read it:
Nonenext to any disk — that disk has never been snapshotted. The server can't be fully restored.- A date — that's how far back a restore would take you. The oldest date across a server's disks is the one that counts.
Run it for each region you use. Servers in a second region are exactly the ones
nobody remembers to check.
How to fix it
Automate snapshots — don't rely on doing it by hand. The simplest free option is
Amazon Data Lifecycle Manager (you pay only for the snapshots):
- Tag the volumes you want protected, e.g.
Backup = daily - EC2 console → Lifecycle Manager → Create lifecycle policy
- Target volumes with that tag, schedule daily, keep the last 7
AWS Backup does the same with more control — cross-region copies, longer
retention, and RDS and other services in one place.
Snapshot all of a server's disks together. Separate snapshots taken minutes apart
can leave a database and its log disk out of step. This captures every attached
volume at the same moment:
aws ec2 create-snapshots \
--instance-specification InstanceId=i-0123456789abcdef0,ExcludeBootVolume=false \
--description "all disks, one point in time"Test a restore at least once. A snapshot that exists is not the same as a
restore that works. Create a volume from a recent snapshot, attach it to a test
instance and check the data is really there.
Knowing, every week
Setting up snapshots is a one-off job. Noticing when they stop — a policy
deleted, a tag missed on a new disk, a new server nobody added — is the part that
fails silently.
Devopsly checks on every sync. Connect your AWS account read-only and it grades
every running server by its least-protected disk: critical if any attached disk
has no snapshot, warning if the newest snapshot covering every disk is more than
7 days old. It also checks the backup retention on your RDS databases.
It tells you what isn't protected. It doesn't run restore tests for you — that part
is still worth doing yourself.
It uses 15 read-only IAM actions and never touches your infrastructure or opens your
files.