Create a gist now

Instantly share code, notes, and snippets.

Embed
What would you like to do?

How to setup AWS lambda function to talk to the internet and VPC

I'm going to walk you through the steps for setting up a AWS Lambda to talk to the internet and a VPC. Let's dive in.

So it might be really unintuitive at first but lambda functions have three states.

  1. No VPC, where it can talk openly to the web, but can't talk to any of your AWS services.
  2. VPC, the default setting where the lambda function can talk to your AWS services but can't talk to the web.
  3. VPC with NAT, The best of both worlds, AWS services and web.

I'm gonna walk you through the steps to set up number 3.

Note: This tutorial isn't exactly in order of steps, you may need to create one thing (subnet, nat, route table) then go back into the settings for something previously created and edit it to use a newly thing.

Creating Subnets

VPC Dashboard > Subnets

This is what I had to start with, my existing vpc that I wanted to connect to already had 4 subnets. Here I noticed I had a couple of subnets already set up. Below is a totally fake ip I pulled from the internet. But the patten of increments of 16 is recreated here.

Note: DO NOT use 131.179.0.0/16 it's just an example.

VPC CIDR
vpc-████████ (131.179.0.0/16) 131.179.0.0/20
vpc-████████ (131.179.0.0/16) 131.179.16.0/20
vpc-████████ (131.179.0.0/16) 131.179.32.0/20
vpc-████████ (131.179.0.0/16) 131.179.48.0/20

Here I created three four new subnets.

VPC CIDR name
vpc-████████ (131.179.0.0/16) 131.179.64.0/20 lambda-subnet-point-to-nat-1
vpc-████████ (131.179.0.0/16) 131.179.80.0/20 lambda-subnet-point-to-nat-2
vpc-████████ (131.179.0.0/16) 131.179.96.0/20 lambda-subnet-point-to-nat-3
vpc-████████ (131.179.0.0/16) 131.179.112.0/20 lambda-subnet-point-to-igw

Note: Here igw stands for Internet Gateway and nat stands for network address translation gateway (NAT Gateway).

Three of them will point to the nat and one points to the igw.

Let's create the Route Tables now.

Creating Route Tables

VPC Dashboard > Route Tables

Your going to want to set up two Route Tables.

One that points to your nat let's call this lambda-rt-to-nat:

Destination Target
131.179.0.0/16 local
0.0.0.0/0 nat-█████████████████

One that points to your igw let's call this lambda-rt-to-igw:

Destination Target
131.179.0.0/16 local
0.0.0.0/0 igw-████████

Your gonna want to go into each of the subnet and assign them to their corresponding route table.

subnet name route table name
lambda-subnet-point-to-nat-1 lambda-rt-to-nat
lambda-subnet-point-to-nat-2 lambda-rt-to-nat
lambda-subnet-point-to-nat-3 lambda-rt-to-nat
lambda-subnet-point-to-igw lambda-rt-to-igw

Set your lambda up

Lambda > Functions > my-function > Configuration > Advanced Settings

Now you want to set up your lambda function to use the subnets you created.

Setup your lambda to use your VPC.

VPC

vpc-████████ (131.179.0.0/16)

Here you setup lambda to use the subnets that point directly to your nat.

Subnets*

subnet name
lambda-subnet-point-to-nat-1
lambda-subnet-point-to-nat-2
lambda-subnet-point-to-nat-3

Create a NAT

VPC Dashboard > NAT Gateways > Create NAT Gateway

Your going to want click Create NAT Gateway and set the Subnet* to lambda-subnet-point-to-igw, and Create New EIP.

Fin

That should be it! Your lambda should be able to talk to both the VPS and the web through a NAT! Comment below if you need help or want to clarify anything here!

Links

Shameless SEO terms

  • amazon lambda nat
  • aws lambda vpc web
  • aws lambda rds and web
  • aws lambda rds and http request
  • lambda timeout
  • AWS lambda timeout random vpc
@scott2b

This comment has been minimized.

Show comment
Hide comment
@scott2b

scott2b Aug 17, 2016

I am confused about why you have associated the lambda-subnet-point-to-igw subnet with the NAT gateway, rather than the 3 nat subnets

scott2b commented Aug 17, 2016

I am confused about why you have associated the lambda-subnet-point-to-igw subnet with the NAT gateway, rather than the 3 nat subnets

@vineus

This comment has been minimized.

Show comment
Hide comment
@vineus

vineus Aug 22, 2016

Thank you for the very clear tuto, works like a charm and way clearer than the doc. I used it to answer SO question here: http://stackoverflow.com/a/39082826/219265

vineus commented Aug 22, 2016

Thank you for the very clear tuto, works like a charm and way clearer than the doc. I used it to answer SO question here: http://stackoverflow.com/a/39082826/219265

@DanielRuskin1

This comment has been minimized.

Show comment
Hide comment
@DanielRuskin1

DanielRuskin1 Aug 23, 2016

@scott2b I think it's because:

  1. The Lambda is in one of the "point to NAT" subnets, and as such points traffic to the NAT
  2. When the NAT gets traffic, it needs something to send it out to the internet with (the IGW). So we put it in the IGW's subnet.

@scott2b I think it's because:

  1. The Lambda is in one of the "point to NAT" subnets, and as such points traffic to the NAT
  2. When the NAT gets traffic, it needs something to send it out to the internet with (the IGW). So we put it in the IGW's subnet.
@rydogjones

This comment has been minimized.

Show comment
Hide comment
@rydogjones

rydogjones Sep 17, 2016

Just want to say thanks for the clear, step by step...we need more AWS docs like this!

Just want to say thanks for the clear, step by step...we need more AWS docs like this!

@lukeggchapman

This comment has been minimized.

Show comment
Hide comment
@lukeggchapman

lukeggchapman Sep 22, 2016

This helped me a lot. Thank you!

This helped me a lot. Thank you!

@leedjones

This comment has been minimized.

Show comment
Hide comment
@leedjones

leedjones Oct 10, 2016

This fails for me setting up the route tables. It wont let me add another route with the error

There are not any Internet Gateway, Network Interface, or Virtual Private Gateway targets.

This fails for me setting up the route tables. It wont let me add another route with the error

There are not any Internet Gateway, Network Interface, or Virtual Private Gateway targets.

@mmmnt

This comment has been minimized.

Show comment
Hide comment
@mmmnt

mmmnt Dec 1, 2016

Thanks man, saved my day :-)

mmmnt commented Dec 1, 2016

Thanks man, saved my day :-)

@SnowSprout

This comment has been minimized.

Show comment
Hide comment
@SnowSprout

SnowSprout Dec 12, 2016

Thank you!!

Thank you!!

@dparlar

This comment has been minimized.

Show comment
Hide comment
@dparlar

dparlar Dec 14, 2016

This solution works perfectly. Thank you for writing this up :)

dparlar commented Dec 14, 2016

This solution works perfectly. Thank you for writing this up :)

@Asoul

This comment has been minimized.

Show comment
Hide comment
@Asoul

Asoul Jan 12, 2017

Thank you so so so much!!!!! This work well 👯‍♂️

Asoul commented Jan 12, 2017

Thank you so so so much!!!!! This work well 👯‍♂️

@postme

This comment has been minimized.

Show comment
Hide comment
@postme

postme Jan 13, 2017

Thank you very much, this really helped me!

postme commented Jan 13, 2017

Thank you very much, this really helped me!

@JonathanBAdams

This comment has been minimized.

Show comment
Hide comment
@JonathanBAdams

JonathanBAdams Jan 26, 2017

I'll second leedjones' comment. I don't recall this being a problem the last time I created a VPC. Beside the "Add another route" button, you'll see the warning, "There are not any Internet Gateway, Network Interface, or Virtual Private Gateway targets."

