At Least One AWS Backup Plan Exists
Overview
This check verifies that your AWS account has at least one AWS Backup plan configured. A backup plan defines when and how your resources are backed up, including schedules, retention policies, and which resources to protect.
Even if you have backup vaults, this check will fail if no backup plan is configured to actually create recovery points.
Risk
Without a backup plan, your AWS resources are not automatically protected. This creates several risks:
- Data loss: Accidental deletions or data corruption cannot be recovered
- Extended outages: No restore capability means longer recovery times during incidents
- Compliance gaps: Many regulations require documented backup and recovery procedures
- Operational risk: Manual backups are error-prone and easily forgotten
Remediation Steps
Prerequisites
You need permission to create AWS Backup plans. Typically this requires the AWSBackupFullAccess managed policy or equivalent permissions.
Required IAM permissions (technical detail)
At minimum, you need these permissions:
backup:CreateBackupPlanbackup:CreateBackupVault(if you need a new vault)backup:CreateBackupSelection(to assign resources to the plan)iam:PassRole(for the backup service role)
AWS Console Method
-
Open the AWS Backup console
-
In the left navigation, click Backup plans
-
Click Create backup plan
-
Choose how to create your plan:
- Start with a template (recommended for beginners) - Uses AWS pre-built schedules
- Build a new plan - Full customization
- Define a plan using JSON - For advanced users
-
If using a template:
- Select a template (e.g., "Daily-35day-Retention" for daily backups kept 35 days)
- Enter a Backup plan name (e.g.,
my-daily-backup-plan) - Click Create plan
-
After creating the plan, you need to assign resources:
- Click your new backup plan
- Under Resource assignments, click Assign resources
- Give the assignment a name (e.g.,
critical-resources) - Choose how to select resources:
- Include all resource types - Backs up everything
- Include specific resource types - Pick specific services (EC2, RDS, EFS, etc.)
- Optionally filter by tags (e.g., only resources tagged
Backup=true) - Select or create an IAM role for AWS Backup to use
- Click Assign resources
-
Your backup plan is now active and will run on the defined schedule
AWS CLI
Step 1: Create a backup plan
aws backup create-backup-plan \
--region us-east-1 \
--backup-plan '{
"BackupPlanName": "DailyBackupPlan",
"Rules": [
{
"RuleName": "DailyRule",
"TargetBackupVaultName": "Default",
"ScheduleExpression": "cron(0 5 ? * * *)",
"StartWindowMinutes": 480,
"CompletionWindowMinutes": 720,
"Lifecycle": {
"DeleteAfterDays": 35
}
}
]
}'
This creates a plan that:
- Runs daily at 5:00 AM UTC
- Stores backups in the "Default" vault
- Retains backups for 35 days
Save the BackupPlanId from the output for the next step.
Step 2: Assign resources to the plan
aws backup create-backup-selection \
--region us-east-1 \
--backup-plan-id <your-backup-plan-id> \
--backup-selection '{
"SelectionName": "AllTaggedResources",
"IamRoleArn": "arn:aws:iam::<your-account-id>:role/service-role/AWSBackupDefaultServiceRole",
"Resources": ["*"],
"Conditions": {
"StringEquals": [
{
"ConditionKey": "aws:ResourceTag/Backup",
"ConditionValue": "true"
}
]
}
}'
Replace:
<your-backup-plan-id>with the ID from Step 1<your-account-id>with your AWS account ID
This example backs up all resources tagged with Backup=true.
CloudFormation
AWSTemplateFormatVersion: '2010-09-09'
Description: AWS Backup Plan with daily backups and 35-day retention
Resources:
BackupVault:
Type: AWS::Backup::BackupVault
Properties:
BackupVaultName: MyBackupVault
BackupPlan:
Type: AWS::Backup::BackupPlan
Properties:
BackupPlan:
BackupPlanName: DailyBackupPlan
BackupPlanRule:
- RuleName: DailyBackupRule
TargetBackupVault: !Ref BackupVault
ScheduleExpression: cron(0 5 ? * * *)
StartWindowMinutes: 480
CompletionWindowMinutes: 720
Lifecycle:
DeleteAfterDays: 35
BackupRole:
Type: AWS::IAM::Role
Properties:
RoleName: AWSBackupServiceRole
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service: backup.amazonaws.com
Action: sts:AssumeRole
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSBackupServiceRolePolicyForBackup
- arn:aws:iam::aws:policy/service-role/AWSBackupServiceRolePolicyForRestores
BackupSelection:
Type: AWS::Backup::BackupSelection
Properties:
BackupPlanId: !Ref BackupPlan
BackupSelection:
SelectionName: TaggedResources
IamRoleArn: !GetAtt BackupRole.Arn
ListOfTags:
- ConditionType: STRINGEQUALS
ConditionKey: Backup
ConditionValue: 'true'
Outputs:
BackupPlanId:
Description: The ID of the backup plan
Value: !Ref BackupPlan
BackupVaultArn:
Description: The ARN of the backup vault
Value: !GetAtt BackupVault.BackupVaultArn
Deploy with:
aws cloudformation deploy \
--region us-east-1 \
--template-file backup-plan.yaml \
--stack-name backup-plan-stack \
--capabilities CAPABILITY_NAMED_IAM
Terraform
# Backup vault to store recovery points
resource "aws_backup_vault" "main" {
name = "my-backup-vault"
}
# Backup plan with daily schedule
resource "aws_backup_plan" "daily" {
name = "daily-backup-plan"
rule {
rule_name = "daily-backup-rule"
target_vault_name = aws_backup_vault.main.name
schedule = "cron(0 5 ? * * *)"
start_window = 480
completion_window = 720
lifecycle {
delete_after = 35
}
}
}
# IAM role for AWS Backup
resource "aws_iam_role" "backup" {
name = "aws-backup-service-role"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Action = "sts:AssumeRole"
Effect = "Allow"
Principal = {
Service = "backup.amazonaws.com"
}
}
]
})
}
resource "aws_iam_role_policy_attachment" "backup" {
role = aws_iam_role.backup.name
policy_arn = "arn:aws:iam::aws:policy/service-role/AWSBackupServiceRolePolicyForBackup"
}
resource "aws_iam_role_policy_attachment" "restore" {
role = aws_iam_role.backup.name
policy_arn = "arn:aws:iam::aws:policy/service-role/AWSBackupServiceRolePolicyForRestores"
}
# Assign resources by tag
resource "aws_backup_selection" "tagged_resources" {
name = "tagged-resources"
plan_id = aws_backup_plan.daily.id
iam_role_arn = aws_iam_role.backup.arn
selection_tag {
type = "STRINGEQUALS"
key = "Backup"
value = "true"
}
}
output "backup_plan_id" {
value = aws_backup_plan.daily.id
}
Deploy with:
terraform init
terraform plan
terraform apply
Verification
After creating your backup plan, verify it exists:
- Go to AWS Backup console > Backup plans
- Confirm your backup plan appears in the list
- Click the plan and verify resources are assigned under Resource assignments
Verify with AWS CLI
# List all backup plans
aws backup list-backup-plans --region us-east-1
# Get details of a specific plan
aws backup get-backup-plan \
--region us-east-1 \
--backup-plan-id <your-backup-plan-id>
# Verify resources are assigned
aws backup list-backup-selections \
--region us-east-1 \
--backup-plan-id <your-backup-plan-id>
Re-run Prowler to confirm the check now passes:
prowler aws --check backup_plans_exist
Additional Resources
- AWS Backup Documentation - Creating a Backup Plan
- AWS Backup Pricing
- AWS Backup Supported Resources
- AWS Backup Best Practices
Notes
-
Cost considerations: AWS Backup charges for storage consumed by recovery points. Review pricing before enabling backups across many resources.
-
Default vault: AWS creates a "Default" backup vault in each region. You can use this or create custom vaults with specific encryption keys.
-
Cross-region and cross-account: For disaster recovery, consider enabling copy rules to replicate backups to another region or AWS account.
-
Resource tagging strategy: Using tags like
Backup=truelets you control which resources are backed up without modifying the backup plan each time you add resources. -
Testing restores: Having backups is only half the solution. Regularly test restore procedures to ensure backups are usable when needed.