When you start using AWS RDS, you might end up creating a new database that is publicly accessible to start playing with it quickly. When it comes to security, having a public accessible DB is a bad idea. So, in this guide, we will show you, how to migrate a public RDS DB to be private without losing any data.
We have an API deployed to Amazon EC2 that is using a RDS Database that was created publicly accessible and we want to make it private.
Create a new route table without internet gateway association. Go to VPC → Route Tables
Put a descriptive name to the Route Table created to identify it
Create two new subnets and add them to the route table created in the previous step. Go to VPC → Subnets
If you don’t know how to setup Subnet CIDR, verify the pattern that is being used on the other subnets. For further information you can read this post.
After this step if you try to associate the new subnet group to your RDS DB you will receive the following error:
You cannot move DB instance XXX to subnet group XXX. The specified DB subnet group and DB instance are in the same VPC. Choose a DB subnet group in different VPC than the specified DB instance and try again. (Service: AmazonRDS; Status Code: 400; Error Code: InvalidVPCNetworkStateFault; Request ID: 7d46c84c-b22a-11e6-be20-b5bb6bd6cc6d)
Workaround for previous error:
Create temporal VPC. Set the VPC CIDR to 172.16.0.0/16.
Create two new temporal Subnets for the new Temp VPC. You can use the below examples:
Private1 in us-east-1a: 172.16.1.0/24
Private2 in us-east-1b: 172.16.2.0/24
Go to RDS and create a new temporal Subnet group with the just created subnets
Modify the RDS DB instance to reside in the new Subnet group created for the new VPC
After changes are completed. Modify RDS DB instance again to point to Subnet group created in step 3
Test API is still working
Clean up temporal VPC/Subnets/Subnets group created.
Go to VPC → Select temporal VPC and delete it. (It will remove all associated assets)
Be careful with this last step, as you can delete unwanted VPC
As the DB is private now, the only way that a developer can connect to the DB for development purposes is using a tunnel connection from another AWS accessible asset. In this case, we will use the EC2 machine where the application is deployed to establish an SSH tunnel to the DB
Go to EC2 -> Key Pairs and create a new key pair for the application
Go to your elastic beanstalk environment, Configuration -> Security
Add the created key pair to the environment and apply changes
Environment will replace the EC2 instance and restart
Test BE API is working
Go to your DB Tool and configure the ssh tunnel connection
In host put the EC2 IP address
User name -> ec2-user
Auth method -> Public Key -> Add the pem file for the EC2 machine
Test the connection.
Troubleshooting tip. If it fails to connect, check the security group of the EC2 machine to verify that the DB port is allowed.