Actually, the problem is suggested in the tutorial, which has us point a route to the nat and igw before having us create the nat (creating the igw is not mentioned.)

I was able to get around this by creating the NAT Gateway before editing the route tables. You'll need to do the same thing for an IGW, and don't forget to attach it to the appropriate VPC before trying to edit the route tables. (Actually, you need to do the IGW first or the NAT Gateway creation fails.)

JonathanBAdams commented Jan 26, 2017

I'll second leedjones' comment. I don't recall this being a problem the last time I created a VPC. Beside the "Add another route" button, you'll see the warning, "There are not any Internet Gateway, Network Interface, or Virtual Private Gateway targets."

Actually, the problem is suggested in the tutorial, which has us point a route to the nat and igw before having us create the nat (creating the igw is not mentioned.)

I was able to get around this by creating the NAT Gateway before editing the route tables. You'll need to do the same thing for an IGW, and don't forget to attach it to the appropriate VPC before trying to edit the route tables. (Actually, you need to do the IGW first or the NAT Gateway creation fails.)

@mp3il

This comment has been minimized.

Show comment
Hide comment
@mp3il

mp3il Jan 30, 2017

Wooha! Thats super useful. thanks!

mp3il commented Jan 30, 2017

Wooha! Thats super useful. thanks!

@bdecotes-pl

This comment has been minimized.

Show comment
Hide comment
@bdecotes-pl

bdecotes-pl Feb 15, 2017

This helped me out quite a bit. Thank you!

This helped me out quite a bit. Thank you!

@sandeshbsuvarna

This comment has been minimized.

Show comment
Hide comment
@sandeshbsuvarna

sandeshbsuvarna Feb 21, 2017

Life saver !!!!!

Life saver !!!!!

@pizza-r0b

This comment has been minimized.

Show comment
Hide comment
@pizza-r0b

pizza-r0b Feb 24, 2017

👍 Thanks!

👍 Thanks!

@Dambre

This comment has been minimized.

Show comment
Hide comment
@Dambre

Dambre Mar 13, 2017

OMG, It is working!

Dambre commented Mar 13, 2017

OMG, It is working!

@eastjavabaker

This comment has been minimized.

Show comment
Hide comment
@eastjavabaker

eastjavabaker Mar 24, 2017

NAT gateway must created first before create new route-tables with destination to NAT gateway

eastjavabaker commented Mar 24, 2017

NAT gateway must created first before create new route-tables with destination to NAT gateway

@jigarcaptain

This comment has been minimized.

Show comment
Hide comment
@jigarcaptain

jigarcaptain Apr 12, 2017

Thanks a lot.

This is probably the best description I’ve seen so far. ~ My Manager

Thanks a lot.

This is probably the best description I’ve seen so far. ~ My Manager

@ihsanhaikalz

This comment has been minimized.

Show comment
Hide comment
@ihsanhaikalz

ihsanhaikalz May 22, 2017

I have followed your instruction here but still my lambda can't send post request to my server, my code is like this https://stackoverflow.com/questions/43998130/send-aws-s3-events-in-cloudwatch-to-my-server-using-lambda-in-java but not sure where it is wrong

I have followed your instruction here but still my lambda can't send post request to my server, my code is like this https://stackoverflow.com/questions/43998130/send-aws-s3-events-in-cloudwatch-to-my-server-using-lambda-in-java but not sure where it is wrong

@hovhanneskhalatyan

This comment has been minimized.

Show comment
Hide comment
@hovhanneskhalatyan

hovhanneskhalatyan May 24, 2017

Thank you very much!!!

Thank you very much!!!

@cagataygurturk

This comment has been minimized.

Show comment
Hide comment
@cagataygurturk

cagataygurturk May 28, 2017

2. VPC, the default setting where the lambda function can talk to your AWS services but can't talk to the web.

