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.
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
- Change the source URL in your module block to your framework subdomain
- Run
terraform init -upgradeto download the compliance.tf module - Run
terraform planto review changes. Expect a clean plan or validation errors for missing values - Fix validation errors if any (see Common Issues below)
- Run
terraform apply - Verify by checking
.compliancetf-manifest.jsonin.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 Version | compliance.tf Version | Status | Notes |
|---|---|---|---|
| v7.x | v7.x | Supported | Direct 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
- RDS DB instance automatic minor version upgrade should be enabled
- RDS DB instance backup should be enabled
- RDS DB instances backup retention period should be greater than or equal to 7
- RDS DB instances should be integrated with CloudWatch logs
- RDS DB instance encryption at rest should be enabled
- RDS DB instances should have iam authentication enabled
- RDS DB instances should have logging enabled
- RDS for MariaDB DB instances should publish logs to CloudWatch Logs
- RDS DB instances should not use public subnet
- RDS for PostgreSQL DB instances should publish logs to CloudWatch Logs
- RDS DB instances should prohibit public access
- RDS for SQL Server DB instances should publish logs to CloudWatch Logs
- RDS DB instance backup should be enabled
- RDS DB instances backup retention period should be greater than or equal to 7
- RDS DB instances should be integrated with CloudWatch logs
- RDS DB instances should be configured to copy tags to snapshots
- RDS DB instances should have deletion protection enabled
- RDS DB instance encryption at rest should be enabled
- RDS DB instances should have iam authentication enabled
- RDS DB instances should have logging enabled
- RDS for MariaDB DB instances should publish logs to CloudWatch Logs
- RDS DB instances should not use public subnet
- RDS for PostgreSQL DB instances should publish logs to CloudWatch Logs
- RDS DB instances should prohibit public access
- RDS for SQL Server DB instances should publish logs to CloudWatch Logs
Rollback
To revert, change the source URL back and re-initialize:
- Change source back to "terraform-aws-modules/rds/aws"
- Run terraform init -upgrade
- Run terraform plan to confirm no resource changes
- Compliance controls are no longer enforced, but existing configurations remain in place