DocumentDB Instance Storage Encryption
Overview
This check verifies that Amazon DocumentDB instances have encryption at rest enabled. DocumentDB instances inherit their encryption settings from their parent cluster. When a cluster is encrypted, all instances within that cluster are automatically encrypted using 256-bit AES encryption through AWS Key Management Service (KMS).
Encryption protects all data on the instance, including storage volumes, indexes, logs, automated backups, and snapshots.
Risk
Without encryption at rest, your DocumentDB data is stored as plaintext. This creates risk if:
- Storage infrastructure is compromised
- Backups or snapshots are shared improperly or leaked
- Insider threats access the underlying storage
- AWS credentials are stolen and used to copy data
This could result in data breaches, compliance violations (HIPAA, PCI-DSS, GDPR), and exposure of sensitive business information.
Remediation Steps
Prerequisites
- AWS Console access with permissions to manage DocumentDB clusters
- (Optional) A KMS key if you want to use a customer-managed key instead of the AWS-managed default
Required IAM permissions
To create encrypted DocumentDB clusters and instances, you need these permissions:
rds:CreateDBClusterrds:CreateDBInstancerds:DescribeDBClustersrds:DescribeDBInstanceskms:DescribeKeykms:CreateGrant(if using customer-managed KMS key)kms:GenerateDataKey(if using customer-managed KMS key)
Important Note
DocumentDB instances inherit encryption from their parent cluster. Instance encryption cannot be configured independently. To have encrypted instances, you must:
- Create an encrypted cluster first
- Add instances to that encrypted cluster
If your instances are not encrypted, it means their parent cluster is not encrypted. You cannot change encryption on an existing cluster - you must migrate to a new encrypted cluster.
AWS Console Method
Option A: Create a new encrypted cluster with instances
- Open the Amazon DocumentDB console
- Click Clusters in the left navigation
- Click Create
- Configure your cluster settings (identifier, instance class, number of instances)
- Expand Show advanced settings
- Under Encryption-at-rest, select Enable encryption (this is the default)
- Choose your KMS key:
- aws/rds - AWS managed key (simplest option)
- Choose a key - Select a customer-managed KMS key
- Complete the remaining configuration and click Create cluster
- All instances created in this cluster will automatically be encrypted
Option B: Migrate existing unencrypted instances to an encrypted cluster
- Open the Amazon DocumentDB console
- Click Clusters, then select the unencrypted cluster containing your instances
- Click Actions > Take snapshot
- Enter a snapshot name and click Create
- Wait for the snapshot to complete (status: "available")
- Click Snapshots in the left navigation
- Select your snapshot, click Actions > Restore
- Enter a new cluster identifier
- Expand Show advanced settings
- Under Encryption-at-rest, select Enable encryption
- Choose your KMS key
- Click Restore cluster
- After the new cluster is available, add instances to it (they will be encrypted)
- Update your application connection strings to point to the new cluster
- Delete the old unencrypted cluster when you confirm the migration succeeded
AWS CLI (optional)
Create a new encrypted cluster with an instance:
# Step 1: Create an encrypted cluster
aws docdb create-db-cluster \
--db-cluster-identifier my-encrypted-docdb \
--engine docdb \
--master-username myuser \
--master-user-password mypassword123 \
--storage-encrypted \
--region us-east-1
# Step 2: Add an instance to the encrypted cluster
aws docdb create-db-instance \
--db-instance-identifier my-encrypted-instance \
--db-instance-class db.r5.large \
--db-cluster-identifier my-encrypted-docdb \
--engine docdb \
--region us-east-1
Create with a customer-managed KMS key:
aws docdb create-db-cluster \
--db-cluster-identifier my-encrypted-docdb \
--engine docdb \
--master-username myuser \
--master-user-password mypassword123 \
--storage-encrypted \
--kms-key-id arn:aws:kms:us-east-1:<account-id>:key/<key-id> \
--region us-east-1
Migrate unencrypted instances to an encrypted cluster:
# Step 1: Create a snapshot of the unencrypted cluster
aws docdb create-db-cluster-snapshot \
--db-cluster-identifier my-unencrypted-cluster \
--db-cluster-snapshot-identifier my-snapshot \
--region us-east-1
# Step 2: Wait for snapshot to be available
aws docdb wait db-cluster-snapshot-available \
--db-cluster-snapshot-identifier my-snapshot \
--region us-east-1
# Step 3: Restore snapshot with encryption enabled
aws docdb restore-db-cluster-from-snapshot \
--db-cluster-identifier my-new-encrypted-cluster \
--snapshot-identifier my-snapshot \
--engine docdb \
--kms-key-id arn:aws:kms:us-east-1:<account-id>:key/<key-id> \
--region us-east-1
# Step 4: Wait for new cluster to be available
aws docdb wait db-cluster-available \
--db-cluster-identifier my-new-encrypted-cluster \
--region us-east-1
# Step 5: Add instances to the new encrypted cluster
aws docdb create-db-instance \
--db-instance-identifier my-new-encrypted-instance \
--db-instance-class db.r5.large \
--db-cluster-identifier my-new-encrypted-cluster \
--engine docdb \
--region us-east-1
Replace:
<account-id>with your 12-digit AWS account ID<key-id>with your KMS key IDmypassword123with a strong password
CloudFormation (optional)
AWSTemplateFormatVersion: '2010-09-09'
Description: Encrypted Amazon DocumentDB cluster with instances
Parameters:
DBClusterIdentifier:
Type: String
Description: Identifier for the DocumentDB cluster
Default: my-encrypted-docdb
MasterUsername:
Type: String
Description: Master username for the cluster
NoEcho: true
MasterUserPassword:
Type: String
Description: Master password for the cluster
NoEcho: true
MinLength: 8
DBInstanceClass:
Type: String
Description: Instance class for DocumentDB instances
Default: db.r5.large
AllowedValues:
- db.r5.large
- db.r5.xlarge
- db.r5.2xlarge
- db.r5.4xlarge
InstanceCount:
Type: Number
Description: Number of instances to create
Default: 1
MinValue: 1
MaxValue: 16
VpcId:
Type: AWS::EC2::VPC::Id
Description: VPC for the DocumentDB cluster
SubnetIds:
Type: List<AWS::EC2::Subnet::Id>
Description: Subnets for the DocumentDB cluster (at least 2 in different AZs)
Resources:
DocumentDBKmsKey:
Type: AWS::KMS::Key
Properties:
Description: KMS key for DocumentDB cluster encryption
EnableKeyRotation: true
KeyPolicy:
Version: '2012-10-17'
Statement:
- Sid: Enable IAM User Permissions
Effect: Allow
Principal:
AWS: !Sub 'arn:aws:iam::${AWS::AccountId}:root'
Action: 'kms:*'
Resource: '*'
- Sid: Allow DocumentDB Service
Effect: Allow
Principal:
Service: rds.amazonaws.com
Action:
- 'kms:Encrypt'
- 'kms:Decrypt'
- 'kms:ReEncrypt*'
- 'kms:GenerateDataKey*'
- 'kms:DescribeKey'
Resource: '*'
DocumentDBKmsKeyAlias:
Type: AWS::KMS::Alias
Properties:
AliasName: !Sub 'alias/docdb-${DBClusterIdentifier}'
TargetKeyId: !Ref DocumentDBKmsKey
DocumentDBSubnetGroup:
Type: AWS::DocDB::DBSubnetGroup
Properties:
DBSubnetGroupDescription: Subnet group for DocumentDB cluster
SubnetIds: !Ref SubnetIds
Tags:
- Key: Name
Value: !Sub '${DBClusterIdentifier}-subnet-group'
DocumentDBSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Security group for DocumentDB cluster
VpcId: !Ref VpcId
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 27017
ToPort: 27017
CidrIp: 10.0.0.0/8
Tags:
- Key: Name
Value: !Sub '${DBClusterIdentifier}-sg'
DocumentDBCluster:
Type: AWS::DocDB::DBCluster
Properties:
DBClusterIdentifier: !Ref DBClusterIdentifier
MasterUsername: !Ref MasterUsername
MasterUserPassword: !Ref MasterUserPassword
DBSubnetGroupName: !Ref DocumentDBSubnetGroup
VpcSecurityGroupIds:
- !Ref DocumentDBSecurityGroup
StorageEncrypted: true
KmsKeyId: !GetAtt DocumentDBKmsKey.Arn
DeletionProtection: true
Tags:
- Key: Name
Value: !Ref DBClusterIdentifier
DocumentDBInstance1:
Type: AWS::DocDB::DBInstance
Properties:
DBClusterIdentifier: !Ref DocumentDBCluster
DBInstanceClass: !Ref DBInstanceClass
Tags:
- Key: Name
Value: !Sub '${DBClusterIdentifier}-instance-1'
Outputs:
ClusterEndpoint:
Description: DocumentDB cluster endpoint
Value: !GetAtt DocumentDBCluster.Endpoint
ClusterPort:
Description: DocumentDB cluster port
Value: !GetAtt DocumentDBCluster.Port
InstanceIdentifier:
Description: Instance identifier
Value: !Ref DocumentDBInstance1
KmsKeyArn:
Description: ARN of the KMS key used for encryption
Value: !GetAtt DocumentDBKmsKey.Arn
Deploy with:
aws cloudformation deploy \
--template-file documentdb-encrypted.yaml \
--stack-name encrypted-documentdb \
--parameter-overrides \
DBClusterIdentifier=my-encrypted-docdb \
MasterUsername=myuser \
MasterUserPassword=mypassword123 \
VpcId=vpc-abc123 \
SubnetIds=subnet-123,subnet-456 \
--capabilities CAPABILITY_IAM \
--region us-east-1
Terraform (optional)
# variables.tf
variable "cluster_identifier" {
description = "Identifier for the DocumentDB cluster"
type = string
default = "my-encrypted-docdb"
}
variable "master_username" {
description = "Master username for the cluster"
type = string
sensitive = true
}
variable "master_password" {
description = "Master password for the cluster"
type = string
sensitive = true
}
variable "instance_class" {
description = "Instance class for DocumentDB instances"
type = string
default = "db.r5.large"
}
variable "instance_count" {
description = "Number of instances to create"
type = number
default = 1
}
variable "subnet_ids" {
description = "List of subnet IDs for the DocumentDB subnet group"
type = list(string)
}
variable "vpc_id" {
description = "VPC ID for the security group"
type = string
}
# main.tf
data "aws_caller_identity" "current" {}
resource "aws_kms_key" "docdb" {
description = "KMS key for DocumentDB cluster encryption"
deletion_window_in_days = 7
enable_key_rotation = true
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Sid = "Enable IAM User Permissions"
Effect = "Allow"
Principal = {
AWS = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:root"
}
Action = "kms:*"
Resource = "*"
},
{
Sid = "Allow DocumentDB Service"
Effect = "Allow"
Principal = {
Service = "rds.amazonaws.com"
}
Action = [
"kms:Encrypt",
"kms:Decrypt",
"kms:ReEncrypt*",
"kms:GenerateDataKey*",
"kms:DescribeKey"
]
Resource = "*"
}
]
})
tags = {
Purpose = "DocumentDB encryption"
}
}
resource "aws_kms_alias" "docdb" {
name = "alias/docdb-${var.cluster_identifier}"
target_key_id = aws_kms_key.docdb.key_id
}
resource "aws_docdb_subnet_group" "main" {
name = "${var.cluster_identifier}-subnet-group"
subnet_ids = var.subnet_ids
tags = {
Name = "${var.cluster_identifier}-subnet-group"
}
}
resource "aws_security_group" "docdb" {
name = "${var.cluster_identifier}-sg"
description = "Security group for DocumentDB cluster"
vpc_id = var.vpc_id
ingress {
from_port = 27017
to_port = 27017
protocol = "tcp"
cidr_blocks = ["10.0.0.0/8"]
}
tags = {
Name = "${var.cluster_identifier}-sg"
}
}
resource "aws_docdb_cluster" "main" {
cluster_identifier = var.cluster_identifier
master_username = var.master_username
master_password = var.master_password
db_subnet_group_name = aws_docdb_subnet_group.main.name
vpc_security_group_ids = [aws_security_group.docdb.id]
storage_encrypted = true
kms_key_id = aws_kms_key.docdb.arn
deletion_protection = true
skip_final_snapshot = false
final_snapshot_identifier = "${var.cluster_identifier}-final-snapshot"
tags = {
Name = var.cluster_identifier
}
}
resource "aws_docdb_cluster_instance" "main" {
count = var.instance_count
identifier = "${var.cluster_identifier}-instance-${count.index + 1}"
cluster_identifier = aws_docdb_cluster.main.id
instance_class = var.instance_class
tags = {
Name = "${var.cluster_identifier}-instance-${count.index + 1}"
}
}
# outputs.tf
output "cluster_endpoint" {
description = "DocumentDB cluster endpoint"
value = aws_docdb_cluster.main.endpoint
}
output "cluster_port" {
description = "DocumentDB cluster port"
value = aws_docdb_cluster.main.port
}
output "instance_identifiers" {
description = "List of instance identifiers"
value = aws_docdb_cluster_instance.main[*].identifier
}
output "kms_key_arn" {
description = "ARN of the KMS key used for encryption"
value = aws_kms_key.docdb.arn
}
Deploy with:
terraform init
terraform apply \
-var="cluster_identifier=my-encrypted-docdb" \
-var="master_username=myuser" \
-var="master_password=mypassword123" \
-var="vpc_id=vpc-abc123" \
-var='subnet_ids=["subnet-abc123", "subnet-def456"]'
Verification
After creating your encrypted cluster and instances, verify encryption is enabled:
- Open the Amazon DocumentDB console
- Click Instances in the left navigation
- Select your instance
- On the Configuration tab, look for the Storage encrypted field - it should show Yes
CLI verification
Check encryption status of all instances:
aws docdb describe-db-instances \
--query 'DBInstances[*].{InstanceID:DBInstanceIdentifier,ClusterID:DBClusterIdentifier,Encrypted:StorageEncrypted}' \
--output table \
--region us-east-1
Check a specific instance:
aws docdb describe-db-instances \
--db-instance-identifier my-encrypted-instance \
--query 'DBInstances[0].{InstanceID:DBInstanceIdentifier,ClusterID:DBClusterIdentifier,Encrypted:StorageEncrypted}' \
--region us-east-1
Expected output for an encrypted instance:
{
"InstanceID": "my-encrypted-instance",
"ClusterID": "my-encrypted-docdb",
"Encrypted": true
}
Re-run the Prowler check:
prowler aws --checks documentdb_instance_storage_encrypted
Additional Resources
- Amazon DocumentDB Encryption at Rest
- AWS KMS Key Management
- Amazon DocumentDB Best Practices
- AWS CLI DocumentDB Reference
Notes
-
Instance encryption is inherited from the cluster: DocumentDB instances do not have their own encryption setting. They automatically use whatever encryption configuration is set on their parent cluster.
-
Encryption cannot be changed after creation: You cannot enable or disable encryption on an existing cluster. To encrypt existing instances, you must create a new encrypted cluster, migrate your data via snapshot restore, and then add new instances.
-
AWS Console vs CLI defaults: The AWS Console enables encryption by default when creating clusters, but the AWS CLI does not. Always specify
--storage-encryptedwhen using the CLI. -
KMS key cannot be changed: Once a cluster is created with a specific KMS key, that key is fixed for the cluster's lifetime. All instances in that cluster use the same key.
-
KMS key access is critical: If DocumentDB loses access to the KMS key (e.g., key is disabled or deleted), the cluster and all its instances enter a terminal state. The only recovery is to restore from a backup.
-
Symmetric keys only: DocumentDB requires symmetric KMS keys. Asymmetric keys are not supported.
-
Performance impact: Encryption has minimal performance impact due to efficient caching of data keys in memory. Applications do not need any code changes to work with encrypted instances.