This is not correct. AWS services are also on Public Internet so you have NAT Gateway and you can access AWS API's and other Internet resources or you can't connect to none of them.

2. VPC, the default setting where the lambda function can talk to your AWS services but can't talk to the web.

This is not correct. AWS services are also on Public Internet so you have NAT Gateway and you can access AWS API's and other Internet resources or you can't connect to none of them.

@b-nroths

This comment has been minimized.

Show comment
Hide comment
@b-nroths

b-nroths Jun 20, 2017

Thank you!

Thank you!

@jeanmidevacc

This comment has been minimized.

Show comment
Hide comment
@jeanmidevacc

jeanmidevacc Jul 17, 2017

Awesome tutorial, very clear thanks !!

Awesome tutorial, very clear thanks !!

@KMNowak

This comment has been minimized.

Show comment
Hide comment
@KMNowak

KMNowak Jul 24, 2017

Thank you for this guide. Works perfect!

KMNowak commented Jul 24, 2017

Thank you for this guide. Works perfect!

@romaninsh

This comment has been minimized.

Show comment
Hide comment
@romaninsh

romaninsh Aug 16, 2017

I had to implement above Lambda VPC setup with Internet access inside a CloudFormation template:

https://gist.github.com/romaninsh/81d4ee778c1e20f709f3518c22521ba4

I had to implement above Lambda VPC setup with Internet access inside a CloudFormation template:

https://gist.github.com/romaninsh/81d4ee778c1e20f709f3518c22521ba4

@voho

This comment has been minimized.

Show comment
Hide comment
@voho

voho Aug 24, 2017

Hi, first - thanks for a great tutorial!!!
Some tips:

  • Could you please add a section on how to test this setup? Maybe simple JS/Python Lambda code?
  • I also second that the NAT must be created just after the subnets, before the routing tables.

voho commented Aug 24, 2017

Hi, first - thanks for a great tutorial!!!
Some tips:

  • Could you please add a section on how to test this setup? Maybe simple JS/Python Lambda code?
  • I also second that the NAT must be created just after the subnets, before the routing tables.
@kevupton

This comment has been minimized.

Show comment
Hide comment
@kevupton

kevupton Aug 29, 2017

WOW. 24 hours later, you life saver
Why is it so hard to find any information on this.

WOW. 24 hours later, you life saver
Why is it so hard to find any information on this.

@mikehains

This comment has been minimized.

Show comment
Hide comment
@mikehains

mikehains Oct 16, 2017

Much much appreciated. Simple instructions, followed easily. Thank you !

Much much appreciated. Simple instructions, followed easily. Thank you !

@codekipple

This comment has been minimized.

Show comment
Hide comment
@codekipple

codekipple Oct 26, 2017

Thanks so much. I was struggling to get to get my lambda setup and this helped me understand what my problem was.

Thanks so much. I was struggling to get to get my lambda setup and this helped me understand what my problem was.

@seydabenzer

This comment has been minimized.

Show comment
Hide comment
@seydabenzer

seydabenzer Nov 16, 2017

You saved another day. Thanks a lot! <3

You saved another day. Thanks a lot! <3

@scottishbee

This comment has been minimized.

Show comment
Hide comment
@scottishbee

scottishbee Nov 19, 2017

I'm trying to get my Lambda function to talk to another service that requires whitelisting. Which of these IPs can I give them to whitelist?

I'm trying to get my Lambda function to talk to another service that requires whitelisting. Which of these IPs can I give them to whitelist?

@caitlinosh

This comment has been minimized.

Show comment
Hide comment
@caitlinosh

caitlinosh Dec 8, 2017

This is great! I was wondering if after you did this you could access your rds from the command line? I have my inbound and outbound ports set to all traffic in my rds security group, but I still get this error "ERROR 2003 (HY000): Can't connect to MySQL server on 'thursdaydatabase.chtwndzhnycc.us-east-1.rds.amazonaws.com' (60)".

