Skip to main content

Check if RDS Instances Are Protected by a Backup Plan

Overview

This check verifies that your Amazon RDS database instances are included in an AWS Backup plan. AWS Backup provides centralized, automated backup management with scheduled backups, retention policies, and cross-region copy capabilities.

Note: This check applies to non-Aurora RDS instances. Aurora databases are evaluated separately.

Risk

Without a backup plan, your RDS instances are vulnerable to:

  • Data loss from accidental deletion or corruption
  • Extended outages when recovery is needed but no recent backup exists
  • Missed recovery objectives (RPO/RTO) during incidents
  • Compliance violations for regulations requiring backup policies

Remediation Steps

Prerequisites

You need:

  • AWS Console access with permissions to manage AWS Backup and IAM roles
  • The ARN of the RDS instance you want to protect
How to find your RDS instance ARN
  1. Go to the RDS Console
  2. Click Databases in the left menu
  3. Select your database instance
  4. In the Configuration tab, find the ARN field

The ARN format is: arn:aws:rds:us-east-1:123456789012:db:my-database

AWS Console Method

  1. Open the AWS Backup console at https://console.aws.amazon.com/backup/

  2. Enable RDS in AWS Backup (first time only):

    • Click Settings in the left menu
    • Under Service opt-in, click Configure resources
    • Ensure RDS is toggled On
    • Click Confirm
  3. Create or select a backup plan:

    • Click Backup plans in the left menu
    • Either select an existing plan or click Create backup plan
    • If creating new: choose Build a new plan, give it a name, and configure a backup rule (e.g., daily backups with 35-day retention)
  4. Assign your RDS instance to the plan:

    • In your backup plan, click Assign resources
    • Enter a Resource assignment name (e.g., rds-production-db)
    • For IAM role, select Default role or choose an existing role with backup permissions
    • Under Resource selection, choose Include specific resource types
    • Select RDS as the resource type
    • Choose All instances or select your specific database
    • Click Assign resources
  5. Your RDS instance is now protected by the backup plan.

AWS CLI (optional)

Step 1: Create a backup vault (if you don't have one)

aws backup create-backup-vault \
--backup-vault-name rds-backup-vault \
--region us-east-1

Step 2: Create a backup plan

aws backup create-backup-plan \
--backup-plan '{
"BackupPlanName": "rds-backup-plan",
"Rules": [{
"RuleName": "DailyBackup",
"TargetBackupVaultName": "rds-backup-vault",
"ScheduleExpression": "cron(0 5 ? * * *)",
"StartWindowMinutes": 60,
"CompletionWindowMinutes": 120,
"Lifecycle": {
"DeleteAfterDays": 35
}
}]
}' \
--region us-east-1

Note the BackupPlanId from the output.

Step 3: Assign the RDS instance to the backup plan

aws backup create-backup-selection \
--backup-plan-id <your-backup-plan-id> \
--backup-selection '{
"SelectionName": "rds-instance-selection",
"IamRoleArn": "arn:aws:iam::<account-id>:role/service-role/AWSBackupDefaultServiceRole",
"Resources": ["arn:aws:rds:us-east-1:<account-id>:db:<your-db-identifier>"]
}' \
--region us-east-1

Replace:

  • <your-backup-plan-id> with the ID from step 2
  • <account-id> with your AWS account ID
  • <your-db-identifier> with your RDS instance identifier
CloudFormation (optional)
AWSTemplateFormatVersion: '2010-09-09'
Description: AWS Backup plan for RDS instances

Parameters:
BackupPlanName:
Type: String
Default: rds-backup-plan
Description: Name of the backup plan
RDSInstanceArn:
Type: String
Description: ARN of the RDS instance to protect

Resources:
BackupVault:
Type: AWS::Backup::BackupVault
Properties:
BackupVaultName: !Sub '${BackupPlanName}-vault'

