How can I encrypt an existing RDS PostgreSQL database provisioned and managed using the CDK?


We have an RDS PostgreSQL database.

It was provisioned, and continues to be managed, via the AWS CDK (so ultimately a generated CloudFormation template).

Unfortunately by default the CDK DatabaseInstance has storageEncrypted set to false, and we now have a lot of real data in an instance with unencrypted storage.

We want to encrypt it. The tutorials we have found all assume manual management via the AWS console, involving promoting a different database to be the production one. This does not seem to play well with the CDK, where for instance security groups & secrets for ECS tasks that need access to the database are automatically managed by DatabaseInstance.connections.allowDefaultPortFrom and DatabaseInstance.secret.

Does anyone have a guide for how to achieve this for a CDK provisioned and managed database?


1 Answer

To encrypt an existing RDS PostgreSQL database provisioned and managed via AWS CDK, you can follow these steps:

Update CDK Code: Modify your CDK code to include the storageEncrypted property set to true for the DatabaseInstance construct.

import * as rds from '@aws-cdk/aws-rds';

const dbInstance = new rds.DatabaseInstance(stack, 'MyDatabase', {
  engine: rds.DatabaseInstanceEngine.postgres({
    version: rds.PostgresEngineVersion.VER_13,
  // Other properties...
  storageEncrypted: true, // Ensure storage encryption is enabled

Deploy Changes: Deploy the updated CDK stack that includes the changes to enable storage encryption for the RDS instance.

cdk deploy

Snapshot Backup: Take a snapshot backup of the existing unencrypted RDS instance for safety. This can be done manually through the AWS Management Console or via CLI.

aws rds create-db-snapshot --db-instance-identifier <your-db-instance-id> --db-snapshot-identifier <snapshot-name>

Create Encrypted Replica: Create a new RDS instance as an encrypted replica of the existing unencrypted instance using the snapshot taken in the previous step. This will ensure data continuity during the encryption process.

aws rds restore-db-instance-from-db-snapshot --db-instance-identifier <new-db-instance-id> --db-snapshot-identifier <snapshot-name> --encrypted

Redirect Traffic: Redirect application traffic to the new encrypted RDS instance. Update any connection strings or configurations in your application to point to the new instance.

Verify Data and Functionality: Once traffic is redirected to the new encrypted RDS instance, verify that your application is functioning as expected and that all data has been migrated successfully.

Clean Up: Once you've verified that everything is working correctly, you can delete the old unencrypted RDS instance and any associated resources.

aws rds delete-db-instance --db-instance-identifier <old-db-instance-id> --skip-final-snapshot
profile picture
answered 3 months ago
  • This fails for us on step 2, cdk deploy. Trying to deploy an existing stack with an existing database having just set storageEncrypted: true results in CloudFormation cannot update a stack when a custom-named resource requires replacing. Rename test-unencrypted-db and update the stack again.

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions