Skip to main content
emnode
Site Reliability

Protect EBS volumes with AWS Backup

EBS volumes not covered by any backup plan or DLM policy have no recovery path. Wire up coverage by tag and verify.

13 min·10 sections·AWS

Last reviewed

Unprotected EBS volumes: the basics

What does "unprotected" actually mean?

An EBS volume is the persistent block storage backing an EC2 instance (or sitting detached, waiting to be attached). It holds the operating system, the application binaries, sometimes the database. Anything you can't afford to recreate from scratch lives on one of these. EBS itself is replicated across multiple devices within a single Availability Zone, which protects against hardware failure but not against the things that actually destroy data in production: accidental deletion, ransomware, a bad migration, a corrupted filesystem, or a region going dark.

An EBS volume is considered "unprotected" when two conditions are both true: there are no AWS Backup recovery points for it within the last N days (typically 1-7 depending on your RPO), and there is no Data Lifecycle Manager (DLM) policy whose tag selector matches it. No recovery point and no policy means no snapshot schedule, which means no recovery path. The volume could be holding the only copy of last quarter's customer data and you wouldn't know until the day you needed to roll back.

Continuity check COV-002 ("Unprotected EBS Volumes") flags this per-volume with HIGH severity. The check isn't about whether a backup ever existed, older one-off snapshots don't count. It's specifically about active, scheduled coverage going forward, because a single ad-hoc snapshot from six months ago is not a recovery strategy.

In this lesson you'll learn the precise definition the continuity check uses, the two AWS mechanisms for scheduled EBS coverage (AWS Backup vs DLM) and when each is the right choice, how to wire up tag-based selection so coverage scales without per-volume work, and how to run the audit query that finds the gap between volumes-that-exist and volumes-that-have-recovery-points. You'll also see what a restore actually looks like in practice, because untested backups are barely better than no backups.

Fun fact

Snapshots are not log shipping

A common assumption is that an EBS snapshot taken every hour gives you a 1-hour RPO. It doesn't: it gives you a 1-hour RPO at best, and only for the volume contents at the instant the snapshot was triggered. Anything written in the interval between snapshots is gone. For a busy MySQL instance on EBS with hourly snapshots, that's potentially 59 minutes of orders, payments, and audit rows you cannot get back. If your RPO is sub-hour, EBS snapshots are the wrong tool, you need RDS automated backups (5-minute point-in-time) or application-level log shipping.

Wiring up coverage in action

Marco is the on-call SRE at a healthcare startup. The 6am continuity report shows 47 EBS volumes flagged by COV-002 across the production account. Severity HIGH on every one of them. Among the flagged volumes: vol-0d2c8f4a1b3e9c7f0, a 500GB gp3 volume attached to an instance running the patient-records service.

He starts by asking the obvious question: does any volume in the flagged set have any recovery point at all? He runs a cross-reference between every EC2 volume in the account and the protected resources AWS Backup currently tracks.

The gap is wider than he expected: 47 volumes exist, but AWS Backup is only tracking 31 of them as protected resources. The other 16, including the patient-records volume, have nothing: no DLM policy match, no backup plan match, no recovery points in the last 24 hours.

First, list every EBS volume the account owns. The query slices to ID, size, state, and the BackupRequired tag: the tag-based selector the backup plan should be using.

$ aws ec2 describe-volumes --query "Volumes[*].{Id:VolumeId,Size:Size,State:State,Backup:Tags[?Key=='BackupRequired']|[0].Value}" --output table
┌─────────────────────────┬──────┬───────────┬────────┐
│ Id │ Size │ State │ Backup │
├─────────────────────────┼──────┼───────────┼────────┤
│ vol-0a1b2c3d4e5f6a7b8 │ 100 │ in-use │ true │
│ vol-0d2c8f4a1b3e9c7f0 │ 500 │ in-use │ None │
│ vol-0e7f1a2c3d4b5a6c7 │ 50 │ in-use │ true │
│ vol-0f8c2b9a3d1e4f5b6 │ 200 │ available │ None │
│ vol-0c1d2e3f4a5b6c7d8 │ 1000 │ in-use │ false │
└─────────────────────────┴──────┴───────────┴────────┘
# Two volumes with no BackupRequired tag at all: those are the candidates for COV-002 flags.

Volumes that have no BackupRequired tag are invisible to a tag-based backup plan.

