How to use Static IPs with AWS Lambda

Jun 9, 2023 (updated Jun 9, 2023)·3 minute read

At Cronitor, many customers have asked us for the range of IP addresses from which our uptime checks originate, so they can allow them to bypass their firewall or CDN bot protection rules.

This is because sometimes their infrastructure considers these requests as crawlers or bots and decides to reject the request (sending a false alarm to our customers).

So it's common practice for service providers to offer a list of static IPs from which the uptime requests will originate from, and customers can add an IP access rule on their side.

The challenge

If you're running your own servers, normally finding the list of public IPs isn't too difficult.

However, we're running our uptime checks on AWS Lambda across 11 regions. The default behavior for a Lambda function is to receive random IP addresses from Amazon's pool of servers and these IP addresses change over time.

This makes it impractical for our customers as they'd need to constantly update their firewall rules and change our IPs.

What we need is a way for all our Lambdas to use a predictable set of public IPs.

The solution: Lambda in VPC + NAT

To address this shortcoming, we deployed our Lambdas within a private subnet in our network and use a NAT Gateway to "bridge" outbound requests from the private network to the public internet.

What’s nice is you can attach an Elastic IP to the NAT, that way the NAT is what routes all outbound requests to the public internet, so every request will originate from its IP.

That way even if there’s multiple Lambdas running in parallel, all outbound requests will go through the NAT and appear as if they originate from a single, predictable IP on the public internet.

Cost concerns

While this solution does solve having a single static IP per region, it can get expensive pretty quickly if you process a lot of bandwidth via the NAT, as both ingress and egress traffic is billed.

Luckily, there is a path forward to continue investing in this solution and keep our costs under control: We could self-host our own NAT instance on EC2.

That does come with the tradeoff of having more infrastructure to maintain and keep secure, but it's an effective way to reduce the bandwidth charges.

Future work

Right now, as a small team of 3, we'd like to avoid adding new moving parts as much as possible so we opted for the simple solution, let AWS manage the NAT for us, knowing there's a way forward in case we'd need to reduce our infrastructure costs in the future.

As the main concern with this approach is cost, we created an alarm in CloudWatch to be notified when one of the NAT Gateways is processing a lot of traffic.

So for now, this solution works for us, and we can finally offer a list of static IPs to our customers.

I hope this helps anyone who is looking to solve this use case too.

Follow me for the latest content