37
votes

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.
6
Here's a good tutorial I wrote: "How to setup AWS lambda function to talk to the internet and VPC" gist.github.com/reggi/dc5f2620b7b4f515e68e46255ac042a7ThomasReggi
Just checked about NAT gateway pricing and is it correct it currently costs $0.045 per hour?August
I explain what is tripping most of us up in this answer: stackoverflow.com/a/63369754/2255753Daniel Nalbach

6 Answers

30
votes

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

41
votes

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.

9
votes

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?

2
votes

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
1
votes

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.