Now cross-reference against AWS Backup. list-protected-resources returns every resource AWS Backup currently has a plan covering; anything missing from this list is unprotected.

$ aws backup list-protected-resources --query "Results[?ResourceType=='EBS'].{Arn:ResourceArn,LastBackup:LastBackupTime}" --output table
┌──────────────────────────────────────────────────────────────┬──────────────────────┐
│ Arn │ LastBackup │
├──────────────────────────────────────────────────────────────┼──────────────────────┤
│ arn:aws:ec2:eu-west-1:123456789012:volume/vol-0a1b2c3d4e5f6a7b8 │ 2026-05-15T03:14:00Z │
│ arn:aws:ec2:eu-west-1:123456789012:volume/vol-0e7f1a2c3d4b5a6c7 │ 2026-05-15T03:14:00Z │
└──────────────────────────────────────────────────────────────┴──────────────────────┘
# vol-0d2c8f4a1b3e9c7f0 (patient-records, 500GB) does not appear here: confirmed unprotected.

The patient-records volume exists in EC2 but has no AWS Backup coverage.

EBS coverage under the hooddeep dive

AWS gives you two scheduled-backup mechanisms for EBS, and they overlap enough to be confusing. EBS Data Lifecycle Manager (DLM) is the older, simpler option: you define a policy that targets volumes (or instances) by tag, set a schedule and retention, and DLM creates EBS snapshots on that cadence. It's free apart from snapshot storage. A single DLM snapshot policy can copy snapshots cross-region (via a CrossRegionCopyRule), but cross-account copy requires a separate event-based policy, and DLM has no point-in-time across resources and no audit reporting framework.

AWS Backup is the newer, broader service: same underlying snapshot mechanism for EBS, but wrapped in a full lifecycle: backup plans with cron-style schedules, cross-region and cross-account copy, vault locks for write-once retention, Backup Audit Manager for compliance reports, and a unified API across EBS, RDS, EFS, DynamoDB, FSx, S3, and more. For EBS specifically the warm-storage rate is the same $0.05/GB-month as native EBS snapshots, so there's no per-resource storage premium (the extra costs come mainly from restores, cross-region transfer, and cold tiering) and there's slightly more setup. For anything that needs cross-account copy, vault-lock immutability, or audit evidence, AWS Backup is the right tool. For a single-region (or single-policy cross-region), simple-retention use case where you only ever back up EBS, DLM is fine.

AWS Backup targets resources at the granularity you choose. You can put an entire EC2 instance in a backup plan (which captures the instance plus all attached EBS volumes as a single recovery point) or target the volumes directly. Volume-level targeting gives you more granular restore (one bad volume can be restored without touching the instance) and is the right default for anything other than "this whole instance is a snowflake." Tag-based selection is what makes coverage scale: the plan says "every resource with BackupRequired=true," and you enforce that tag via Service Catalog, Terraform module defaults, or an SCP that denies untagged volume creation.

# A minimal backup plan: daily at 03:00 UTC, 35-day retention, selects every resource tagged BackupRequired=true.
aws backup create-backup-plan --backup-plan '{
  "BackupPlanName": "daily-tagged-resources",
  "Rules": [{
    "RuleName": "daily-35d",
    "TargetBackupVaultName": "Default",
    "ScheduleExpression": "cron(0 3 ? * * *)",
    "StartWindowMinutes": 60,
    "CompletionWindowMinutes": 240,
    "Lifecycle": { "DeleteAfterDays": 35 }
  }]
}'

# Assign every BackupRequired=true resource to that plan.
aws backup create-backup-selection \
  --backup-plan-id <plan-id-from-above> \
  --backup-selection '{
    "SelectionName": "tagged-resources",
    "IamRoleArn": "arn:aws:iam::123456789012:role/service-role/AWSBackupDefaultServiceRole",
    "ListOfTags": [{ "ConditionType": "STRINGEQUALS", "ConditionKey": "BackupRequired", "ConditionValue": "true" }]
  }'

What is the impact of leaving EBS volumes unprotected?

The most direct impact is data loss when something goes wrong. An accidental terminate-instance on an instance with DeleteOnTermination=true wipes the volume; a runaway script that does dd if=/dev/zero of=/dev/nvme1n1 corrupts it; ransomware encrypts every file on it. Without a recovery point, the data is gone, and gone means rebuilding from whatever upstream source you can find, which for a database with a week of accumulated transactions usually means "we cannot."