BackupPlan:
Type: AWS::Backup::BackupPlan
Properties:
BackupPlan:
BackupPlanName: !Ref BackupPlanName
BackupPlanRule:
- RuleName: DailyBackup
TargetBackupVault: !Ref BackupVault
ScheduleExpression: cron(0 5 ? * * *)
StartWindowMinutes: 60
CompletionWindowMinutes: 120
Lifecycle:
DeleteAfterDays: 35

BackupRole:
Type: AWS::IAM::Role
Properties:
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: rds-instance-selection
IamRoleArn: !GetAtt BackupRole.Arn
Resources:
- !Ref RDSInstanceArn

Outputs:
BackupPlanId:
Description: ID of the created backup plan
Value: !Ref BackupPlan
BackupVaultArn:
Description: ARN of the backup vault
Value: !GetAtt BackupVault.BackupVaultArn

Deploy the stack:

aws cloudformation create-stack \
--stack-name rds-backup-protection \
--template-body file://template.yaml \
--parameters ParameterKey=RDSInstanceArn,ParameterValue=arn:aws:rds:us-east-1:123456789012:db:my-database \
--capabilities CAPABILITY_IAM \
--region us-east-1
Terraform (optional)
variable "rds_instance_arn" {
description = "ARN of the RDS instance to protect"
type = string
}

variable "backup_plan_name" {
description = "Name of the backup plan"
type = string
default = "rds-backup-plan"
}

resource "aws_backup_vault" "rds_vault" {
name = "${var.backup_plan_name}-vault"
}

resource "aws_backup_plan" "rds_plan" {
name = var.backup_plan_name

rule {
rule_name = "DailyBackup"
target_vault_name = aws_backup_vault.rds_vault.name
schedule = "cron(0 5 ? * * *)"
start_window = 60
completion_window = 120

lifecycle {
delete_after = 35
}
}
}

resource "aws_iam_role" "backup_role" {
name = "${var.backup_plan_name}-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_policy" {
policy_arn = "arn:aws:iam::aws:policy/service-role/AWSBackupServiceRolePolicyForBackup"
role = aws_iam_role.backup_role.name
}

resource "aws_iam_role_policy_attachment" "restore_policy" {
policy_arn = "arn:aws:iam::aws:policy/service-role/AWSBackupServiceRolePolicyForRestores"
role = aws_iam_role.backup_role.name
}

resource "aws_backup_selection" "rds_selection" {
iam_role_arn = aws_iam_role.backup_role.arn
name = "rds-instance-selection"
plan_id = aws_backup_plan.rds_plan.id

resources = [
var.rds_instance_arn
]
}

output "backup_plan_id" {
description = "ID of the created backup plan"
value = aws_backup_plan.rds_plan.id
}

output "backup_vault_arn" {
description = "ARN of the backup vault"
value = aws_backup_vault.rds_vault.arn
}

Deploy:

terraform init
terraform apply -var="rds_instance_arn=arn:aws:rds:us-east-1:123456789012:db:my-database"

Verification

After remediation, verify your RDS instance is protected:

  1. Go to AWS Backup > Protected resources
  2. Filter by RDS resource type
  3. Confirm your database instance appears in the list
CLI verification

List protected resources:

aws backup list-protected-resources \
--region us-east-1 \
--query "Results[?ResourceType=='RDS']"

Check backup jobs for your instance:

aws backup list-backup-jobs \
--by-resource-arn arn:aws:rds:us-east-1:<account-id>:db:<your-db-identifier> \
--region us-east-1

Re-run the Prowler check:

prowler aws --check rds_instance_protected_by_backup_plan --region us-east-1

Additional Resources

Notes

  • RDS automated backups vs. AWS Backup: RDS has its own automated backup feature, but AWS Backup provides centralized management, cross-account/cross-region copies, and consistent retention policies across services.

  • Tag-based selection: For managing many databases, consider using tag-based resource selection instead of specifying individual ARNs. Tag all databases that need backup (e.g., backup=daily) and configure AWS Backup to select resources by tag.

  • Cost considerations: AWS Backup charges for backup storage. Review the pricing page to understand costs for your retention requirements.

  • Recovery testing: Periodically test restoring from backups to ensure your recovery process works as expected.