Skip to content

Migrate RDS

RDS database instance module with compliance controls for encryption at rest, backup retention, deletion protection, IAM authentication, CloudWatch logging, and public access restrictions. Encryption at rest may require a snapshot-restore cycle if not already enabled.

Minor Fixes15-30 minutes per instance

Before and After

The migration is a source URL change. Your arguments, outputs, and Terraform state remain the same.

Before (terraform-aws-modules):

module "rds" {
  source  = "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"

  tags = {
    Environment = "production"
  }
}

After (compliance.tf / PCI DSS v4.0):

module "rds" {
  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"

  tags = {
    Environment = "production"
  }
}

Before (terraform-aws-modules):

module "rds" {
  source  = "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"

  tags = {
    Environment = "production"
  }
}

After (compliance.tf / SOC 2):

module "rds" {
  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"

  tags = {
    Environment = "production"
  }
}

What Changes

  • Source URL points to compliance.tf registry
  • Compliance controls are enforced via validation rules
  • terraform plan will fail if required controls are not satisfied

What Stays the Same

  • All input variables (same interface as upstream terraform-aws-modules)
  • All output values
  • Resource addresses in Terraform state
  • Provider configuration
  • Version constraints

Step-by-Step Migration

  1. Change the source URL in your module block to your framework subdomain
  2. Run terraform init -upgrade to download the compliance.tf module
  3. Run terraform plan to review changes. Expect a clean plan or validation errors for missing values
  4. Fix validation errors if any (see Common Issues below)
  5. Run terraform apply
  6. Verify by checking .compliancetf-manifest.json in .terraform/modules/

Common Issues and Fixes

Storage encryption requires snapshot-restore cycle

Cause: Encrypting an existing unencrypted RDS instance is not supported by AWS as an in-place operation. The storage_encrypted control will fail if the instance is not already encrypted.

Fix: Create an encrypted snapshot of the existing instance, restore from the encrypted snapshot, then update the Terraform state. Alternatively, disable the control temporarily and plan the encryption retrofit separately.

Missing backup retention period

Cause: The rds_db_instance_backup_enabled control requires backup_retention_period >= 1 (typically 7). Many development configurations set this to 0.

Fix: Set backup_retention_period = 7 (or higher based on your retention policy).

Missing CloudWatch log exports

Cause: The rds_db_instance_logging_enabled control requires enabled_cloudwatch_logs_exports to be set. Available log types depend on the database engine (MySQL: audit, error, general, slowquery; PostgreSQL: postgresql, upgrade).

Fix: Add enabled_cloudwatch_logs_exports with the appropriate log types for your engine.

Deletion protection not enabled

Cause: The rds_db_instance_deletion_protection_enabled control (SOC 2) requires deletion_protection = true. Development instances often have this disabled.

Fix: Set deletion_protection = true. This can be applied in-place without downtime.

Auto minor version upgrade not enabled (PCI DSS only)

Cause: The rds_db_instance_automatic_minor_version_upgrade_enabled control requires auto_minor_version_upgrade = true. This is a PCI DSS v4.0 requirement not present in SOC 2.

Fix: Set auto_minor_version_upgrade = true. Applied during the next maintenance window.

Version Compatibility

Upstream Versioncompliance.tf VersionStatusNotes
v7.xv7.xSupportedDirect swap. Adapter version constraint: >=7.0.0

State Impact

No terraform state mv needed in typical cases. Resource addresses are unchanged because compliance.tf modules use the same internal resource structure as upstream. If a compliance control adds a new resource (rare), terraform plan will show the addition.

Controls Enforced

Rollback

To revert, change the source URL back and re-initialize:

  1. Change source back to "terraform-aws-modules/rds/aws"
  2. Run terraform init -upgrade
  3. Run terraform plan to confirm no resource changes
  4. Compliance controls are no longer enforced, but existing configurations remain in place

Migration Guide | Compatibility | RDS Module