Update 2022-12-9: the solution now uses the new port forwarding to remote hosts feature.
Although port forwarding using AWS System Manager Session Manager is easy for forwarding traffic to a service on a remote host. Previously, port forwarding was more complex when taking an extra hop.
With the release of the
RemoteHostPortForwarding SSM Session Manager capability,
it’s also easier to jump an extra hop. An obvious use case for
RemoteHostPortForwarding is to set up a tunnel to allow a local machine to access an RDS database deployed in a private subnet.
Create a remote port forwarding session to RDS
At this point, I assume you’re already familiar with AWS Session Manager for remote shell access (as a replacement for SSH or RDP). If you’re not familiar with AWS SSM Session Manager yet, I highly recommend reading Keep up with the times: forget SSH, welcome AWS Session Manager first.
To create a local tunnel to RDS, the first thing you need is an EC2 instance accessible by AWS SSM Session Manager. The easiest way to achieve this is to use an instance running Amazon Linux with an instance profile allowing
AmazonSSMManagedInstanceCore access. Besides the instance profile, the instance also needs network access to the database. Verify the outbound rules of your EC2 security group and the inbound rules of the RDS security. Both security groups should allow access to the database port.
Ensure you have installed the SSM Session Manager plugin for the AWS CLI.
Having the instance running, you can create a Systems Manager Session to the remote RDS host, using the instance as a jump host:
aws ssm start-session --region <your region> --target <your jump host instance id> \ --document-name AWS-StartPortForwardingSessionToRemoteHost \ --parameters host="<rds endpoint>",portNumber="5432",localPortNumber="5432"
Note: this example is based on PostgreSQL. For other databases, change the port numbers.
Running the command above, you should see output similar to:
Starting session with SessionId: vourid-12a3456bcdefghi789 Port 5432 opened for sessionId yourid-12a3456bcdefghi789 Waiting for connections...
Leave this window open.
Locally connect to your remote RDS instance running in a private subnet
In another window, you can now start a local connection to the private RDS instance.
psql -h 127.0.0.1 -p 5432 -U web -d backstage
Enjoy and until next time!