This is great! I was wondering if after you did this you could access your rds from the command line? I have my inbound and outbound ports set to all traffic in my rds security group, but I still get this error "ERROR 2003 (HY000): Can't connect to MySQL server on 'thursdaydatabase.chtwndzhnycc.us-east-1.rds.amazonaws.com' (60)".

@joshhornby

This comment has been minimized.

Show comment
Hide comment
@joshhornby

joshhornby Jan 6, 2018

This works perfectly. Thank you so much!

This works perfectly. Thank you so much!

@seaweasel

This comment has been minimized.

Show comment
Hide comment
@seaweasel

seaweasel Jan 17, 2018

I just want you to know I'm naming my firstborn after you.

I just want you to know I'm naming my firstborn after you.

@liuxuc

This comment has been minimized.

Show comment
Hide comment
@liuxuc

liuxuc Jan 19, 2018

Works like a charm! Really appreciate the article. Thanks!

liuxuc commented Jan 19, 2018

Works like a charm! Really appreciate the article. Thanks!

@igorescobar

This comment has been minimized.

Show comment
Hide comment
@igorescobar

igorescobar Jan 31, 2018

It works! <3

It works! <3

@ramirezzRK

This comment has been minimized.

Show comment
Hide comment
@ramirezzRK

ramirezzRK Feb 17, 2018

Thanks so much for this tutorial. Lot of head scratching about this one

Struggled a bit with very last step "Create a nat" which I found hard to imagine in the context (I know, begginer :/) This is super important step as it creates bridge between nat and igw subnets!!!

I Imagine it works something like this:

https://imgur.com/Xro1YqO

ramirezzRK commented Feb 17, 2018

Thanks so much for this tutorial. Lot of head scratching about this one

Struggled a bit with very last step "Create a nat" which I found hard to imagine in the context (I know, begginer :/) This is super important step as it creates bridge between nat and igw subnets!!!

I Imagine it works something like this:

https://imgur.com/Xro1YqO

@xkguq007

This comment has been minimized.

Show comment
Hide comment
@xkguq007

xkguq007 Feb 26, 2018

Great works, time saver! ;D

Great works, time saver! ;D

@velopert

This comment has been minimized.

Show comment
Hide comment
@velopert

velopert Mar 6, 2018

Thanks!

It is important to select lambda-subnet-point-to-igw when you create NAT Gateway. When I saw that, I thought it was a typo and I selected one of lambda-subnet-point-to-nat.

