VPC configuration to communicate with external networks outside AWS

My situation is the following:

  • I’m using Amazon Web Services (AWS) as the infrastructure provider of my project.
  • AWS is fantastic but it can become expensive really fast.
  • I want to minimize my spending while still being able to use the best parts of AWS’ offering for some of the managed services I use.
  • This is all for my development environment, but it can very well be used for production too.

My constraints are the following:

  • I’m using MySQL managed by RDS.
  • I’m running one EC2 instance where I have a web app.
  • I’m using Ray autoscaler for scaling the app’s workload.
  • I need an ElasticSearch instance but I don’t want to pay for the managed service on development.
  • I want my development environment to look as close as posible to my production enviroment.

So, being the cheap developer that I am, or as I prefer to call it, the financially-responsible developer that I am, I found a pretty convenient solution to this likely not-so-uncommon problem.

Why not just run an instance of MySQL, ElasticSearch, and Nginx in my local LAN and avoid all this trouble?

Because I want my dev environment to closely resemble my production environment without paying for managed services I don’t need in development.

Plus, I need the Ray autoscaler to work on Development too and although it supports running on custom clusters, configuring that will require having to maintain two branches of the autoscaler configuration and that would cost more money overall in terms of time investment required.

The solution

I decided to create a t2.micro instance of OpenVPN that would serve as the entry point to my AWS network, and have my development laptop plus another personal computer that I had sitting in my house running Ubuntu to act as cheap development servers without significantly impacting the development architecture compared to the architecture that will ultimately run production.

To do this yourself:

  • Install OpenVPN on an EC2 instance. There are plenty of tutorials out there that can help you with this, for example this one. I know that AWS has its own VPN solution, but using it would defeat the purpose of keeping everything as cheap as possible.
  • Go to your VPC configuration on AWS and open the Route Tables configuration.

  • Depending on the number of VPCs that you have, the number of routes may vary but in general, you should choose the one that applies to the VPC you want to enable to communicate with your external OpenVPN network. Click on that route.
  • You should find 2 routes there, one to your local AWS network and one to the Internet Gateway. Both come configured by default. Click on Edit Routes.

  • Inside the Destination column, add the CIDR block that corresponds to the one you configured in your OpenVPN setup. Mine, and the default one for OpenVPN, is 10.8.0.0/24.

  • Inside the Target column, choose the instance where your OpenVPN server is running and click on Save Changes.

  • Finally, and the part that is the least obvious, go to your EC2 instances and choose again the one running OpenVPN. Click on Actions > Networking > Change source/destination check.

  • Check Stop and then Save it. This will make your instance to accept traffic coming from other instances and destined to outside networks to pass through it without being checked/rejected.

  • After all of this, you should be able to seamlessly connect to your OpenVPN clients running on your LAN from inside AWS, using their 10.8.0.0/24 addresses. Very cool.

This relatively simple configuration allowed me to considerably reduce my spending on servers while keeping the relevant parts of my development environment running on AWS. It did increase bandwidth usage but that was okay for me in terms of costs.