40

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.
Boann
  • 48,794
  • 16
  • 117
  • 146
Mandeep Singh
  • 7,674
  • 19
  • 62
  • 104
  • 4
    Here's a good tutorial I wrote: "How to setup AWS lambda function to talk to the internet and VPC" https://gist.github.com/reggi/dc5f2620b7b4f515e68e46255ac042a7 – ThomasReggi Jun 14 '16 at 23:19
  • Just checked about NAT gateway pricing and is it correct it currently costs $0.045 per hour? – A.W. Oct 24 '19 at 06:56
  • 1
    I explain what is tripping most of us up in this answer: https://stackoverflow.com/a/63369754/2255753 – Daniel Nalbach Aug 12 '20 at 04:35

6 Answers6

47

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.

Vincent de Lagabbe
  • 4,964
  • 3
  • 31
  • 38
  • 6
    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. – Vincent de Lagabbe Aug 22 '16 at 16:09
  • 2
    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) – RichVel Feb 22 '18 at 15:38
  • The tutorial isn't perfect and leaves some details out, but is still a good starting point for beginners. – Vadorequest Mar 03 '19 at 21:18
  • 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: https://edgarroman.github.io/zappa-django-guide/aws_network_primer/ – Vadorequest Mar 03 '19 at 22:14
  • 1
    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 – Kevin Danikowski Aug 21 '20 at 16:32
  • I finally found an answer that a very beginner in network could understand, setup and make it work! Thanks! – julison Apr 19 '21 at 11:13
  • Thank you. Wish AWS had a visual designer for all this networking stuff. click and drag. Thanks a million – Stephane Jun 09 '22 at 01:42
37

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

Mircea
  • 10,216
  • 2
  • 30
  • 46
  • 8
    And I need to select the private subnet in the Lambda function's configuration – Mandeep Singh Feb 19 '16 at 18:50
  • Thank you!! It helped me a lot. – Hime Jan 03 '17 at 22:59
  • 1
    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. – user7817808 May 09 '18 at 17:37
  • 1
    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) – Mircea Aug 11 '18 at 02:22
  • @Mircea you saved me. how many years of AWS / Networking experience do you have? – nxmohamad Jun 11 '19 at 05:05
  • 1
    @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 :) – Mircea Jun 12 '19 at 23:15
  • @Mircea respect! do you have a twitter I can follow? – nxmohamad Jun 13 '19 at 08:03
10

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?

Community
  • 1
  • 1
Michael - sqlbot
  • 169,571
  • 25
  • 353
  • 427
  • 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. – Mircea Feb 17 '16 at 18:28
  • I will edit to address the igw inclusion/exclusion as the defining attribute more clearly, and add authoritative citations. – Michael - sqlbot Feb 17 '16 at 20:24
  • 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 – Mandeep Singh Feb 18 '16 at 05:19
  • 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). – Michael - sqlbot Feb 18 '16 at 06:51
  • @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. – Carl Oct 26 '16 at 09:10
  • @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. – Michael - sqlbot Oct 26 '16 at 10:19
  • @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. – Carl Nov 02 '16 at 13:13
2

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
shontauro
  • 1,812
  • 1
  • 25
  • 26
1

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.

Sinai R.
  • 33
  • 10
  • > choose your VPC, add SG that's you're working with. Do you add the groups that are associated to the NAT, to the lambda or the SGs that are associated to the internet gateway? or both? – JZ. Nov 26 '22 at 00:35
-2

You actually don't need to create Internet and NAT gateways anymore:https://aws.amazon.com/blogs/security/how-to-connect-to-aws-secrets-manager-service-within-a-virtual-private-cloud/

Sébastien Tromp
  • 603
  • 1
  • 15
  • 30
  • 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. – Thales Minussi Feb 21 '19 at 19:15