;( that was totally a mistake. In order for NAT to access to public internet, you HAVE to select lambda-subnet-point-to-igw.

By the way, you have to create NAT first before you configure lambda-rt-to-nat.

velopert commented Mar 6, 2018

Thanks!

It is important to select lambda-subnet-point-to-igw when you create NAT Gateway. When I saw that, I thought it was a typo and I selected one of lambda-subnet-point-to-nat.

;( that was totally a mistake. In order for NAT to access to public internet, you HAVE to select lambda-subnet-point-to-igw.

By the way, you have to create NAT first before you configure lambda-rt-to-nat.

@murtyjones

This comment has been minimized.

Show comment
Hide comment
@murtyjones

murtyjones Mar 9, 2018

Do these newly created subnets all need to be in the same availability zone (e.g us-east-1a)?

Do these newly created subnets all need to be in the same availability zone (e.g us-east-1a)?

@ybendek

This comment has been minimized.

Show comment
Hide comment
@ybendek

ybendek Mar 22, 2018

You are my hero, it works like a charm. Why is not this into the official documentation??? thank you thank you

ybendek commented Mar 22, 2018

You are my hero, it works like a charm. Why is not this into the official documentation??? thank you thank you

@oscarnevarezleal

This comment has been minimized.

Show comment
Hide comment
@oscarnevarezleal

oscarnevarezleal Mar 23, 2018

So many thanks for this. I couldn´t find any information like this in the official documentation.
And yes, NAT gateway must created first.

So many thanks for this. I couldn´t find any information like this in the official documentation.
And yes, NAT gateway must created first.

@benjaminlong

This comment has been minimized.

Show comment
Hide comment
@benjaminlong

benjaminlong Apr 19, 2018

I wish I'd seen this tuto...

I wish I'd seen this tuto...

@zachstegall

This comment has been minimized.

Show comment
Hide comment
@zachstegall

zachstegall Apr 26, 2018

Spot on, man. I spent hours on this. Thank you.

Spot on, man. I spent hours on this. Thank you.

@apautrot

This comment has been minimized.

Show comment
Hide comment
@apautrot

apautrot Apr 26, 2018

Same here... Iv'e spent hours trying to understand how I could setup all of this.
I couldn't have made it properly without your tuto !
So much thanks to you !

Same here... Iv'e spent hours trying to understand how I could setup all of this.
I couldn't have made it properly without your tuto !
So much thanks to you !

@bgarciaentornos

This comment has been minimized.

Show comment
Hide comment
@bgarciaentornos

bgarciaentornos May 15, 2018

Hi, thanks a lot, this was very useful.

Now I'm having the same problem as caitlinosh, I can't connect to my RDS anymore via MySQL Workbench (it used to work). Any help would be much much appreciated.

Thanks.

Hi, thanks a lot, this was very useful.

Now I'm having the same problem as caitlinosh, I can't connect to my RDS anymore via MySQL Workbench (it used to work). Any help would be much much appreciated.

Thanks.

@ciferkey

This comment has been minimized.

Show comment
Hide comment
@ciferkey

ciferkey Jun 4, 2018

How could these steps be modified to use a ec2 instance running one of amazon's NAT AMIs? I'm looking to use that as a cost saving measure for a small project.

ciferkey commented Jun 4, 2018

How could these steps be modified to use a ec2 instance running one of amazon's NAT AMIs? I'm looking to use that as a cost saving measure for a small project.

@AlexanderCollins

This comment has been minimized.

Show comment
Hide comment
@AlexanderCollins

AlexanderCollins Jun 25, 2018

@caitlinosh @bgarciaentornos Did either of you manage to resolve the issue of connecting to your RDS? I'm having the same issue.

[EDIT]
@caitlinosh @bgarciaentornos I've solved our problem. To allow lambdas to have internet access, RDS access and to allow the RDS to be publicly available (hopefully within a specific ip range - i.e your static IP), your RDS's subnet group must contain only public subnets; that is subnets which have a route table that points 0.0.0.0/0 to an IGW which is attached to your VPC. You must create a subnet group in Amazon RDS > Subnet Groups which contains the public subnets and then launch an RDS instance with this new subnet group (or configure your current system to these specifications).

In my case I have 6 subnets, 3 are private pointing to a nat gateway, the other three public pointing to an IGW as described above. It's important to note that as long as the Lambda function and the RDS instance are in the same VPC, then the Lambda function will have access to the RDS instance.

AlexanderCollins commented Jun 25, 2018

@caitlinosh @bgarciaentornos Did either of you manage to resolve the issue of connecting to your RDS? I'm having the same issue.

[EDIT]
@caitlinosh @bgarciaentornos I've solved our problem. To allow lambdas to have internet access, RDS access and to allow the RDS to be publicly available (hopefully within a specific ip range - i.e your static IP), your RDS's subnet group must contain only public subnets; that is subnets which have a route table that points 0.0.0.0/0 to an IGW which is attached to your VPC. You must create a subnet group in Amazon RDS > Subnet Groups which contains the public subnets and then launch an RDS instance with this new subnet group (or configure your current system to these specifications).

In my case I have 6 subnets, 3 are private pointing to a nat gateway, the other three public pointing to an IGW as described above. It's important to note that as long as the Lambda function and the RDS instance are in the same VPC, then the Lambda function will have access to the RDS instance.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment