RDS Cluster Storage Encrypted
Overview
This check verifies that your Amazon RDS clusters (Aurora and Multi-AZ DB clusters) have storage encryption enabled. Encryption at rest protects your data by encrypting the underlying storage, automated backups, read replicas, and snapshots using AWS Key Management Service (KMS).
Risk
If storage encryption is not enabled:
- Data exposure: Sensitive data stored in the database could be accessed if physical storage media is compromised
- Backup vulnerability: Automated backups and snapshots remain unencrypted, creating additional exposure points
- Compliance gaps: Many regulatory frameworks (PCI-DSS, HIPAA, SOC 2) require encryption of data at rest
- Lateral risk: If an attacker gains access to unencrypted backups, they can perform offline data theft
Remediation Steps
Prerequisites
- AWS Console access with permissions to create and modify RDS clusters
- If using a customer-managed KMS key, ensure it exists and you have access to it
Important: You cannot enable encryption on an existing unencrypted cluster. You must create a new encrypted cluster and migrate your data.
AWS Console Method
Step 1: Identify unencrypted clusters
- Open the Amazon RDS Console
- Click Databases in the left navigation
- For each cluster, click on its name and check the Configuration tab
- Look for Encryption - if it shows "Not enabled", the cluster needs remediation
Step 2: Create a new encrypted cluster
- In the RDS Console, click Create database
- Choose your engine type (Aurora MySQL, Aurora PostgreSQL, or Multi-AZ)
- Configure your database settings as needed
- Scroll to Encryption section
- Check Enable encryption
- Choose your KMS key:
- Default: Uses the AWS-managed
aws/rdskey (simpler) - Custom: Select a customer-managed key (recommended for additional control)
- Default: Uses the AWS-managed
- Complete the remaining configuration and click Create database
Step 3: Migrate data to the encrypted cluster
- Use AWS Database Migration Service (DMS) or native database tools to migrate data
- Update your application connection strings to point to the new cluster
- Verify the application works correctly with the new cluster
- Delete the old unencrypted cluster once migration is confirmed successful
AWS CLI (optional)
List clusters and check encryption status:
aws rds describe-db-clusters \
--region us-east-1 \
--query 'DBClusters[*].[DBClusterIdentifier,StorageEncrypted,KmsKeyId]' \
--output table
Create an encrypted Aurora MySQL cluster:
aws rds create-db-cluster \
--region us-east-1 \
--db-cluster-identifier my-encrypted-cluster \
--engine aurora-mysql \
--engine-version 8.0.mysql_aurora.3.04.0 \
--master-username admin \
--master-user-password '<your-secure-password>' \
--storage-encrypted \
--backup-retention-period 7 \
--deletion-protection
Create an encrypted cluster with a customer-managed KMS key:
aws rds create-db-cluster \
--region us-east-1 \
--db-cluster-identifier my-encrypted-cluster \
--engine aurora-mysql \
--engine-version 8.0.mysql_aurora.3.04.0 \
--master-username admin \
--master-user-password '<your-secure-password>' \
--storage-encrypted \
--kms-key-id arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012 \
--backup-retention-period 7 \
--deletion-protection
Create an instance in the cluster:
After creating the cluster, you must create at least one DB instance:
aws rds create-db-instance \
--region us-east-1 \
--db-instance-identifier my-encrypted-cluster-instance-1 \
--db-cluster-identifier my-encrypted-cluster \
--db-instance-class db.r6g.large \
--engine aurora-mysql
CloudFormation (optional)
AWSTemplateFormatVersion: '2010-09-09'
Description: RDS Aurora Cluster with encryption enabled
Parameters:
DBClusterIdentifier:
Type: String
Description: Identifier for the DB cluster
MasterUsername:
Type: String
Description: Master username for the cluster
MasterUserPassword:
Type: String
NoEcho: true
Description: Master password for the cluster
KMSKeyId:
Type: String
Description: KMS Key ARN for encryption (optional - uses default aws/rds key if not specified)
Default: ''
Conditions:
UseCustomKMSKey: !Not [!Equals [!Ref KMSKeyId, '']]
Resources:
RDSCluster:
Type: AWS::RDS::DBCluster
Properties:
DBClusterIdentifier: !Ref DBClusterIdentifier
Engine: aurora-mysql
EngineVersion: '8.0.mysql_aurora.3.04.0'
MasterUsername: !Ref MasterUsername
MasterUserPassword: !Ref MasterUserPassword
StorageEncrypted: true
KmsKeyId: !If [UseCustomKMSKey, !Ref KMSKeyId, !Ref 'AWS::NoValue']
BackupRetentionPeriod: 7
DeletionProtection: true
Tags:
- Key: Environment
Value: Production
Outputs:
ClusterEndpoint:
Description: Cluster endpoint
Value: !GetAtt RDSCluster.Endpoint.Address
ClusterArn:
Description: Cluster ARN
Value: !GetAtt RDSCluster.DBClusterArn
Deploy the stack:
aws cloudformation create-stack \
--region us-east-1 \
--stack-name encrypted-rds-cluster \
--template-body file://template.yaml \
--parameters \
ParameterKey=DBClusterIdentifier,ParameterValue=my-encrypted-cluster \
ParameterKey=MasterUsername,ParameterValue=admin \
ParameterKey=MasterUserPassword,ParameterValue='<your-secure-password>'
Terraform (optional)
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {
region = "us-east-1"
}
variable "cluster_identifier" {
description = "Identifier for the RDS cluster"
type = string
}
variable "master_username" {
description = "Master username for the cluster"
type = string
}
variable "master_password" {
description = "Master password for the cluster"
type = string
sensitive = true
}
variable "kms_key_id" {
description = "KMS Key ARN for encryption (optional)"
type = string
default = null
}
resource "aws_rds_cluster" "encrypted" {
cluster_identifier = var.cluster_identifier
engine = "aurora-mysql"
engine_version = "8.0.mysql_aurora.3.04.0"
master_username = var.master_username
master_password = var.master_password
storage_encrypted = true
kms_key_id = var.kms_key_id
backup_retention_period = 7
deletion_protection = true
skip_final_snapshot = false
final_snapshot_identifier = "${var.cluster_identifier}-final-snapshot"
tags = {
Environment = "Production"
}
}
output "cluster_endpoint" {
description = "The cluster endpoint"
value = aws_rds_cluster.encrypted.endpoint
}
output "cluster_arn" {
description = "The cluster ARN"
value = aws_rds_cluster.encrypted.arn
}
Apply the configuration:
terraform init
terraform plan -var="cluster_identifier=my-encrypted-cluster" \
-var="master_username=admin" \
-var="master_password=<your-secure-password>"
terraform apply
Verification
After creating your encrypted cluster, verify encryption is enabled:
- Open the Amazon RDS Console
- Click Databases and select your cluster
- Go to the Configuration tab
- Confirm Encryption shows "Enabled" with the KMS key ARN
CLI verification
aws rds describe-db-clusters \
--region us-east-1 \
--db-cluster-identifier my-encrypted-cluster \
--query 'DBClusters[0].[DBClusterIdentifier,StorageEncrypted,KmsKeyId]' \
--output table
Expected output should show StorageEncrypted: True and display the KMS key ARN.
Re-run the Prowler check:
prowler aws --checks rds_cluster_storage_encrypted --region us-east-1
Additional Resources
- Encrypting Amazon Aurora resources
- Encrypting Amazon RDS resources
- AWS KMS concepts
- AWS Database Migration Service
Notes
- Encryption cannot be added to existing clusters: You must create a new encrypted cluster and migrate data. Plan for migration downtime accordingly.
- Encryption is permanent: Once a cluster is created with encryption enabled, it cannot be disabled.
- Snapshots inherit encryption: Snapshots of encrypted clusters are automatically encrypted with the same KMS key.
- Cross-region considerations: When copying encrypted snapshots across regions, you must specify a KMS key in the destination region.
- KMS key management: If using a customer-managed KMS key, ensure the key policy grants RDS the necessary permissions and that key rotation is enabled.
- Performance impact: Encryption has minimal performance impact as it uses AES-256 encryption handled by the underlying storage infrastructure.