20.6 ElastiCache Security: VPC, Security Groups, Encryption at Rest and in Transit
Right, let’s talk about keeping your cache safe. This isn’t just about locking the door; it’s about knowing which doors exist, who has the keys, and whether you’re shouting your secrets through the walls for everyone to hear. AWS gives you the tools, but it’s on you to use them properly. The default settings are often convenient, and convenience is the sworn enemy of security.
Your Cache Lives in a VPC, and So Should You
First and foremost, if you’re creating a new ElastiCache cluster today, it had damn well better be in a VPC. The classic “EC2-VPC” days are over, and thank goodness. A VPC is your own private, logically isolated neighborhood within the AWS cloud. Placing your cache here is the foundational security move; it means your cluster isn’t sitting on some public internet backbone waiting for a port scan to find it. It’s only accessible to the resources you explicitly allow into your VPC or that specific subnet.
When you create a cluster, you define a subnet group. Think of this as choosing the specific street within your neighborhood where the house will be built. This is crucial for High Availability setups, where you’d spread nodes across different Availability Zones (i.e., different streets in different fault-tolerant sectors of your neighborhood). The key takeaway: nothing gets in or out of this VPC without your permission, enforced by security groups and network ACLs.
Security Groups: The Bouncer at the Door
The VPC is the neighborhood, and the Security Group is the bouncer at your cache’s specific front door. It’s a stateful firewall that controls inbound and outbound traffic to your cluster nodes. This is your first and most important line of defense. The most common, and most egregious, pitfall I see is a security group rule like 0.0.0.0/0 on port 6379 (Redis). Please don’t. You’re basically putting a sign on your database that says “Free Data, Take All.”
You should be painfully specific. Your security group should only allow inbound traffic on the cache port from the security group attached to your application servers (EC2 instances, ECS tasks, Lambda functions, etc.). This is the “default deny” principle, and it’s beautiful.
Here’s what a tight, proper security group setup looks like. First, create a security group for your application tier:
# Create the security group for your app servers
APP_SG_ID=$(aws ec2 create-security-group \
--group-name MyAppServerSG \
--description "Security group for application servers" \
--vpc-id vpc-1234567890abcdef0 \
--output text --query 'GroupId')
Then, create a security group for your ElastiCache cluster and only allow access from the app server’s group:
# Create the security group for your cache
CACHE_SG_ID=$(aws ec2 create-security-group \
--group-name MyElastiCacheSG \
--description "Security group for ElastiCache cluster" \
--vpc-id vpc-1234567890abcdef0 \
--output text --query 'GroupId')
# Authorize ingress from the app servers ONLY
aws ec2 authorize-security-group-ingress \
--group-id $CACHE_SG_ID \
--protocol tcp \
--port 6379 \
--source-group $APP_SG_ID
This creates a clean, minimal allow list. The cache nodes will only accept connections from resources that have the MyAppServerSG security group attached. This is infinitely more secure than using IP addresses.
Encryption: For When the Bouncer is Eavesdropped
Security groups control access, but they don’t protect the content of the communication. If someone is listening on the wire, they can see all your cached session tokens and user data. This is where encryption comes in.
Encryption in Transit is non-negotiable for any serious workload. It uses TLS to create a secure channel between your client and the cache node. AWS makes this relatively painless. You just tick a box (“Encryption in-transit”) when creating the cluster. The tricky part is on the client side: you must use a client that supports TLS and connect to the TLS-enabled port (6380 for Redis instead of 6379). For redis-cli, that means using the --tls flag. For most Redis clients, you’ll need to set the ssl or tls option to true in your connection configuration.
# Python example using redis-py
import redis
import botocore.session
# Get the auth token (if using IAM authentication)
session = botocore.session.get_session()
client = redis.Redis(
host='my-cluster.xxxxx.ng.0001.use1.cache.amazonaws.com',
port=6380,
ssl=True,
ssl_cert_reqs=None, # This is often required to avoid cert validation issues
username='myuser', # If using Redis AUTH
password=session.get_credentials().access_key # If using IAM Auth (advanced!)
)
Encryption at Rest is exactly what it sounds like: your data on disk is encrypted. AWS uses KMS to manage the keys. You enable this with another checkbox. The why is simple: it protects your data from someone physically stealing the underlying hardware (unlikely, but possible) or, more realistically, from an attacker who gains privileged access to the underlying hypervisor. It’s low-cost insurance. The performance hit is negligible for most use cases, so just enable it.
The IAM Authentication Curveball (Redis 6+)
Here’s where the designers made a genuinely interesting, if slightly awkward, choice. Redis 6 added Role-Based Access Control (RBAC). ElastiCache supports this, and it gives you two ways to authenticate: the traditional Redis AUTH password and… IAM.
IAM authentication is wild. Instead of a static password, your application generates a temporary token using its IAM credentials. This token is used as the password. The huge advantage is that there’s no long-lived password to rotate or leak. The disadvantage is that it’s more complex to set up and your client libraries need to support it.
You must enable both IAM and Password-based authentication on the cluster, create a user with an IAM-style password, and grant that user IAM permissions. It’s powerful, but it’s not for the faint of heart. The traditional password method is still perfectly valid and much simpler.
The bottom line? Use a VPC. Lock down your security groups with surgical precision. Enable encryption in transit—seriously, just do it. Use encryption at rest for good measure. And if you’re feeling brave and want to eliminate passwords entirely, take IAM authentication for a spin. Your cache is often the keys to the kingdom; treat it that way.