Gain remote access to an AWS RDS instance

Often your developers or you need remote access to a RDS cluster. Often you would use a bastion host for that. You’d connect to the bastion host and from there configure port forwarding to the instance. Why using a bastion host is not a good idea is written up here. Connecting to the bastion host requires you to manage SSH keys and whitelist IPs. This is management overhead that can cause security misconfigurations.

I also see articles that advice you to set the database to Public Access. This is a terrible idea because you can port scan the whole IPv4 range in a couple of hours for open ports. Your cluster would be known to the world almost instantly. Furthermore Aurora Serverless does not even allow you to set the cluster to public anymore. It only works from an VPC.

You could also use AWS Client VPN to gain access to the cluster. However this comes at a significant cost (starts at around 70 USD per month).

There is another cheap way to gain access:

  1. Set Up a EC2 instance in the public network, use a ASG with spot instances and a minimum count of 1
  2. Give the instance role the AmazonSSMManagedInstanceCore policy
  3. The inbound security group of this EC2 instance should allow no inbound traffic at all
  4. This EC2 instance does not need a key pair (we do not SSH into it)

After this instance has started, you can easily connect to your RDS cluster by using the following command filling in your instance ID (you might need to install Session Manager CLI):

aws ssm start-session \
    --region eu-west-1 \
    --target <your instance id> \
    --document-name AWS-StartPortForwardingSessionToRemoteHost \
    --parameters host="<your RDS dns name>",portNumber="3306",localPortNumber="3399"

I am using MySQL here so I need to use 3306, but for Postgres you could use 5432.

The database will now be available on localhost:3399:

localhost:3399

We can now connect via some tool (TablePlus is my favourite):

You might need to create a new database if the cluster bootstrapping did not do that for you (it is a setting when you create the database).

Depending on the spot price this allows you access to your RDS cluster for as low as 1 USD per month. Note that your cost will go up next year because Elastic IP’s will be charged around 3.6 USD per month from then on.

You can also just use this Terraform module for NAT instances, it already is configured properly to serve as a SSM node. It also configures with spot instances. This way you do not need to add any new instances for this service.

If you have trouble connecting login to the EC2 instance with Systems Manager Session Manager and tail the logs in /var/log/amazon/ssm/errors.log to see what is going on. Most likely the security group of the RDS instance is not allowing traffic from the EC2 instance.

You can also use this to remotely access AWS EFS volumes

The code is very similar:

aws ssm start-session \
    --region eu-west-1 \
    --target i-09e4ddd26eab49f68 \
    --document-name AWS-StartPortForwardingSessionToRemoteHost \
    --parameters host="fs-0237f0e4ed67f5a7c.efs.eu-west-1.amazonaws.com",portNumber="2049",localPortNumber="2049"

You can then connect via the EFS helper tool locally on your machine to the EFS volume.