How I Secured AWS Lambda to MongoDB with VPC Peering, NAT Gateway & Default VPC Networking

When building a secure serverless application, I recently ran into a classic AWS networking issue:

I needed my Lambda function to access MongoDB privately (hosted in a different VPC via VPC Peering), and I also needed Lambda to access the internet.

Simple? Not quite.

Here’s how I solved it—step by step, using:

  • 🏗️ AWS Default VPC
  • 🔁 VPC Peering
  • 🛣️ Custom Route Table
  • 🌐 NAT Gateway
  • 🌎 Private internet access for Lambda

🔍 The Problem

After establishing VPC peering between the Lambda’s VPC (default) and MongoDB’s VPC, everything seemed fine:

  • ✅ Lambda could talk to MongoDB.
  • ❌ Lambda lost internet access!

Which broke all third-party API calls.

Turns out, when you attach Lambda to a VPC subnet, it loses internet access unless routed through a NAT Gateway—even if the subnet is in a Default VPC with an Internet Gateway.


🎯 The Goal

  • ✅ Lambda must access MongoDB privately via VPC peering.
  • ✅ Lambda must access the internet via a NAT Gateway.
  • ✅ MongoDB is hosted in a separate VPC.
  • ✅ Use the Default VPC to keep things simple.

⚠️ Important Note on MongoDB Atlas

MongoDB Atlas does not support VPC peering for Serverless, Shared (M0–M5), or Flex clusters.

To use VPC peering, your MongoDB Atlas cluster must be M10 or higher (i.e., a dedicated cluster).

If you’re on a lower tier:

  • ❌ You can’t set up VPC peering.
  • ✅ You must instead use public access (with IP whitelisting and TLS).

⚙️ Step-by-Step Solution

1️⃣ VPC Peering: Connect Lambda VPC to MongoDB VPC

  1. Go to VPC → Peering Connections → Create.
  2. Choose:
    • Requester: Default VPC (Lambda’s VPC).
    • Accepter: MongoDB’s VPC.
  3. Accept the connection in the MongoDB VPC.
  4. Update both VPC route tables to include each other’s CIDR blocks:
    • Lambda VPC: 10.1.0.0/16 → pcx-xxxx
    • MongoDB VPC: 172.31.0.0/16 → pcx-xxxx

2️⃣ Create a Custom Public Subnet in Default VPC

You can’t modify the default subnet’s route table if it already uses 0.0.0.0/0 with an Internet Gateway!

So instead:

  1. Create a new subnet:
    • Name: LambdaPublicSubnet
    • VPC: Default
    • CIDR block: 172.31.100.0/24
    • AZ: (choose any available)
  2. Enable auto-assign public IP.

3️⃣ Create a Custom Route Table (Not Default)

  1. Go to Route Tables → Create.
    • Name: LambdaCustomRT
    • VPC: Default
  2. Add routes:
    • 0.0.0.0/0 → NAT Gateway (you’ll create this next).
    • MongoDB CIDR (e.g., 10.1.0.0/16) → Peering Connection ID
  3. Associate this route table with the LambdaPublicSubnet.

⚠️ This is key:
You cannot add another 0.0.0.0/0 → NAT Gateway to the default route table, because it already has one pointing to an Internet Gateway. So you must use a custom route table for NAT routing.


4️⃣ Create a NAT Gateway

  1. Go to NAT Gateways → Create NAT Gateway.
  2. Attach it to:
    • Subnet: Your LambdaPublicSubnet
    • Elastic IP: Allocate a new one
  3. Wait for the status to become Available.

5️⃣ Attach Lambda to VPC + Subnet

  1. Go to your Lambda function → Configuration → VPC.
  2. Attach:
    • Subnet: LambdaPublicSubnet (or more if needed)
    • Security Group: Allow outbound to MongoDB + Internet (443)
  3. Save the configuration.

Lambda will now:

  • Privately connect to MongoDB via VPC Peering.
  • Access the internet via the NAT Gateway.

🔐 Security Group Rules

  • Lambda SG:
    • Outbound: allow 0.0.0.0/0 on ports 443 (HTTPS), 27017 (Mongo)
  • MongoDB SG:
    • Inbound: allow 27017 from Lambda subnet range (e.g., 172.31.100.0/24)

📊 Final Architecture

[ Lambda ]
  | (Private Subnet)
  |
[ NAT Gateway ]
  |
[ Internet ]

[ Lambda ]
  |
[ VPC Peering ]
  |
[ MongoDB VPC / EC2 ]

✅ Key Lessons Learned

  • 🧭 You can’t route 0.0.0.0/0 to both IGW and NATGW in the same route table.
  • 🔧 So you need a custom route table + custom subnet.
  • 🛣️ Default VPC’s route table points to Internet Gateway, so it’s not usable for NAT.
  • 📡 NAT Gateway must be placed in a public subnet (associated with a custom route table).
  • 🔐 Lambda in a VPC doesn’t get public IPs, so NAT is required for outbound internet.
  • 🧩 MongoDB Atlas VPC peering only works with M10 or higher (dedicated tiers).

🧪 Debugging Tip

If Lambda still can’t access the internet:

  • Make sure it’s attached to the custom subnet
  • Ensure the route table is correctly associated with the subnet
  • Confirm the NAT Gateway is Available and using a valid EIP

🙌 That’s It!

This pattern is useful not just for MongoDB but for any private resource in a peered VPC—while keeping Lambda’s public internet access functional and secure.

Leave a Reply

Your email address will not be published. Required fields are marked *