AWS Security Hub · RDS
RDS.8: RDS DB instances should have deletion protection
Written and reviewed by Emnode · Last reviewed
What does AWS Security Hub RDS.8 check?
RDS.8 checks whether the DeletionProtection flag is enabled on each standalone RDS DB instance (MySQL, MariaDB, PostgreSQL, Oracle, SQL Server). It reports FAILED for any such instance without the flag set.
Why does RDS.8 matter?
A delete on RDS is one of the few genuinely irreversible cloud operations the moment it completes, and the flag defaults to off: an instance from a Terraform module, a CloudFormation template, or a hurried console wizard arrives unprotected. The failure mode is silent until catastrophic: a protected and unprotected instance behave identically every normal day, and you only discover the difference at the exact moment a delete-db-instance would have gone through. The severity rating reflects likelihood, not blast radius; the thing it prevents is a deleted production database.
How do I fix RDS.8?
- Enable it with modify-db-instance --deletion-protection.
- Set the safe default in the IaC templates that create instances, since an unprotected instance usually signals templates spawning other unprotected resources too.
- Track the count of production instances failing the control toward zero.
- Disable protection only as a deliberate logged step when an instance must genuinely be deleted.
Remediation script · bash
# Enable deletion protection on every unprotected standalone RDS instance in a region.
for id in $(aws rds describe-db-instances \
--query 'DBInstances[?DeletionProtection==`false`].DBInstanceIdentifier' --output text); do
aws rds modify-db-instance --db-instance-identifier "$id" \
--deletion-protection --apply-immediately
echo "Protected RDS instance: $id"
done
# Termination-protect every production-tagged CloudFormation stack (eyeball the list first).
aws cloudformation describe-stacks \
--query "Stacks[?Tags[?Key=='Environment' && Value=='production']].StackName" \
--output text | tr '\t' '\n' | while read -r stack; do
aws cloudformation update-termination-protection \
--stack-name "$stack" --enable-termination-protection
echo "Protected stack: $stack"
done
# Deletion-protect a production load balancer.
aws elbv2 modify-load-balancer-attributes --load-balancer-arn "$LB_ARN" \
--attributes Key=deletion_protection.enabled,Value=true Full walkthrough (console steps, edge cases and verification) in the lesson Enable deletion and termination protection.
Is RDS.8 a false positive?
An instance that is meant to be disposable (a per-pull-request test database, an ephemeral restore-and-validate instance, or a scratch instance an automation pipeline creates and deletes on every run) will fail this control, yet enabling deletion protection on it would break the very automation that owns its lifecycle, since a delete-db-instance call is rejected until protection is first turned off. The right response is a documented exception, not a fix: scope a Security Hub suppression rule by a tag like lifecycle=ephemeral, with the owner and a review date recorded, so the disposable fleet stops generating noise while every long-lived production instance stays in scope. Suppress only the instances that are genuinely throwaway, never blanket-suppress the control.
More RDS controls
- RDS.1 An RDS snapshot is shared publicly
- RDS.2 An RDS instance is publicly accessible from the internet
- RDS.3 RDS DB instances should be encrypted at rest
- RDS.4 RDS snapshots should be encrypted at rest
- RDS.5 RDS DB instances should use multiple AZs
- RDS.6 RDS lacks enhanced monitoring
- RDS.7 RDS clusters should have deletion protection
- RDS.9 RDS engine logs are not shipped to CloudWatch
- RDS.10 RDS relies on long-lived database passwords
- RDS.11 RDS instances should have automatic backups
- RDS.12 IAM auth should be configured for RDS clusters
- RDS.13 RDS is not receiving automatic minor security patches