RDS instance has deletion protection enabled
RDS DB instances are assessed for deletion protection. If an instance belongs to an Aurora cluster, the setting is evaluated at the cluster level; otherwise, it is evaluated on the instance itself.
Risk
Without deletion protection, a user or pipeline can delete a database in one action, causing immediate loss of availability and possible data loss if backups are stale or missing. This heightens exposure to insider misuse, compromised credentials, or faulty automation, increasing recovery time and cost.
Run this check with Prowler
Run in Prowler Cloudprowler aws --checks rds_instance_deletion_protectionRecommendation
Enable deletion protection on production RDS instances and Aurora clusters. Enforce least privilege for delete/modify actions and require change control to disable protection. Use defense in depth with reliable backups and tested restores to limit impact if a deletion occurs.
Remediation
CLI
aws rds modify-db-instance --db-instance-identifier <db_instance_id> --deletion-protection --apply-immediatelyTerraform
# Enable deletion protection on a standalone RDS instance
resource "aws_db_instance" "<example_resource_name>" {
deletion_protection = true # Critical: prevents instance deletion
}
# Enable deletion protection on an RDS/Aurora cluster
resource "aws_rds_cluster" "<example_resource_name>" {
deletion_protection = true # Critical: prevents cluster deletion (required for instances in this cluster)
}NativeIaC
# CloudFormation: enable deletion protection
Resources:
<example_db_instance_name>:
Type: AWS::RDS::DBInstance
Properties:
DeletionProtection: true # Critical: enables deletion protection for standalone instances
<example_db_cluster_name>:
Type: AWS::RDS::DBCluster
Properties:
DeletionProtection: true # Critical: enables deletion protection at cluster level (required for Aurora members)Other
Check Code
from prowler.lib.check.models import Check, Check_Report_AWS
from prowler.providers.aws.services.rds.rds_client import rds_client
class rds_instance_deletion_protection(Check):
def execute(self):
findings = []
for db_instance in rds_client.db_instances.values():
report = Check_Report_AWS(metadata=self.metadata(), resource=db_instance)
# Check if is member of a cluster
if db_instance.cluster_id:
if (
db_instance.cluster_arn in rds_client.db_clusters
and rds_client.db_clusters[
db_instance.cluster_arn
].deletion_protection
):
report.status = "PASS"
report.status_extended = f"RDS Instance {db_instance.id} deletion protection is enabled at cluster {db_instance.cluster_id} level."
else:
report.status = "FAIL"
report.status_extended = f"RDS Instance {db_instance.id} deletion protection is not enabled at cluster {db_instance.cluster_id} level."
else:
if db_instance.deletion_protection:
report.status = "PASS"
report.status_extended = (
f"RDS Instance {db_instance.id} deletion protection is enabled."
)
else:
report.status = "FAIL"
report.status_extended = f"RDS Instance {db_instance.id} deletion protection is not enabled."
findings.append(report)
return findings