Was this helpful? Support me via buymeacoffee.com and help me create lots more great content!

How to Remotely Connect to an AWS RDS Instance in a Private Subnet

In some AWS setups, you may have an RDS (Relational Database Service) instance located within a private subnet, making it inaccessible from the public internet. To access this RDS instance remotely without installing a bastion server or relying on public-facing EC2 instances, you can use AWS Systems Manager Session Manager along with SSH port forwarding. This article guides you through the process.

Assumptions

Before we dive into the steps, let's establish a few assumptions:

  • There is no bastion instance serving as a gateway for external access.
  • No security groups are configured to provide external access.
  • You have an EC2 instance running within the same private subnet as the RDS instance.
  • This EC2 instance is running on an Ubuntu-based operating system.

Prerequisites

Install ec2-instance-connect on EC2 instance

  • You can install ec2-instance-connect by connecting to an existing EC2 instance using AWS Session Manager and running the following command:
apt-get install ec2-instance-connect

Note: If you use autoscaling groups or blue/green deployments, you can include this installation in the EC2 user data to ensure ec2-instance-connect is installed when a new server is created.

Create an SSH Key

You will need an SSH key to connect to the EC2 instance. If you already have one, you can skip this step. To create an SSH key, run:

ssh-keygen -f my_rsa

This will generate SSH private and public keys named my_rsa and my_rsa.pub.

Push Your SSH Key to the Target Instance

To connect to the EC2 instance, send the SSH public key to the desired EC2 instance using the following command:

aws ec2-instance-connect send-ssh-public-key \
  --instance-id i-0c6e3bd52bbb2373c \
  --availability-zone eu-west-1a \
  --instance-os-user ubuntu \
  --ssh-public-key file:///my_rsa.pub

Note: The SSH public keys are available for one-time use for 60 seconds in the instance metadata. To connect successfully, use SSH within this time window. There is no need to track or manage these keys directly.

Start an AWS System Manager Session

Start an AWS System Manager session and enable port forwarding. In this case, forward port 9999 on your local machine to port 22 on the target EC2 instance:

aws ssm start-session \
  --target i-0c6e3bd52bbb2373c \
  --document-name AWS-StartPortForwardingSession \
  --parameters '{"portNumber":"22", "localPortNumber":"9999"}'

Open a Tunnel to RDS (in Another Terminal)

To open a tunnel to your RDS instance via the AWS System Manager session you created above, use the following command:

ssh ubuntu@localhost \
  -p 9999 \
  -N \
  -L 3388:production-database.inzy2e1e4v6s.eu-west-1.rds.amazonaws.com:3306

Note: This command may appear to hang because it maintains a tunnelling connection between port 3388 on localhost and port 3306 on production-database.inzy2e1e4v6s.eu-west-1.rds.amazonaws.com via the EC2 instance i-07edf50160ab3172.

Connect to Your RDS Instance

With the above steps complete, you can now use your favourite database client (e.g., SequelPro, HeidiSQL) to connect to your RDS database. The connection details will be as follows:

  • Host: localhost
  • Port: 3388
  • Username / Password: As per the live database you are trying to access

You should now have access to your RDS instance.

Originally published at https://chrisshennan.com/blog/using-aws-systems-manager-and-ssh-to-access-an-rds-instance