The second-order impact is compliance. HIPAA, SOC 2, ISO 27001, and PCI DSS all require demonstrable backup procedures with documented RPO and RTO. A volume that an auditor finds without backup coverage isn't just a technical risk; it's an audit finding that says "the control they claim to have isn't working." Backup Audit Manager exists specifically to produce the evidence chain that satisfies these auditors, and it only works if coverage exists in the first place.

The third-order impact is incident time. When a recovery is needed, the question isn't "do we have a backup?"; that should be a known yes. The question is "what's the most recent recovery point, and how long will the restore take?" Teams without scheduled coverage spend the first hours of an incident answering the first question instead of executing the restore, which extends the outage window enormously.

On the financial side, EBS snapshot storage is cheap: roughly $0.05/GB-month for the incremental snapshot data, which is typically a fraction of the volume size after the initial baseline. A 500GB volume with daily snapshots and 35-day retention typically costs $10-30/month in snapshot storage. The cost of not backing up is whatever the data is worth on the day it disappears, which is invariably much, much higher.

How do you protect EBS volumes safely?

Closing the unprotected-volume gap is a four-step loop. It runs continuously as the fleet grows because new volumes appear faster than humans can enumerate them.

1. Inventory the gap with a cross-reference query

Pull every EBS volume from the account, pull every protected EBS resource from AWS Backup, diff them. Anything in the first set missing from the second is unprotected: that's the working list. Do this per-account and per-region; AWS Backup is regional, and a cross-region setup needs a copy rule, not a separate plan.

2. Tag the gap and let the plan absorb it

Rather than adding volumes to a backup plan one by one, apply the standard selection tag (BackupRequired=true is the common convention) to every flagged volume. The next plan execution picks them up automatically. If the gap is large, do this via a tag-update script that walks the inventory output from step 1; manual tagging at scale is how volumes get missed.

3. Verify the next backup window actually produces a recovery point

Tagging a volume does not protect it; running the plan against the volume protects it. After the next scheduled window, re-run list-protected-resources and confirm the previously-unprotected volumes now appear with a LastBackupTime in the last 24 hours. Don't trust the plan definition alone; trust the recovery point that the definition produced.

4. Prevent recurrence by making the tag mandatory at creation time

Enforce BackupRequired as a required tag at volume creation via Service Catalog, the Terraform module everyone uses, or a tag-policy/SCP that denies ec2:CreateVolume without it. The default value in your IaC module should be true; opting out of backups should require a deliberate choice, not opting in. Pair this with AWS Backup Audit Manager so you get continuous evidence that the policy is working.

# Tag the unprotected patient-records volume so the existing tag-based plan picks it up.
aws ec2 create-tags \
  --resources vol-0d2c8f4a1b3e9c7f0 \
  --tags Key=BackupRequired,Value=true

# Trigger an on-demand backup so you don't wait until the next scheduled window.
aws backup start-backup-job \
  --backup-vault-name Default \
  --resource-arn arn:aws:ec2:eu-west-1:123456789012:volume/vol-0d2c8f4a1b3e9c7f0 \
  --iam-role-arn arn:aws:iam::123456789012:role/service-role/AWSBackupDefaultServiceRole \
  --lifecycle DeleteAfterDays=35

# When it's time to recover, a restore comes back as a new volume in 'available' state: attach it manually.
aws backup start-restore-job \
  --recovery-point-arn arn:aws:backup:eu-west-1:123456789012:recovery-point:1EB3B5E7-9EB0-435A-A80B-108B488B0D45 \
  --iam-role-arn arn:aws:iam::123456789012:role/service-role/AWSBackupDefaultServiceRole \
  --metadata 'volumeType=gp3,encrypted=true,availabilityZone=eu-west-1a'

Quick quiz

Question 1 of 5

Continuity check COV-002 has flagged 12 EBS volumes as unprotected. Your backup plan already exists with a tag-based selection on BackupRequired=true. What's the most effective remediation?

You've completed Protect EBS volumes with AWS Backup. You know the exact definition the continuity check uses, when to reach for AWS Backup vs DLM, how to scale coverage through tag-based selection, and how to verify that a plan actually produces recovery points. The next time COV-002 fires with HIGH severity on a stack of unprotected volumes, you'll have a four-step loop ready to run: inventory, tag, verify, prevent.

Back to the library