Skip to main content

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:CreateDBCluster
  • rds:CreateDBInstance
  • rds:DescribeDBClusters
  • rds:DescribeDBInstances
  • kms:DescribeKey
  • kms: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:

  1. Create an encrypted cluster first
  2. 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

  1. Open the Amazon DocumentDB console
  2. Click Clusters in the left navigation
  3. Click Create
  4. Configure your cluster settings (identifier, instance class, number of instances)
  5. Expand Show advanced settings
  6. Under Encryption-at-rest, select Enable encryption (this is the default)
  7. Choose your KMS key:
    • aws/rds - AWS managed key (simplest option)
    • Choose a key - Select a customer-managed KMS key
  8. Complete the remaining configuration and click Create cluster
  9. All instances created in this cluster will automatically be encrypted

Option B: Migrate existing unencrypted instances to an encrypted cluster

  1. Open the Amazon DocumentDB console
  2. Click Clusters, then select the unencrypted cluster containing your instances
  3. Click Actions > Take snapshot
  4. Enter a snapshot name and click Create
  5. Wait for the snapshot to complete (status: "available")
  6. Click Snapshots in the left navigation
  7. Select your snapshot, click Actions > Restore
  8. Enter a new cluster identifier
  9. Expand Show advanced settings
  10. Under Encryption-at-rest, select Enable encryption
  11. Choose your KMS key
  12. Click Restore cluster
  13. After the new cluster is available, add instances to it (they will be encrypted)
  14. Update your application connection strings to point to the new cluster
  15. 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 ID
  • mypassword123 with 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:

  1. Open the Amazon DocumentDB console
  2. Click Instances in the left navigation
  3. Select your instance
  4. 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

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-encrypted when 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.