Setup a SSH tunnel

Header image

Often you need to migrate production data back to your development environment.

In our case we use virtual private networks with strict private- and public subnets in order to secure our infrastructure, e.g. access to the database or hotfixing something via a remote shell (keep 12-factor's admin processes in mind).

However, that makes accessing production data quick and easily (so no developer unfriendly RDS snapshot S3 transfers) hard as we can't access a resource in a private subnet from the outside.

Gladly we have something called bastion hosts with gives us a helping hand.

In the example below we have a postgres database running on a RDS instance in a private subnet. On the other hand we have a tiny EC2 instance in a public subnet which accepts incoming traffic over SSH (port 22) retricted to our IP address. The same instance (the bastion host) is allowed to access the database in the private subnet.

Now let's setup a SSH tunnel:

ssh -L 8001:yourendpointhere.eu-west-1.rds.amazonaws.com:5432 ubuntu@<public_ip_bastion_host>

Once setup your SSH tunnel you are able to e.g. create database backups easily to your local machine:

pg_dump -Fc -v -h localhost -p 8001 -U [master username] [database] > [database].dump

Using Django you are also able to run your local code in the remote shell (using the django-environ library):

DATABASE_URL=postgresql://postgres:xxx@localhost:8001/[database] python manage.py shell