ElastiCache for Redis replication groups should be encrypted with CMK
AWS-managed keys give you encryption but no control over key rotation schedules, key policies, or cross-account access grants. With a CMK, you own the key lifecycle: you can disable or delete the key to render cached data unrecoverable, enforce separation of duties through IAM and KMS key policies, and audit every decrypt call in CloudTrail. Redis replication groups often cache sensitive session tokens, PII, or query results that deserve the same key governance you apply to your primary data stores.
Losing control of the encryption key means losing the ability to provably revoke access to cached data during an incident or offboarding event.
Retrofit consideration
Changing kms_key_id or enabling at_rest_encryption_enabled on an existing replication group forces replacement. Terraform destroys and recreates the replication group, causing full cache eviction and downtime. Plan a maintenance window and pre-warm the new cluster before cutting over.
Implementation
Choose the approach that matches how you manage Terraform.
If you use terraform-aws-modules/elasticache/aws, set the right module inputs for this control. You can later migrate to the compliance.tf module with minimal changes because it is compatible by design.
module "elasticache" {
source = "terraform-aws-modules/elasticache/aws"
version = ">=1.0.0,<2.0.0"
description = "Redis cluster"
engine = "redis"
engine_version = "7.1"
node_type = "cache.t3.micro"
num_cache_clusters = 2
replication_group_id = "abc123"
subnet_ids = ["subnet-12345678", "subnet-12345678"]
vpc_id = "vpc-12345678"
}
Use AWS provider resources directly. See docs for the resources involved: aws_elasticache_replication_group.
resource "aws_elasticache_replication_group" "this" {
at_rest_encryption_enabled = true
auth_token = "PofixExampleAuthToken32CharsLng"
description = "pofix example replication group"
node_type = "cache.t3.micro"
num_cache_clusters = 2
replication_group_id = "pofix-abc123"
snapshot_retention_limit = 15
subnet_group_name = "example-subnet-group"
transit_encryption_enabled = true
kms_key_id = "arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012"
}
What this control checks
In aws_elasticache_replication_group, two arguments must be set: at_rest_encryption_enabled must be true, and kms_key_id must reference a customer-managed KMS key (a key ARN or key ID from an aws_kms_key resource). A configuration passes when both are explicitly set with valid values pointing to a CMK you own. It fails when at_rest_encryption_enabled is false or omitted, or when kms_key_id is absent, which causes ElastiCache to fall back to the default AWS-managed aws/elasticache key.
Common pitfalls
Replacement required on existing clusters
Both
at_rest_encryption_enabledandkms_key_idare ForceNew arguments onaws_elasticache_replication_group. Terraform destroys and recreates the replication group, wiping the cache entirely. You can usecreate_before_destroyif you also rename the resource (ElastiCache group names must be unique), but you will still lose all cached data and need to pre-warm the new cluster after cutover.KMS key policy must grant ElastiCache access
Cluster creation fails with an opaque
InvalidParameterValueerror if your CMK's key policy does not includekms:GenerateDataKey*andkms:Decryptfor theelasticache.amazonaws.comservice principal (or the account root with appropriate IAM delegation). Validate the key policy grants before runningterraform apply, not after.Alias strings can pass plan but fail at apply
Passing a bare alias like
alias/my-keytokms_key_idmay passterraform planwithout error but cause a creation failure at apply time. Referenceaws_kms_key.example.arndirectly to ensure you are passing a key ARN that ElastiCache can resolve without ambiguity.Pending deletion KMS key breaks the cluster
If the referenced CMK enters
PendingDeletionstate, ElastiCache loses the ability to decrypt data and the replication group becomes unusable. Addlifecycle { prevent_destroy = true }to youraws_kms_keyresource and set up CloudWatch alarms on theKMSKeyPendingDeletionmetric so you catch a scheduled deletion before it takes effect.
Audit evidence
Config rule evaluation results should show each AWS::ElastiCache::ReplicationGroup resource as compliant, confirming both encryption at rest and a CMK ARN. The DescribeReplicationGroups API response should show AtRestEncryptionEnabled: true and a KmsKeyId value that maps to a customer-managed key. Verify via aws kms describe-key --key-id <arn> that KeyManager is CUSTOMER.
CloudTrail logs showing kms:Decrypt and kms:GenerateDataKey events associated with ElastiCache activity serve as ongoing proof the CMK is in active use. Compliance dashboard exports covering this control complete the evidence package.
Framework-specific interpretation
Related controls
Tool mappings
Use these identifiers to cross-reference this control across tools, reports, and evidence.
Compliance.tf Control:
elasticache_replication_group_encryption_at_rest_enabled_with_kms_cmkAWS Config Managed Rule:
ELASTICACHE_REPL_GRP_ENCRYPTED_AT_RESTCheckov Check:
CKV_AWS_191Powerpipe Control:
aws_compliance.control.elasticache_replication_group_encryption_at_rest_enabled_with_kms_cmkProwler Check:
elasticache_redis_cluster_rest_encryption_enabledAWS Security Hub Control:
ElastiCache.4Trivy Check:
AWS-0045
Last reviewed: 2026-03-09