AWS Lambda connecting to Internet
Since I faced the same issue adding a bit more clarity to the above answer -
- Add NAT Gateway or NAT instance to public subnet (the one that has an
0.0.0.0/0
entry to internet gateway in corresponding (public) subnets route table) - Edit route table of private subnet (where you are running your lambda) to have an entry for
0.0.0.0/0
to the NAT gateway in the public subnet. - Make sure security group assigned to lambda allows outbound connections.
By default, a lambda function is not bounded to a VPC, which enables it to have internet access, but prevents it from accessing resources in a VPC, such as RDS instances.
If you attach the lambda to a VPC, you'll loose internet access, which prevents you from accessing resources such S3 and Dynamo, and from making HTTP requests.
If you need both, then I'll have to set up the VPC for internet access, which is a mess (hey AWS guys, if you have a well-defined process for it, please make it simple: turn it into a checkbox or button ;)
Create a new VPC
I find it's best to leave the default VPC alone, so you don't take the risk of breaking something that's already working in that VPC (in case you already have resources there), and also because you can use the default VPC as configuration reference in the future.
Use the wizard for creating the VPC.
Create the Route Tables
- Name the first
public-subnet
(if it's not already there); - Name the second
private-lambda
. AWS support recommends having a separate subnet just for the lambda, and this Route Table is going to be attached to it.
Create the subnets
By default, when you create a VPC, it will create a public subnet for you. If you used default values, its name should be Public subnet
. Leave it at that.
Now you are going to create the private subnets. Is recommended to have several private subnets for your Lambda if you want it to have high availability.
Each of these private subnets will be linked to the VPC you just created. Now, supposing you left the VPC IP as 10.0.0.0/16
, and that you run your resources in Virginia (us-east-1
), here is a template for creating six private subnets, each in a different availability zone (for high availability):
private-lambda-us-east-1a
, availability zoneus-east-1a
, IP block10.0.16.0/24
private-lambda-us-east-1b
, availability zoneus-east-1b
, IP block10.0.32.0/24
private-lambda-us-east-1c
, availability zoneus-east-1c
, IP block10.0.48.0/24
private-lambda-us-east-1d
, availability zoneus-east-1d
, IP block10.0.64.0/24
private-lambda-us-east-1e
, availability zoneus-east-1e
, IP block10.0.80.0/24
private-lambda-us-east-1f
, availability zoneus-east-1f
, IP block10.0.92.0/24
But you can see the pattern: - There's a 16 increment in the 3rd position of the IP block; - The names indicate the selected availability zone in your region.
Ensure Route Table vs Subnet associations
- Go to the Route Tables panel;
- Select the public-subnet table, review its associations and make sure it's associated to the Public Subnet;
- Select the private-lambda table, review its associations and make sure It's associated to all the
private-lambda-*
subnets you just created.
Create an Internet Gateway
Just create one and attach it to the VPC.
Configure the routes for the Public Subnet
In my case it came configured, but just make sure that the Route Table for your Public Subnet has an entry from 0.0.0.0/0
to your just-created Internet Gateway.
Create a NAT (network address translator)
Create a new NAT and select your Public Subnet. Allocate a new EIP.
Configure the routes for the Private Subnets
Ensure that the Route Table for your Private Subnets has an entry from 0.0.0.0/0
to your new NAT.
And with these steps, you should now have an Internet-enabled VPC.
Use Case: configuring a Lambda for internet and RDS access
Create a Security Group for the lambda
- New up a SG and configure Outbound -> All Trafic -> to
0.0.0.0/0
and::/0
Modify the Security Group of your RDS instance to allow
- Inbound -> All trafic -> from the lambda SG
Configure the lambda
- Create a new lambda or select an existing one;
- Select your new VPC;
- Select all your private subnets (
private-lambda-*
) for high availability; - Select your lambda Security Group.
And that's it. You should now have a lambda function that can access both VPC and Internet resources :)
I found the error, the NAT Gateway should be added to a public subnet (not a private one).
A public subnet is the subnet with the Internet Gatway route associated to 0.0.0.0/0
If you are to do this with Terraform, here are the resources that you will need to configure (in addition to Lambda resources):
aws_vpc
aws_subnet
(public and private; multiple for high availability)aws_internet_gateway
for outbound connection to the internetaws_route_table
(x2 for public and private subnets)aws_route_table_association
aws_eip
(Elastic IP for the NAT Gateway)aws_nat_gateway
aws_default_network_acl
to manage the default NACL with Terraformaws_default_security_group
to manage the default Security Group with Terraformaws_iam_role_policy_attachment
to attachAWSLambdaVPCAccessExecutionRole
policy
Deploy AWS Lambda to VPC with Terraform.