Serverless is great. There, I said it.
At this point I'm not sure many people would argue with me on that, but to each their own.
Serverless provides us with the luxury of fast compute in the cloud without having to worry about machines or state. Pretty awesome.
But since we don't have to worry about machines or state, a handful of problems present themselves that we didn't have before.
Things like monitoring your app become more difficult. You also have all the difficulties of distributed computing thrown into the mix.
But what about a static IP? There are a multitude of reasons you would need a static IP address, like integrating with a 3rd party or connecting to an internal network. These tasks typically need to whitelist IP address for security measures.
It's hard to argue against security, so we must come up with a way to get Lambda functions to send external traffic from a known IP address.
Full disclosure - this has been a solved problem for a while. When I was doing my initial research on how to get Lambda to use a static IP, I used this tutorial and this one to work my way through the console and set it up.
But I am a boy scout. I like to leave things better than how I found them.
I've taken the tutorials, comments, and trial and error, and created a SAM template that will automatically deploy everything you need into the cloud with minimal setup.
All you need are:
- AWS CLI configured on your machine
- SAM CLI
- An S3 Bucket in your account to deploy resources into
- A CIDR block for the network you're about to create
If you're unfamiliar with CIDR, networking, subnets, and IP configuration like I am, don't worry. These are the values I used in test.
You will probably want to change these for production usage, but these values should get you by for a POC.
Networking is hard. I often say don't confuse complexity with unfamiliarity. But my college degree is "Bachelor of Science in Software Engineering with Focus in Networking" and I still think it's hard. I'm familiar with it, yet it remains complex.
That's why we chose serverless, right? Because we want to focus on solving business problems instead of dealing with networking.
For those curious (which I expect everyone reading this is, that's just the nature of engineers), here is the architecture we're setting up with this SAM template.
At a high level, we've configured a few moving parts that communicate with each other to route traffic through a static IP:
- API Gateway to accept incoming requests
- VPC containing a private subnet and a public subnet
- Lambda function in the private subnet
- Internet gateway giving internet access to the public subnet
- NAT Gateway with a configured static IP to route external traffic
- Route tables to send traffic through the gateways
When you deploy the stack in your AWS account, CloudFormation will provide you with two outputs: an IP address and a url.
The IP address is your assigned elastic IP. This is the address you can give to your integrators to whitelist. It is not going to change. All outbound web traffic from your lambda functions in the private subnet will be coming from that IP.
The url is a test endpoint. It is an API that hits ipify to get the IP address of the Lambda and compares that address to your static IP. The response will give you the expected IP, actual IP, and tell you if they match.
That's it! Configure a couple of minor parameters, deploy, and enjoy!
From here you can either modify the test endpoint or create a new one to satisfy your needs.
I hope this gets you past your problem as fast as possible and opens the door to solving business problems. Again, that's why we chose serverless: to spend as much time as we can on helping our customers, not configuring and maintaining infrastructure.