Back to Checks
DynamoDB table is protected by a backup plan
dynamodb_table_protected_by_backup_plan
Service: dynamodbSeverity: medium
OfficialBuilt-inVerified
Categories:resilience
Resource Type:AwsDynamoDbTable
DynamoDB tables are evaluated for inclusion in an AWS Backup backup plan through resource assignments, including explicit tables, resource-type wildcards, or all-resources coverage.
The result indicates whether a table is governed by scheduled backups and retention defined by the plan.
Risk
Without a backup plan, table data lacks governed copies, harming availability and integrity. Accidental deletes, corrupt writes, or malicious actions can become unrecoverable, and RPO/RTO worsen. You also forfeit cross-Region/account copies and immutability features, increasing downtime and data loss.
Run this check with Prowler
Run in Prowler CloudRun
prowler aws --checks dynamodb_table_protected_by_backup_planRecommendation
Place all critical tables under an AWS Backup backup plan following defense in depth and least privilege:
- Use tag-based assignments for coverage at scale
- Define schedules, retention, and cross-Region/account copies
- Enable Vault Lock for immutability
- Regularly test restores and restrict backup deletion
Remediation
Terraform
# Terraform: Add DynamoDB tables to an AWS Backup plan
resource "aws_backup_plan" "<example_resource_name>" {
name = "<example_resource_name>"
rule {
rule_name = "r"
target_vault_name = "Default"
}
}
data "aws_iam_role" "<example_resource_name>" {
name = "AWSServiceRoleForBackup"
}
resource "aws_backup_selection" "<example_resource_name>" {
name = "<example_resource_name>"
plan_id = aws_backup_plan.<example_resource_name>.id
iam_role_arn = data.aws_iam_role.<example_resource_name>.arn
resources = [
"arn:aws:dynamodb:*:*:table/*" # CRITICAL: adds all DynamoDB tables to the backup plan, making them protected
]
}NativeIaC
# CloudFormation: Add DynamoDB tables to an AWS Backup plan
Resources:
BackupPlan:
Type: AWS::Backup::BackupPlan
Properties:
BackupPlan:
BackupPlanName: <example_resource_name>
BackupPlanRule:
- RuleName: r
TargetBackupVault: Default
BackupSelection:
Type: AWS::Backup::BackupSelection
Properties:
BackupPlanId: !Ref BackupPlan
BackupSelection:
SelectionName: <example_resource_name>
IamRoleArn: <example_role_arn>
Resources:
- arn:aws:dynamodb:*:*:table/* # CRITICAL: adds all DynamoDB tables to the backup plan, making them protectedOther
1In the AWS Backup console, go to Settings > Configure resources and enable DynamoDB, then Confirm
2Go to Backup plans > Create backup plan > Build a new plan
3Enter a plan name, set Rule name to any value, set Backup vault to Default, and Create plan
4On the plan page, choose Assign resources
5Enter a Resource assignment name, set IAM role to Default role, select your DynamoDB table, and choose Assign resources
Check Code
from prowler.lib.check.models import Check, Check_Report_AWS
from prowler.providers.aws.services.backup.backup_client import backup_client
from prowler.providers.aws.services.dynamodb.dynamodb_client import dynamodb_client
class dynamodb_table_protected_by_backup_plan(Check):
def execute(self):
findings = []
for table in dynamodb_client.tables.values():
report = Check_Report_AWS(metadata=self.metadata(), resource=table)
report.status = "FAIL"
report.status_extended = (
f"DynamoDB table {table.name} is not protected by a backup plan."
)
if (
table.arn in backup_client.protected_resources
or f"arn:{dynamodb_client.audited_partition}:dynamodb:*:*:table/*"
in backup_client.protected_resources
or "*" in backup_client.protected_resources
):
report.status = "PASS"
report.status_extended = (
f"DynamoDB table {table.name} is protected by a backup plan."
)
findings.append(report)
return findings