Apex UP Lambda VPC Permissions

July 20, 2018

I recently started using Apex’s UP which is a fantastic tool to get a serverless API up and running quickly. I had previously written the application as a traditional Go API listening on an HTTP port and did not want to do a lot of work to take advantage of AWS’ Lambda.

After making sure that my main function had a fast startup to make sure the lambda executed efficiently, it did not take very long to get it deployed as an API with all of the bells and whistles using UP’s fantastic features.

The problem however, was that I also had a running EC2 instance running a small database that the API uses. This database is running inside a private VPC that is not accessible by the Internet, which meant that deploying the serverless API out of the box would not work with the database as it couldn’t connect to it. Lambda’s default permissions are public and thus do not have access to internal VPC resources.

Up Config

Up has great documentation and tells you how to do this: https://up.docs.apex.sh/#configuration.lambda_settings

You simply assign your lambda at least one subnet (preferably two) and a security group. You have to assign both, you cannot just use subnets and leave the security group field blank.

I assigned my lambda the default security group (open to the public) that AWS created for me when I created the EC2 instance and VPC, and also assigned it one of the public subnets.

NAT Gateway

This won’t work out of the box. If it’s a brand new AWS account (mine was) you need to create a NAT Gateway, this video: https://aws.amazon.com/premiumsupport/knowledge-center/nat-gateway-vpc-private-subnet/ explains in detail how to do that and it will also show you how to create a private subnet. By default all of your subnets are public (if they are created through the EC2 wizard form) so you will need to choose a subnet (preferably one not used by any other resource) and convert it from a public to private subnet. How?

Private subnet

Create a new routing table

Under VPC -> Routing table, create new a table (i had one already created) your new routing table will need to have two entries like this:

Destination Target
172.31.0.0/16 local
0.0.0.0/0 nat-**

Note: your other routing table, probably has 0.0.0.0/0 pointing to your Internet Gateway, we want it to point to our newly created NAT Gateway

Update subnet

Now pick a couple of subnet(s) of your choice or create new ones and use the newly created routing table. After it’s all said and done, you should be able to use those two subnets and the default public SG on your Lambda config to get access to internal VPC resources.