Tag Archives: Amazon Web Services

Connecting to an RDS instance in a VPC

Disclaimer: For those who don’t know what RDS and VPC stand for, this post is not for you.

I was working on a project recently where I was developing a Java app that connected to a mysql database. For simplicity sake, I had set up the database in RDS on AWS and wanted to connect from my local machine. I figure I could test the code locally, then push it out to an EC2 instance later.

The problem (security benefit?) is that by default RDS instances in a VPC are not publicly accessible. The RDS team implemented an option when you create your RDS instance via the console to enable this, but since I had created mine as part of a larger CloudFormation script, I was out of luck. I also tried checking the AWS Command Line Interface (CLI) toolkit, but again, that option had not yet been implemented there, either.

Some additional internet searching led me to the idea of using a ssh tunnel to connect to my RDS instance via my EC2 instance running in my VPC. Since my EC2 instance was accessible, I could connect to it from my local laptop. My confusion, however, was two-fold. First, where does the tunnel run? And second, what configuration items need to be put in place to make this work. Here is what I learned.

1. Make sure that as part of your CloudFormation script you open the port you want to use on EC2 so that it is accessible. I’m using port 3306, so I added this port to my EC2 security group in my CloudFormation script.

"MyEc2SecurityGroup": {
      "Type": "AWS::EC2::SecurityGroup",
      "Properties": {
        "VpcId": {
          "Ref": "VPCId"
        },
        "GroupDescription": "Enable SSH and MySQL access",
        "SecurityGroupIngress": [
          {
            "IpProtocol": "tcp",
            "FromPort": "22",
            "ToPort": "22",
            "CidrIp": {
              "Ref": "SSHLocation"
            }
          },
          {
            "IpProtocol": "tcp",
            "FromPort": "3306",
            "ToPort": "3306",
            "CidrIp": {
              "Ref": "SSHLocation"
            }
          }
        ]
      }

2. The ssh tunnel actually runs on YOUR computer, not on the EC2 instance. As someone relatively inexperienced with creating ssh tunnels, this was a surprise to me.

3. Thekeesh.com provided a useful tutorial that helped me get my ssh tunnel running. You will need to open up a command line prompt to run this command.

The key piece his article was missing was the need to include a link to the PEM keyfile. My command to launch the ssh tunnel instead looked more like this.

ssh -i <path to keyfile.pem> -N -L 3306:<rds dns entry name>:3306 <ec2 user id>@<ec2 ip address>

For example, my ssh tunnel command might look like this if I were using ubuntu linux on EC2

ssh -i /users/me/mykey.pem -N -L 3306:abcd1234.efgh5678.us-east-1.rds.amazonaws.com:3306 ubuntu@54.0.0.1

4. In my Java app, my connection string actually uses the local loopback IP to connect to RDS.

jdbc:mysql://127.0.0.1:3306/MyDatabase