Sign in
Menu
Sign up
Docs
Adopt in an existing estateMigration kit

RDS

For an engineer moving an existing RDS from terraform-aws-modules to compliance.tf. The controls cover encryption at rest, backup retention, deletion protection, IAM authentication, log exports and public access. When you finish, terraform plan passes with the compliance.tf source.

Minor to significant · 15-30 minutes per instance, or hours if the instance must be rebuilt for encryption · No state moves, unless an unencrypted instance has to be rebuilt · Upstream v7.x

Before you start

  • A registry token, set up as in Registry tokens. The registry host for each framework is on Registry endpoints.
  • An upstream version inside the supported range (v7.x). Older versions: upgrade upstream first, see Version compatibility.
  • State: No terraform state mv. Resource addresses stay the same, because compliance.tf modules keep the upstream resource structure. If a control adds a resource, the plan shows it as an addition. One exception: an unencrypted instance has to be rebuilt to pass the encryption control (see the fix below).
  • Not sure if this module should go first? The Migration kit tells you where to start. The Assessment checklist finds risks before you plan.

Change the source

The diff changes the source and adds the settings this module's controls need, so the plan passes. Replace the referenced resources (aws_...) with your own.

 module "rds" {
-  source  = "terraform-aws-modules/rds/aws"
+  source  = "soc2.compliance.tf/terraform-aws-modules/rds/aws"
   version = "~> 7.0"

   identifier = "my-app-db"

   engine         = "mysql"
   engine_version = "8.0"
   instance_class = "db.t3.micro"

   allocated_storage = 20
   db_name           = "myapp"
   username          = "dbadmin"

+  storage_encrypted                   = true
+  backup_retention_period             = 7
+  deletion_protection                 = true
+  copy_tags_to_snapshot               = true
+  iam_database_authentication_enabled = true
+  publicly_accessible                 = false
+  enabled_cloudwatch_logs_exports     = ["audit", "error", "general", "slowquery"]
+
   tags = {
     Environment = "production"
   }
 }
 module "rds" {
-  source  = "terraform-aws-modules/rds/aws"
+  source  = "pcidss.compliance.tf/terraform-aws-modules/rds/aws"
   version = "~> 7.0"

   identifier = "my-app-db"

   engine         = "mysql"
   engine_version = "8.0"
   instance_class = "db.t3.micro"

   allocated_storage = 20
   db_name           = "myapp"
   username          = "dbadmin"

+  storage_encrypted                   = true
+  backup_retention_period             = 7
+  deletion_protection                 = true
+  iam_database_authentication_enabled = true
+  publicly_accessible                 = false
+  auto_minor_version_upgrade          = true
+  enabled_cloudwatch_logs_exports     = ["audit", "error", "general", "slowquery"]
+
   tags = {
     Environment = "production"
   }
 }

Then download the new source and plan. terraform init installs a module whose source changed; -upgrade is only for fetching the same source and version again:

terraform init
terraform plan

After init, .terraform/modules/<module name>/compliancetf-manifest.json names the framework the module was built for.

Fix the plan errors

Each error names the control and links its page, which lists the frameworks that map it. These are the ones this module raises most often.

The existing instance is not encrypted

AWS cannot encrypt an existing unencrypted RDS instance in place. Setting storage_encrypted = true on it makes Terraform plan to replace the instance. Control: rds_db_instance_encryption_at_rest_enabled.

Take a snapshot, copy it with encryption, restore a new instance from the encrypted copy and move the state to it. Until then, turn the control off for this instance and record why.

storage_encrypted = true

Backup retention is 0

The control requires automated backups. Development configurations often set backup_retention_period = 0. Control: rds_db_instance_backup_enabled.

Set a retention period of at least 7 days, or longer if your retention policy says so.

backup_retention_period = 7

No CloudWatch log exports

The control requires enabled_cloudwatch_logs_exports. The log types depend on the engine: audit, error, general and slowquery for MySQL; postgresql and upgrade for PostgreSQL. Control: rds_db_instance_logging_enabled.

List the log types for your engine.

enabled_cloudwatch_logs_exports = ["audit", "error", "general", "slowquery"]

Deletion protection is off (SOC 2 only)

The control requires deletion_protection = true. Development instances often have it off. Control: rds_db_instance_deletion_protection_enabled.

Turn it on. AWS applies it in place, without downtime.

deletion_protection = true

Automatic minor version upgrades are off (PCI DSS v4.0 only)

PCI DSS v4.0 maps this control; SOC 2 does not. Control: rds_db_instance_automatic_minor_version_upgrade_enabled.

Turn it on. AWS applies the next minor version in the maintenance window.

auto_minor_version_upgrade = true

A control that does not apply to this instance can be turned off on the source URL; see Turn controls on and off.

Controls this enforces

SOC 2

PCI DSS v4.0

Each framework also maps controls that this module does not enforce. Those stay with your team; the module page lists enforced and mapped-only controls apart.

Roll back

  1. Point the source back at terraform-aws-modules/rds/aws, keeping the same version constraint.
  2. Run terraform init.
  3. Run terraform plan. Expect no resource changes: the values you added stay in place, but compliance.tf no longer checks them.

Next steps

On this page

Ask AI about this

Help improve this page