EBS Volume Has At Least One Snapshot
Overview
This check verifies that each Amazon EBS (Elastic Block Store) volume has at least one snapshot. Snapshots are point-in-time backups of your EBS volumes stored in Amazon S3, enabling you to recover data if something goes wrong.
Risk
Severity: High
EBS volumes without snapshots have no backup protection. If the volume is accidentally deleted, becomes corrupted, or is affected by ransomware, you could experience:
- Permanent data loss with no way to recover
- Extended service outages while rebuilding systems from scratch
- Compliance violations for regulations requiring data backup (HIPAA, SOC 2, etc.)
Creating at least one snapshot ensures you have a recovery point available when you need it.
Remediation Steps
Prerequisites
- AWS Console access with permissions to create EBS snapshots
- The Volume ID of the EBS volume that needs a snapshot (looks like
vol-0123456789abcdef0)
AWS Console Method
- Open the Amazon EC2 console
- In the left navigation, click Volumes (under Elastic Block Store)
- Select the checkbox next to the volume that needs a snapshot
- Click the Actions dropdown menu
- Select Create snapshot
- Enter a Description (e.g., "Initial backup snapshot")
- (Optional) Add tags to help organize your snapshots
- Click Create snapshot
The snapshot will appear in the Snapshots section with a status of "pending" until it completes.
AWS CLI (optional)
Create a snapshot for a single volume
aws ec2 create-snapshot \
--region us-east-1 \
--volume-id vol-0123456789abcdef0 \
--description "Initial backup snapshot"
Create a snapshot with tags
aws ec2 create-snapshot \
--region us-east-1 \
--volume-id vol-0123456789abcdef0 \
--description "Production database backup" \
--tag-specifications 'ResourceType=snapshot,Tags=[{Key=Name,Value=prod-db-snapshot},{Key=Environment,Value=production}]'
Find all volumes without snapshots
This command identifies volumes that have never been backed up:
# Get all volume IDs
ALL_VOLUMES=$(aws ec2 describe-volumes \
--region us-east-1 \
--query 'Volumes[*].VolumeId' \
--output text)
# Get volumes that have snapshots
VOLUMES_WITH_SNAPSHOTS=$(aws ec2 describe-snapshots \
--region us-east-1 \
--owner-ids self \
--query 'Snapshots[*].VolumeId' \
--output text | tr '\t' '\n' | sort -u)
# Compare to find volumes without snapshots
for vol in $ALL_VOLUMES; do
if ! echo "$VOLUMES_WITH_SNAPSHOTS" | grep -q "$vol"; then
echo "Volume without snapshot: $vol"
fi
done
Create snapshots for all unprotected volumes
for vol in $ALL_VOLUMES; do
if ! echo "$VOLUMES_WITH_SNAPSHOTS" | grep -q "$vol"; then
echo "Creating snapshot for: $vol"
aws ec2 create-snapshot \
--region us-east-1 \
--volume-id "$vol" \
--description "Initial backup snapshot" \
--tag-specifications "ResourceType=snapshot,Tags=[{Key=Name,Value=${vol}-snapshot},{Key=CreatedBy,Value=remediation-script}]"
fi
done
CloudFormation (optional)
CloudFormation can create a one-time snapshot. For ongoing automated snapshots, see the Automated Snapshot Scheduling section below.
AWSTemplateFormatVersion: '2010-09-09'
Description: EBS Snapshot for backup and recovery
Parameters:
VolumeId:
Type: String
Description: The ID of the EBS volume to snapshot
SnapshotDescription:
Type: String
Default: "Automated EBS snapshot for backup"
Description: Description for the snapshot
Resources:
EBSSnapshot:
Type: AWS::EC2::Snapshot
Properties:
VolumeId: !Ref VolumeId
Description: !Ref SnapshotDescription
Tags:
- Key: Name
Value: !Sub "${VolumeId}-snapshot"
- Key: CreatedBy
Value: CloudFormation
Outputs:
SnapshotId:
Description: The ID of the created snapshot
Value: !Ref EBSSnapshot
Deploy the template:
aws cloudformation create-stack \
--region us-east-1 \
--stack-name ebs-snapshot-remediation \
--template-body file://template.yaml \
--parameters ParameterKey=VolumeId,ParameterValue=vol-0123456789abcdef0
Terraform (optional)
Single snapshot
variable "volume_id" {
description = "The ID of the EBS volume to snapshot"
type = string
}
variable "description" {
description = "Description for the snapshot"
type = string
default = "Automated EBS snapshot for backup"
}
variable "tags" {
description = "Tags to apply to the snapshot"
type = map(string)
default = {}
}
resource "aws_ebs_snapshot" "this" {
volume_id = var.volume_id
description = var.description
tags = merge(
{
"Name" = "${var.volume_id}-snapshot"
},
var.tags
)
}
output "snapshot_id" {
description = "The ID of the created snapshot"
value = aws_ebs_snapshot.this.id
}
Apply the configuration:
terraform init
terraform apply -var="volume_id=vol-0123456789abcdef0"
Multiple volumes
variable "volume_ids" {
description = "List of EBS volume IDs to snapshot"
type = list(string)
}
resource "aws_ebs_snapshot" "volumes" {
for_each = toset(var.volume_ids)
volume_id = each.value
description = "Automated backup snapshot"
tags = {
Name = "${each.value}-snapshot"
ManagedBy = "Terraform"
}
}
output "snapshot_ids" {
description = "Map of volume IDs to snapshot IDs"
value = { for k, v in aws_ebs_snapshot.volumes : k => v.id }
}
Automated Snapshot Scheduling (recommended)
Creating a single snapshot addresses the immediate finding, but you should set up automated snapshots to maintain ongoing protection.
Using Amazon Data Lifecycle Manager (DLM)
DLM automates snapshot creation on a schedule. Here is a CloudFormation template:
AWSTemplateFormatVersion: '2010-09-09'
Description: Automated EBS snapshot lifecycle policy
Parameters:
TargetTagKey:
Type: String
Default: "Backup"
Description: Tag key to identify volumes for backup
TargetTagValue:
Type: String
Default: "true"
Description: Tag value to identify volumes for backup
RetentionCount:
Type: Number
Default: 7
Description: Number of snapshots to retain
Resources:
SnapshotLifecyclePolicy:
Type: AWS::DLM::LifecyclePolicy
Properties:
Description: Daily EBS snapshots with 7-day retention
State: ENABLED
ExecutionRoleArn: !GetAtt DLMRole.Arn
PolicyDetails:
ResourceTypes:
- VOLUME
TargetTags:
- Key: !Ref TargetTagKey
Value: !Ref TargetTagValue
Schedules:
- Name: DailySnapshots
CreateRule:
Interval: 24
IntervalUnit: HOURS
Times:
- "03:00"
RetainRule:
Count: !Ref RetentionCount
CopyTags: true
DLMRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service: dlm.amazonaws.com
Action: sts:AssumeRole
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSDataLifecycleManagerServiceRole
After deploying this policy, tag your EBS volumes with Backup=true to include them in automated snapshots.
Using Terraform with DLM
resource "aws_dlm_lifecycle_policy" "ebs_backup" {
description = "Daily EBS snapshot policy"
execution_role_arn = aws_iam_role.dlm_role.arn
state = "ENABLED"
policy_details {
resource_types = ["VOLUME"]
target_tags = {
Backup = "true"
}
schedule {
name = "Daily snapshots"
create_rule {
interval = 24
interval_unit = "HOURS"
times = ["03:00"]
}
retain_rule {
count = 7
}
copy_tags = true
}
}
}
resource "aws_iam_role" "dlm_role" {
name = "dlm-lifecycle-role"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Principal = {
Service = "dlm.amazonaws.com"
}
Action = "sts:AssumeRole"
}
]
})
}
resource "aws_iam_role_policy_attachment" "dlm_policy" {
role = aws_iam_role.dlm_role.name
policy_arn = "arn:aws:iam::aws:policy/service-role/AWSDataLifecycleManagerServiceRole"
}
Verification
After creating a snapshot, verify it exists:
- In the EC2 console, go to Snapshots (under Elastic Block Store)
- Search for your volume ID in the search bar
- Confirm the snapshot shows a status of completed
CLI verification
# Check if a specific volume has snapshots
aws ec2 describe-snapshots \
--region us-east-1 \
--owner-ids self \
--filters "Name=volume-id,Values=vol-0123456789abcdef0" \
--query 'Snapshots[*].[SnapshotId,StartTime,State]' \
--output table
Expected output shows at least one snapshot with state completed:
------------------------------------------------------------
| DescribeSnapshots |
+---------------------------+---------------------+---------+
| snap-0123456789abcdef0 | 2024-01-15T10:30:00|completed|
+---------------------------+---------------------+---------+
Additional Resources
- Amazon EBS Snapshots User Guide
- Amazon Data Lifecycle Manager
- AWS Backup for EBS
- EBS Snapshot Pricing
Notes
-
Snapshot costs: You pay for the storage used by snapshots. The first snapshot of a volume copies all data; subsequent snapshots are incremental and only store changed blocks.
-
Encryption: Snapshots of encrypted volumes are automatically encrypted. Snapshots of unencrypted volumes are unencrypted by default but can be copied with encryption enabled.
-
Cross-region copies: For disaster recovery, consider copying critical snapshots to another AWS region.
-
Snapshot completion time: Large volumes may take hours to complete their first snapshot. The volume remains usable during this time.
-
Application consistency: For databases and applications that write to disk, consider stopping writes or using application-consistent snapshot methods (like VSS for Windows or database-specific backup commands) before creating snapshots.