Picture this: a team ships a Lambda function that calls a couple of third-party APIs. Works perfectly in every test. Then the product needs the function to also read from an RDS database sitting in a private VPC, so someone attaches the function to that VPC and redeploys.
Suddenly the same function that was calling those APIs all week starts timing out on every outbound call. Nothing in the code changed. The database connection works fine. It's just the internet calls that stopped. That's usually the point where someone spends half a day checking IAM permissions and security groups before realizing the actual cause has nothing to do with either one.
If you've worked with Lambda for a while, you've probably run into this confusing moment yourself: your function calls an external API just fine, no setup needed. Then one day you attach it to a VPC so it can talk to your RDS database, and suddenly it can't reach the internet anymore. No API calls. No S3. Nothing.
This trips up a lot of people, because it feels backwards. You added more network access, and somehow you lost access. Here's why that happens, and what you can do about it.
The Short Answer
By default, Lambda already has internet access. You don't set up a VPC, a NAT gateway, or an internet gateway. It just works.
That's because Lambda doesn't run inside your AWS account's network at all. It runs inside a VPC that AWS manages for you, behind the scenes. That AWS-managed VPC already has internet access built in. You never see it, and you never touch it.
What Changes When You Attach Your Own VPC
Most people attach a Lambda function to their own VPC for one reason: to reach something private. Usually that's an RDS database, an ElastiCache cluster, or an internal service that only exists inside your VPC and has no public endpoint.
The moment you do that, Lambda creates network interfaces (ENIs) inside the subnets you picked. Those ENIs only get a private IP address. No public IP. And that one detail is the root of the whole problem.
Without a public IP, your function has no way to reach the internet through a normal internet gateway. It's stuck talking only to things inside your VPC, unless you give it a path out.
Why Putting it in a "public" Subnet Doesn't Fix it
A common mistake is dropping the Lambda function into a public subnet, thinking that solves it. It doesn't.
A public subnet only helps resources that have a public IP address. Lambda's ENI never gets one, no matter which subnet you place it in. So the internet gateway sitting there is useless to it. This is the single most common Lambda networking mistake, and it wastes a lot of debugging time before people realize the subnet type was never the issue. It's exactly what the team from the intro tried first, and exactly why it didn't help.
The Real Fix: Private Subnet Plus NAT Gateway
The actual fix is to put your Lambda function in a private subnet, and route its outbound traffic through a NAT gateway that sits in a public subnet. The NAT gateway has a public IP. Your Lambda function doesn't need one, because it's borrowing the NAT gateway's connection to reach the internet.
This works, but it isn't free. A NAT gateway charges you by the hour, plus a per-GB fee for every bit of data that flows through it. For a low-traffic function this is a few dollars a month. For something with heavy or spiky traffic, it can turn into a real ongoing cost, and this is why teams often ask "do we actually need this?"
A Cheaper Option: VPC Endpoints
Here's the part a lot of tutorials skip. If your Lambda function only needs to reach other AWS services (S3, DynamoDB, SQS, Secrets Manager, and so on), you don't need a NAT gateway at all. You can use a VPC endpoint instead.
There are two kinds:
- Gateway endpoints: free, and only available for S3 and DynamoDB.
- Interface endpoints: small hourly cost, but far cheaper than a NAT gateway, and available for most other AWS services.
With the right VPC endpoints in place, your Lambda function can talk to AWS services without ever leaving the AWS network, and without needing general internet access at all.
This matters because a lot of people reach for a NAT gateway when a VPC endpoint would have done the job for less money and less setup.
A Simple Way to Decide
Ask yourself one question first: does this function actually need to reach something inside a VPC?
No -don't attach a VPC to it at all. Leave it in the default, AWS-managed network. It already has internet access, and you avoid the whole NAT/endpoint decision entirely.
Yes****
- figure out what it's actually calling once it's inside the VPC
- Only AWS services like S3 or DynamoDB? Use VPC endpoints.
- Third-party APIs, or AWS services without an endpoint option? You'll need a NAT gateway.
- A mix of both? Use VPC endpoints for the AWS traffic, and a NAT gateway for everything else.
Default vs. VPC-attached, side by side
Conclusion
Lambda has internet access out of the box because it runs in a VPC that AWS controls, not one you can see. The moment you attach it to your own VPC, usually to reach a private database, it loses that internet access, because its network interface only gets a private IP. Putting it in a public subnet doesn't help. The real options are a NAT gateway for general internet access, or a VPC endpoint if you're only talking to AWS services. Skip the VPC entirely if you don't actually need to reach something inside one.


