RDS clusters should have deletion protection enabled
Accidental cluster deletion destroys all automated snapshots and can cause permanent data loss if no manual snapshots exist. Deletion protection adds a deliberate two-step process: an operator must first disable the flag, then issue the delete call. This friction prevents fat-finger mistakes, overly broad IAM teardown scripts, and malicious deletions from compromised credentials.
In production environments running Aurora or DocumentDB, a single aws rds delete-db-cluster call without this guard can wipe hours or days of data that falls between your last manual snapshot and the deletion event. The cost of enabling this setting is zero; the cost of not enabling it is an outage.
Retrofit consideration
Enabling deletion_protection on an existing cluster triggers a modification that applies immediately with no downtime, but Terraform will show a plan diff for every unprotected cluster.
Implementation
Choose the approach that matches how you manage Terraform.
Use the compliance.tf module to enforce this control by default. See get started with compliance.tf.
module "rds_aurora" {
source = "nistcsf.compliance.tf/terraform-aws-modules/rds-aurora/aws"
version = ">=10.0.0,<11.0.0"
create_db_subnet_group = true
create_security_group = true
engine = "aurora-mysql"
engine_version = "8.0.mysql_aurora.3.08.0"
instances = {
one = {
instance_class = "db.t4g.medium"
}
}
manage_master_user_password = true
master_username = "root"
name = "abc123"
skip_final_snapshot = true
subnets = ["subnet-12345678", "subnet-12345678"]
vpc_id = "vpc-12345678"
}
module "rds_aurora" {
source = "nistcsfv11.compliance.tf/terraform-aws-modules/rds-aurora/aws"
version = ">=10.0.0,<11.0.0"
create_db_subnet_group = true
create_security_group = true
engine = "aurora-mysql"
engine_version = "8.0.mysql_aurora.3.08.0"
instances = {
one = {
instance_class = "db.t4g.medium"
}
}
manage_master_user_password = true
master_username = "root"
name = "abc123"
skip_final_snapshot = true
subnets = ["subnet-12345678", "subnet-12345678"]
vpc_id = "vpc-12345678"
}
If you use terraform-aws-modules/rds-aurora/aws, set the right module inputs for this control. You can later migrate to the compliance.tf module with minimal changes because it is compatible by design.
module "rds_aurora" {
source = "terraform-aws-modules/rds-aurora/aws"
version = ">=10.0.0,<11.0.0"
create_db_subnet_group = true
create_security_group = true
engine = "aurora-mysql"
engine_version = "8.0.mysql_aurora.3.08.0"
instances = {
one = {
instance_class = "db.t4g.medium"
}
}
manage_master_user_password = true
master_username = "root"
name = "abc123"
skip_final_snapshot = true
subnets = ["subnet-12345678", "subnet-12345678"]
vpc_id = "vpc-12345678"
deletion_protection = true
}
Use AWS provider resources directly. See docs for the resources involved: aws_rds_cluster.
resource "aws_rds_cluster" "this" {
backtrack_window = 72
cluster_identifier = "pofix-abc123"
db_subnet_group_name = "example-db-subnet-group"
enabled_cloudwatch_logs_exports = ["audit"]
engine = "aurora-mysql"
engine_version = "8.0.mysql_aurora.3.08.0"
manage_master_user_password = true
master_username = "dbadmin"
skip_final_snapshot = true
vpc_security_group_ids = ["sg-12345678"]
deletion_protection = true
}
What this control checks
For aws_rds_cluster resources, deletion_protection must be set to true. When omitted, the AWS provider defaults it to false, and the cluster fails. The same argument applies to aws_docdb_cluster and aws_neptune_cluster resources; the control evaluates those cluster types too. Explicitly set deletion_protection = true on every cluster resource. Either false or an omitted argument is a failing evaluation.
Common pitfalls
Default is false when argument is omitted
The
aws_rds_clusterresource defaultsdeletion_protectiontofalseif you don't declare it. There's no provider-level override to change this default. Every cluster definition needsdeletion_protection = trueset explicitly.Terraform destroy requires a two-step process
When
deletion_protection = true,terraform destroywill fail: the API rejects the delete call. You'll need to setdeletion_protection = false, apply, then destroy. This is intentional, but it catches teams off guard during dev/test teardown.DocumentDB and Neptune clusters evaluated separately
Findings will appear for
aws_docdb_clusterandaws_neptune_clusterresources as well asaws_rds_cluster. Setdeletion_protection = trueon all three resource types, or suppress the findings in Security Hub for services that are genuinely out of scope.Cluster vs. instance confusion
Aurora instances (
aws_rds_cluster_instance) don't have adeletion_protectionargument. The setting lives onaws_rds_clusteronly. You can still delete individual instances from a protected cluster; the protection only blocks deleting the cluster itself.
Audit evidence
The primary evidence is AWS Config rule results for rds-cluster-deletion-protection-enabled showing COMPLIANT status across all applicable clusters. aws rds describe-db-clusters output should show "DeletionProtection": true on every cluster object. If Security Hub is in use, there should be no active FAILED findings for this control.
For change-level evidence, CloudTrail ModifyDBCluster and CreateDBCluster events should show DeletionProtection set to true, confirming the setting was applied at provisioning or remediation.
Framework-specific interpretation
NIST Cybersecurity Framework v2.0: PR.DS covers protecting data from loss, corruption, or unauthorized access. Deletion protection is a preventive control directly in scope: it blocks unauthorized or accidental removal of data stored in RDS clusters without requiring any additional tooling.
Related controls
Tool mappings
Use these identifiers to cross-reference this control across tools, reports, and evidence.
Compliance.tf Control:
rds_db_cluster_deletion_protection_enabledAWS Config Managed Rule:
RDS_CLUSTER_DELETION_PROTECTION_ENABLEDCheckov Check:
CKV_AWS_139Powerpipe Control:
aws_compliance.control.rds_db_cluster_deletion_protection_enabledProwler Checks:
rds_cluster_deletion_protection,rds_instance_deletion_protectionAWS Security Hub Controls:
DocumentDB.5,Neptune.4,RDS.7Trivy Checks:
AWS-0177,AWS-0343
Last reviewed: 2026-03-09