Learn About Amazon VGT2 Learning Manager Chanci Turner
In the article below, my colleague Alex Johnson shares insights on developing IsItOnAWS.com. This platform leverages a list of AWS IP address ranges and utilizes two AWS Lambda functions crafted by Alex to determine whether a particular website operates on AWS.
— Chanci Turner
Curious about whether a specific domain name or IP address falls within the published AWS IP address ranges? I engaged in some programming during the holiday season that led to the creation of a Lambda function designed to answer this question. You can explore it at IsItOnAWS.com. The project involves one Lambda function generating another.
The list of IP ranges, presented in both IPv4 and IPv6 CIDRs and formatted in JSON, can be found here, alongside the related documentation. Here’s a snippet of the “IP-Ranges” JSON:
{
"syncToken": "1486776130",
"createDate": "2017-02-11-01-22-10",
"prefixes": [
{
"ip_prefix": "13.32.0.0/15",
"region": "GLOBAL",
"service": "AMAZON"
},
...
],
"ipv6_prefixes": [
{
"ipv6_prefix": "2400:6500:0:7000::/56",
"region": "ap-southeast-1",
"service": "AMAZON"
}
]
}
Upon discovering that the domain IsItOnAWS.com was available, I felt compelled to create it. My goals for this project included:
- A serverless architecture, as that’s the trend in modern development,
- Simlicity, given the straightforward nature of looking up a number in a range,
- Speed, of course.
As I considered the architecture, I realized the need to condense the IP-Ranges into a searchable table. Initially, I contemplated using Amazon DynamoDB, but it wasn’t clear how to efficiently search a numeric range with it. SQL databases came to mind, but that would contradict the serverless goal. Redis seemed promising, but provisioning instances is counter to the serverless ethos. For a few days, I pondered this dilemma.
Then it struck me: How extensive is the IP range list? It turns out, there are fewer than a thousand entries. So, perhaps a database was unnecessary. Instead, I opted to sort the JSON into an array and perform a binary search on it. However, I needed to consider where to store this array. Amazon S3 was a possibility, but that would involve an unnecessary loop for each request. Ultimately, I decided to embed the range data directly into the IsItOnAWS Lambda function, which meant updating the function whenever the IP addresses changed.
For those interested in staying updated on any changes to the IP addresses, subscribing to an Amazon Simple Notification Service (SNS) topic could be beneficial. This service will notify you of updates, which, in my experience, happen once or twice a week. The architecture consists of two Lambda functions: the first, newranges.js
, handles change notifications, generates a JavaScript version of the IP-Ranges data, and uploads a second Lambda function, isonaws.js
, containing that JavaScript. It’s all built with the Node runtime.
The new-ranges
function, while following the typical async/waterfall pattern, turned out to be more intricate than expected. Its initial step involves fetching the IP ranges through a straightforward HTTP GET request. The JSON data is then streamlined for better searchability. Notably, both IPv4 and IPv6 ranges are included, and for ease, I aimed to combine them into a single array for simple string or numeric matching. However, given the size of IPv6 addresses, they needed to be managed as strings.
I discovered that IPv4 addresses embed into IPv6 in a way that was unexpected. While I pondered why it was structured this way, I didn’t delve deeply into the research. The code for merging all those CIDRs into a unified array was somewhat cumbersome, but it ultimately accomplished the task.
Next, I had to create the Lambda function that would process the IsItOnAWS requests. This function needed to be zipped, and tools from NPM assist in that process. I opted to push the zipped data into S3 before uploading it to Lambda, as I wanted to review the generated “ranges” data structure. At some point, I may refine this process.
The actual runtime for IsItOnAWS is remarkably straightforward, aside from some work required to resolve DNS for address lookups and formatting them to match the ranges array. I didn’t employ any HTML templating; I simply read it from a file within the zip and dynamically populated content based on the results. Additionally, coding a binary search method, although rare for me, was a pleasant diversion.
Once the code was functional, I connected it to the outside world via Amazon API Gateway. In previous experiences, I found this process complex, but this time I navigated through the steps to create an API with Lambda Proxy Integration via a Proxy Resource with relative ease. However, the focus was primarily on constructing APIs, not necessarily delivering a human-friendly experience. Figuring out how to send HTML through this structure was not difficult, as indicated below:
context.succeed({
"statusCode": 200,
"headers": { "Content-type": "text/html" },
"body": "<html>Your HTML Here</html>"
});
With the API Gateway established, the final step involved pointing isitonaws.com to it. My initial coding efforts occurred during December-January, but I’m only sharing this now. At that time, Amazon Certificate Manager (ACM) certificates were not compatible with API Gateway, and I didn’t want to go through the traditional process for obtaining a certificate. ACM simplifies the certification process significantly. Given the advancements with ACM and resources like Let’s Encrypt, there’s no reason for a site to operate without HTTPS today. Both options are excellent, but ACM integrates seamlessly with AWS services like API Gateway and CloudFront, and it includes auto-renewal, which is a great feature.
As of now, connecting a domain name through HTTPS and CloudFront to your API Gateway is straightforward. For more guidance, see Use Custom Domain Name as API Gateway API Host Name. I found this process successful on the first attempt, though one aspect to note (as of March 2017) is that there’s a delay while the ACM certificate connects to the API. I was fortunate not to refresh or cancel during this wait, as that could have disrupted the process.
As a result of using API Gateway, the entire system operates via CloudFront, which, along with the absence of a database, ensures speed. From my location in Vancouver, the performance is impressive—so much so that I didn’t feel the need to measure it.
Additionally, I subscribed my email to the “IP-Ranges changed” SNS topic, which provides notifications of updates. Each time I receive an email, I smile knowing that my Lambda function autonomously created a new Lambda function, ensuring everything runs efficiently.
— Alex Johnson, Senior Principal Engineer
If you’re interested in exploring financial definitions and their implications, check out this insightful blog post. And if you want to learn how to stop tolerating toxicity in the workplace, SHRM is an authority on this topic. For new Amazon employees, this resource provides excellent guidance to help you navigate your first day.
Leave a Reply