Putting Your Lambda In A VPC

How to get your lambda in your default VPC and still retain internet access.

When our system was first written, lambdas didn’t exist. Which was a shame, as they’re pretty much exactly what we needed. Now we’re moving- all the new stuff is in lambdas, and the old architecture is being broken up and distributed.

Having learned the lesson from Netscape, we’re transitioning to a better world one piece at a time. That means we’re now in a halfway house- our lambdas need access to our systems that are still hosted in EC2. Of course, as with most things on AWS, it’s not as simple as flipping a switch. So here’s how I did it today.

Create an NAT Gateway. Simply put, an NAT Gateway allows you to bridge from a private subnet (more on that later) into a public one. When you create your NAT Gateway, (from the VPC Dashboard) you’ll need to specify two things:

The first is the public subnet that the NAT will be created in. The default subnet for your VPC will be public. You can tell if you subnet is public by having a look at the Route Table. If it includes a line routing to an internet gateway (typically 0.0.0.0/0 -> igw-1234567) then it’s public.

The next is the Elastic IP. Probably, you’ll want to hit the button to generate one from the dialog. Effectively it’s a static, public, IP address that AWS will keep assigned to your gateway- even if they replace the instance with a new one.

Create a subnet. VPCs are broken down into subnets, and your lambdas need their own. Annoyingly, they can only exist in a ‘private’ state (which is why we have to do all this mucking around.) Subnets can be created from the VPC Dashboard as well. You’ll need to give it a name, and specify what VPC it should be created in- which should be the same VPC as the NAT Gateway, and the EC2 resources you want to access.

Subnets are a way of delimiting all the IP addresses within your VPC. You’ll be prompted to provide an IPv4 CIDR block, which is a way of specifying a span of addresses. There’s no hard and fast rules- but I’m in the habit of specifying AAA.BBB.CCC.0/20 where A and B are the same as the highest CIDR block already defined by the VPC subnets, and C is 16 more. For example, if the highest defined is 127.16.16.0/20 then the new one will be 127.16.32.0/20.

Route the new subnet through the NAT gateway. By routing the new subnet through your gateway, you give it access outside of it’s private bubble to your other AWS resources (and the internet). To do this, edit the route table of your new subnet, so that 0.0.0.0/0 targets your new NAT’s address (e.g. the second line should be 0.0.0.0/0 -> nat12345678...).

Configure you lambda. You can do this in the UI (it’s tucked under configuration/advanced) or through the amazing Serverless Framework. The bare minimum you need to do is assign it to your newly created subnet. However, if you’ve got EC2 configured with security groups (which you should), then you’ll be able to assign what groups the lambda belongs to too.

And that’s “it”. Feel free to drop a comment if you’ve got any questions! There’s a whole world of adding multiple subnets to cross different availability zones, linking to the non-default VPC, and sizing your subnet; but that’s for another day!