DEV Community

Cover image for Access AWS ElastiCache from Localhost Using a Bastion Host and SSM
Rodrigo Burgos
Rodrigo Burgos

Posted on

Access AWS ElastiCache from Localhost Using a Bastion Host and SSM

When managing cloud infrastructure, you often want to securely access services like Redis (ElastiCache) that live in private subnets. Direct access from your machine is usually not allowed — and that’s a good thing. But what if you still want to test or inspect your Redis cluster?

One approach is to set up a bastion host with SSM (Session Manager) and use it to tunnel requests to ElastiCache from your localhost — without exposing anything to the public internet.

Let’s break down how to do it using Terraform and the AWS CLI.

Infrastructure Overview

Here’s what we’re setting up:

  • A bastion EC2 instance in a public subnet.

  • A Redis ElastiCache cluster in private subnets.

  • Security Groups allowing just enough access to get the job done.

  • SSM Session Manager to connect to the bastion host without SSH or public key management.

Terraform Resources

  1. EC2 Bastion host
resource "aws_instance" "bastion_host" {
  ami                         = "ami-02f3f602d23f1659d"
  instance_type               = "t3.micro"
  subnet_id                   = var.subnet_id_a
  associate_public_ip_address = true
  key_name                    = "your_key"
  iam_instance_profile        = aws_iam_instance_profile.ssm_profile.name
  vpc_security_group_ids      = [aws_security_group.bastion_sg.id]

  root_block_device {
    volume_size = 10
  }

  user_data = file("user_data.sh")
}
Enter fullscreen mode Exit fullscreen mode
  1. IAM Role for SSM
resource "aws_iam_role" "ssm_role" {
  name = "ssm-role"
  assume_role_policy = jsonencode({
    Version = "2012-10-17",
    Statement = [{
      Effect = "Allow",
      Principal = {
        Service = "ec2.amazonaws.com"
      },
      Action = "sts:AssumeRole"
    }]
  })

  managed_policy_arns = [
    "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore"
  ]
}

resource "aws_iam_instance_profile" "ssm_profile" {
  name = "ssm-profile"
  role = aws_iam_role.ssm_role.name
}

Enter fullscreen mode Exit fullscreen mode
  1. Bastion Host Security Group Allow only egress to required ports (Redis, HTTP, HTTPS):
resource "aws_security_group" "bastion_sg" {
  name   = "bastion-sg"
  vpc_id = var.vpc_id

  egress {
    from_port   = 6379
    to_port     = 6379
    protocol    = "tcp"
    cidr_blocks = ["10.0.0.0/16"] # restrict to your VPC range
  }

  egress {
    from_port   = 443
    to_port     = 443
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }
}
Enter fullscreen mode Exit fullscreen mode
  1. ElastiCache Redis Cluster
resource "aws_elasticache_cluster" "redis" {
  cluster_id           = "redis-dev"
  engine               = "redis"
  node_type            = "cache.t2.micro"
  num_cache_nodes      = 1
  port                 = 6379
  subnet_group_name    = aws_elasticache_subnet_group.redis_subnets.name
  security_group_ids   = [aws_security_group.redis_sg.id]
}

Enter fullscreen mode Exit fullscreen mode
  1. Redis Security Group

Allow ingress only from the bastion host:

resource "aws_security_group" "redis_sg" {
  name   = "redis-sg"
  vpc_id = var.vpc_id

  ingress {
    from_port       = 6379
    to_port         = 6379
    protocol        = "tcp"
    security_groups = [aws_security_group.bastion_sg.id]
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

Enter fullscreen mode Exit fullscreen mode

Accessing Redis from Localhost

  1. Start the SSM session On your local machine, use the AWS CLI to start a session:
aws ssm start-session \
  --target i-xxxxxxxxxxxxxxxxx \
  --profile your-aws-profile \
  --region us-east-1
Enter fullscreen mode Exit fullscreen mode
  1. Connect to Redis from the bastion
redis-cli -h redis-dev.xxxxxx.use1.cache.amazonaws.com -p 6379
Enter fullscreen mode Exit fullscreen mode

You should see:

redis-dev.xxxxxx.use1.cache.amazonaws.com:6379> ping
PONG
Enter fullscreen mode Exit fullscreen mode

Nice — Redis is alive 🎉

Bonus: Security Best Practices

✅ Never use 0.0.0.0/0 unless you’re testing — always restrict IPs or CIDRs.

✅ Use private subnets for ElastiCache.

✅ Limit egress/ingress traffic via security groups.

✅ Prefer SSM over SSH for bastion access (no exposed ports).

✅ Remove public IPs once everything is connected through VPC peering or VPNs.

Top comments (1)

Collapse
 
nevodavid profile image
Nevo David

Helpful guide for secure access setup!