AWS Lambda: How to set up a NAT gateway for a lambda function with VPC access

23,451

Solution 1

You need both the IGW and the NAT gateway for this to work.

In the public subnets (ones you want to reach from outside) point the 0.0.0.0/0 traffic to the IGW gateway. The NAT gateway itself needs to sit in one of these public subnets.

In the private subnets that you want to NAT point 0.0.0.0/0 traffic to the NAT gateway elastic network interface.

If 0.0.0.0/0 is aleady bound to the gateway you need to remove that and add it pointing the NAT gateway.

See: http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/vpc-nat-gateway.html

Solution 2

I found a good detailed tutorial on how to allow your lambda to connect to both VPC ressources and the internet here: https://gist.github.com/reggi/dc5f2620b7b4f515e68e46255ac042a7

A quick walk-through:

  • setup new subnets for your lambda (with CIDRs not overlapping your existing subnets). You need:
    • one subnet which will be pointing to an Internet Gateway (IGW) to be used by the NAT (let's call it A)
    • several pointing to the NAT to be used by your lambda (B, C and D)
  • add a NAT gateway: set the subnet to A
  • set your lambda VPC subnets to B, C and D
  • create 2 routes table:
    • one that points to your NAT with destination 0.0.0.0/0
    • one that points to your IGW (should already exists) with destination 0.0.0.0/0
  • update the subnet A to use the route table pointing to the IGW
  • update the subnets B, C and D to use the route table pointing to the NAT

Hope this helps.

Solution 3

You need two different subnets. It sounds as if you only have one.

Lambda can only use private subnets inside VPC.

Definition of a private subnet: the default route is a NAT instance (which most be on a different, public subnet) or a NAT Gateway, and no machines in the subnet have a public IP address. Machines with public IP addresses are allowed on a private subnet, but for the most part, they will not work properly, because this is technically a misconfiguration.

Definition of a public subnet: the default route is the igw-xxxxxxxx Internet Gateway object, and machines have public IP addresses assigned. Machines without public IP addresses are allowed on a public subnet, but they will not be able to access the Internet, because this is a misconfiguration.

It sounds like you are trying to change your existing subnet from public to private by changing the default route. As expected, this breaks other things.

See also Why do we need private subnet in VPC?

Solution 4

Hey guys I developed a step by step tutorial with explicit screenshots about it:

Part I

  1. Create a lambda function in AWS
  2. Create an API Gateway to redirect all the requests to your AWS Lambda Function https://medium.com/@shontauro/how-can-i-turn-my-restful-api-into-a-serverless-application-and-deploy-it-to-aws-lambda-step-by-ec7ce38e18be

Part II

  1. Configure a VPC for your lambda function
  2. Grant internet access to the lambda function in a safety way
  3. Deploy the Node.js Restful API into your Lambda Function https://medium.com/@shontauro/how-can-i-turn-my-restful-api-into-a-serverless-application-and-deploy-it-to-aws-lambda-step-by-8ff6cc97780f

Solution 5

For using your Lambda inside of your VPC and internet access:

I believe, most of you already have IGW ,that you're working with inside of your VPC and working with internet,so no need create a new one.

Steps worked for me:

  1. Create a new subnets (recommended 2 or more) under your main VPC. Give it new CIDR with a mask ,you think it'll be count of network interfaces use in your Lambda.(I did X.X.X.X/28 , because for us it's enough)

  2. Create NAT Gateway , add to it Elastic IP or create new EIP and add it to your main Subnet under your VPC. (remember it'll work if you already have Internet Gateway)

  3. Create Route table and add 0.0.0.0/0 route to Target - Nat Gateway ID (nat-xxxxxxxxxxxxxxxxx)that we've created (step 2)

  4. Create new Security Groups (ALL to ALL) for your lambda to work with internet. I believe it's secure to add 0.0.0.0/0 to lambda for internet.

  5. Open lambda - choose your VPC, add SG that's you're working with and add new created from the step 4 to work with internet. press Save and Test.

Share:
23,451
Mandeep Singh
Author by

Mandeep Singh

I am a full stack developer with a never ending desire to learn new things by building stuff. Over the last 10+ years of working as a software developer, I have developed expertise in Node, Express, Vue, Nuxt, React, Elasticsearch, Postgres, Docker and AWS technologies. I have worked on various products with small to medium sized teams and also as solo developer. I am passionate about my work and strive to build easy to scale and easy to maintain solutions, with a lot of emphasis on maintainability. I am quite efficient at rapid prototyping, building Minimum Viable Products (MVPs) quickly and then scaling them to full fledged production applications. Other than learning new things, I also enjoy sharing my learning with my peers and the developer community in general. This not only helps the people around me to grow together, but has also helped me in improving my own communication skills and become a better mentor and a better developer.

Updated on October 08, 2020

Comments

  • Mandeep Singh
    Mandeep Singh over 3 years

    As per this document, if I need to access internet resources from my Lambda function with VPC access, I need to set up a NAT gateway.

    So I followed this guide to set up a NAT gateway. However, at the stage when I need to edit the route tables of my subnet to add an entry with destination: 0.0.0.0/0 and target as my NAT gateway's id, I got an error that

    An entry with this destination already exists
    

    I checked and noticed that for that existing entry, the target was an internet gateway for my VPC. If I replace that entry with the NAT gateway id, I cannot access any of the EC2 instances in that VPC through SSH from the outside world. How can I achieve a solution where all the EC2 instances in this VPC:

    • Are accessible only via SSH and the rest of the traffic is blocked
    • Are able to completely access other EC2 instances in the same VPC
    • Lambda function having access to this VPC can access outside resources like SQS and Kinesis.
  • Mircea
    Mircea about 8 years
    a private subnet does not have to have a nat instance or gateway as a default route. you can have machines without a public IP in a public subnet. The only real difference between the private and the public subnets is the route to the igw.
  • Michael - sqlbot
    Michael - sqlbot about 8 years
    I will edit to address the igw inclusion/exclusion as the defining attribute more clearly, and add authoritative citations.
  • Mandeep Singh
    Mandeep Singh about 8 years
    There are a lot of EC2 instances on this account and there are 4 subnets. I want to make sure that I do not mess up anything while making the change. Should I add a new subnet. I am not sure how should I configure my Lambda to work with this strategy
  • Michael - sqlbot
    Michael - sqlbot about 8 years
    If you already have a subnet where the default route points to a NAT instance or NAT Gateway, you should be able to use that subnet with Lambda. If not, you will need to create a new subnet, if you want to be certain nothing will break, and then arrange for NAT for machines (including Lambda interfaces) in that subnet (NAT Gateway is easiest and typically has best performance; NAT Instance is a little more involved but documented, lower performance (though you may not notice, depending on traffic), and cheaper).
  • Mandeep Singh
    Mandeep Singh about 8 years
    And I need to select the private subnet in the Lambda function's configuration
  • Vincent de Lagabbe
    Vincent de Lagabbe over 7 years
    I added a detailed walk-through. Not as detailed as the linked tuto, but this is exactly what I did and it seems to answer the original question.
  • Carl
    Carl over 7 years
    @Michael-sqlbot I would like to question your second statement. Lambda can run in public subnets. However, since the ENIs created for Lambda does not respect the subnet "auto-assign public IP" setting it does not get a public IP and cannot access outside resources so given OPs question it doesn't help. That said, I have deployed Lambdas in public subnets that can access ElastiCache clusters in the same public subnets.
  • Michael - sqlbot
    Michael - sqlbot over 7 years
    @polythene, technically, yes, you can misuse a public subnet by assigning interfaces with only private addresses as long as you don't need anything from the Internet (except DNS, which will still work). In VPC, unlike the common model for Ethernet LANs, there's no advantage to putting two things on the same subnet simply because they talk to each other. The entire network in VPC is virtualized, software defined, so for traffic to cross subnets within the same availability zone has no performance implications.
  • Carl
    Carl over 7 years
    @Michael-sqlbot You are absolutely correct but that is beside the point. My point was only that the statement is untrue, nothing else. I for one advocate not using private subnets unless you really need them and depending on your use case I just wanted to clarify that even when you deploy Lambdas in VPC you might not necessarily need a private subnet. That said, I wouldn't say that you are misusing a public subnet by creating ENIs without public IPs in them. I call that a perfectly valid pattern as long as it makes sense for your use case.
  • Hime
    Hime over 7 years
    Thank you!! It helped me a lot.
  • RichVel
    RichVel about 6 years
    The linked article is quite useful but has some errors - for example it uses 'AWS services' to mean 'services only in your VPC', but in fact many AWS services are on the public Internet (such as default S3 setup)
  • user7817808
    user7817808 almost 6 years
    With a NAT Gateway running ~$30/mo in the least expensive regions (and no NAT GW provided by the Free Tier), this kind of sucks from a hobbyist perspective.
  • Mircea
    Mircea over 5 years
    yes and no. if you use the built-in one you're right, it sucks for a hobbyist. in that case you can try to leverage an EC2 instance that you can build to act as a NAT instance (what people did before the managed version was out there)
  • Thales Minussi
    Thales Minussi about 5 years
    This is only for AWS Secret Manager. If your Lambda still needs to access ElasticSearch, RDS or other services that sit on top of a VPC, you still need to configure it.
  • Vadorequest
    Vadorequest about 5 years
    The tutorial isn't perfect and leaves some details out, but is still a good starting point for beginners.
  • Vadorequest
    Vadorequest about 5 years
    Additionally, for those who want to understand the VPC thing and how it relates to RDS/Lambda, here comes a very well written explanation, for beginners: edgarroman.github.io/zappa-django-guide/aws_network_primer
  • nxmohamad
    nxmohamad almost 5 years
    @Mircea you saved me. how many years of AWS / Networking experience do you have?
  • Mircea
    Mircea almost 5 years
    @nxmohamad thanks for the kind words. I've worked with AWS since the early days but if it matters I've learned most of these things the hard way :)
  • nxmohamad
    nxmohamad almost 5 years
    @Mircea respect! do you have a twitter I can follow?
  • Kevin Danikowski
    Kevin Danikowski over 3 years
    if I could give you 100 votes I would, OMG was so tough to get this answer, still confused what the heck is going on lol
  • julison
    julison about 3 years
    I finally found an answer that a very beginner in network could understand, setup and make it work! Thanks!
  • Stephane
    Stephane almost 2 years
    Thank you. Wish AWS had a visual designer for all this networking stuff. click and drag. Thanks a million