To VPC or not to VPC...
Tags: serverless, aws, database, programming
Published: 2022-11-03 00:22:34

If you are building on AWS you've probably run into the situation where you have a Lambda that needs to talk to a database.  Easy right... well, it actually requires some non-trivial knowledge of concepts like VPCs, subnets, and security groups.  Probably more than what you initially bargained for.

Of course, you probably made it through this (there are a plethora of tutorials solving this exact thing) and also realized the importance of restricting access to your database by placing it within the confines of a VPC.

Then your use case changed and now you need to make a network request from a public source to your Lambda.  Problem is, the Lambda is inside a VPC which is not accessible to the public internet.

After days spent scouring the internet for solutions to this problem, here is what I found.

1. Get rid of the VPC, who needs 'em anyway? Seriously though... don't do this.  The most valuable asset to any application is its data.  If you make your database public by taking it out of the VPC, the only thing separating your data from a hacker is an alphanumeric username and password combination.  Sure, you could have a **strong** password but you have to really be comfortable with that risk.  Most people aren't.

2. Even better, just use a NAT gateway.  A NAT gateway allows a Lambda in a VPC to be assigned a publicly addressable IP address.  Once you make it past the finicky nature of setting up this configuration, it works really well.  The Lambda is publicly accessible, can query the database and return a response to the user, just like you drew it up.  One caveat though, there is no free tier.  To this point, you're likely still paying 0$ for your database and Lambda.  However, the NAT gateway is going to cost you a whopping $30 monthly.  That is steep, especially if you are trying to build out a serverless stack on the cheap.  For me, it just wasn't worth it - there had to be a better way.

This is where it got difficult.  There didn't _seem_ to be another way.  It looked fairly certain that I would either have to sacrifice security or pay a prohibitive cost.  However, I dug to the deepest depths of the internet (Stackoverflow) and eventually the heavens opened up revealing a closely guarded secret, https://stackoverflow.com/a/41559669, which led me to the following,

Use a public Lambda to call the private Lambda.  That sounds so obvious in hindsight.  But wait, I thought the VPC Lambda wasn't publicly accessible.  That certainly is true, but apparently the `Invoke` API does not adhere to such mortal rules.  Now, you can have your cake and eat it too.  We retain the security of having the database in the VPC, while also keeping costs at zero.  The only downside is you will have to manage several Lambdas which does add some operational overhead.  It also slightly complicates the debugging process, as each Lambda has its own logging group and figuring out which one is behaving poorly can be a tad tedious.

Anyways, hope this was education and/or helps someone who finds themself in a similar situation.  Curious to see what else the community has to say about VPC, Lambdas, and the like.

Thanks for reading!