Use AWS CloudFront Functions for URI Rewrites
for ('at the edge') sub-millisecond execution time.
With just over one week to move a customer application from one data center into our managed service environment, I was provided with a new (to me) requirement. The requirement was to configure URI redirects for their web application. This didn't seem like a huge concern at the immediate request. I figured I'd just put a couple of listener rules on the Application Load Balancer (ALB) and call it good doing what all DevOps engineers do...
That was before I received the spreadsheet with almost 60 (known) redirects. More potentially to come.
What to do?
I didn't want to make an already complicated solution more complicated.
I knew I had limits to the number of rules allowed in Load Balancer Listeners.
I wasn't interested in adding or modifying any Lambda@Edge functions managing my Content Security Policies.
Fortunately for me, right at the time of receiving this new requirement, AWS Announced CloudFront Functions.
What is/are CloudFront Functions?
...a new serverless edge compute capability. You can use this new CloudFront feature to run JavaScript functions across 225+ CloudFront edge locations in 90 cities across 47 countries.... ( read the full announcement here ).
How could CloudFront Functions help me?
Aside from the rule limits imposed on me by ALB Listeners such as:
- 100 total rules per ALB
- 5 conditions per rule
- 5 wildcards per rule
- 5 weighted target groups per rule
I would have had to use wildcards to make some of the rewrites work. You can use your imagination and the following example to see how this may not produce a favorable outcome.
Use case example
Imagine a website like AllRecipies wanting to redirect certain recipes to new or improved names.
Consider Homemade Mac and Cheese served here: allrecipes.com/recipe/11679/homemade-mac-an..
Let's say for example sake the 11679
in that URI is a catalog of recipes. AllRecipies may want to redirect anything that isn't a successful hit to a different catalog of recipes. So they use a wildcard like:
allrecipes.com/recipe/11679/* to push all requests to allrecipies.com/summer21
What happens is now allrecipes.com/recipe/11679/homemade-MOUSE-.. successfully redirects with a 200
response instead of going to a 404
Page Not Found.
NOTE: oddly enough, AllRecipes is actually doing some magic to forward that URL to the correct recipe.
Using CloudFront Functions for URI Rewrites
Being under the gun to come up with a solution, I immediately took a stab at CloudFront Functions. I'm honestly not sure how I got this to work after the first attempt, so I'm interested in getting anyone's feedback on this implementation.
To accommodate an unknown amount of future requests for rewrites, I tweaked and implemented the example provided in the CloudFront Functions Introduction Blog.
My implementation
function handler(event) {
var request = event.request;
var rewrites = [
['/summer21','/recipies?year=2021&season=summer'],
['/recipies/homemade-mouse-and-cheese/', '/recipies/homemade-mac-and-cheese/'],
['/recipies/camping/grilling', '/recipies?activities=camping&with=grill']
]
for (var arrayIndex in rewrites){
if (request.uri == rewrites[arrayIndex][0]) {
var newUri = rewrites[arrayIndex][1];
var response = {
statusCode: 301,
statusDescription: 'Permanently moved',
headers: {
"location": { "value": newUri }
}
}
return response;
}
}
return request;
}
Making the solution more robust
This CloudFront Function appears to be working as expected. This example allows you to redirect any URI pattern and forward it to a new path or include a search query for client or server-side functionality. All while using JavaScript at the Edge. Without a doubt, this could be modified to further accommodate query strings in the request.
I typically like to deploy my solutions via CloudFormation specifically because this is for a customer; however, at the time of this post and the function implementation, the CloudFormation Team has not released an update to the User Guide for creating this as a managed resource in CloudFormation. I am told it should be released soon. Once I have the information, I will try to get back here and provide a CloudFormation Template in an update.
Until then, if you are looking to try this out or implement CloudFront Functions in your own environment, I encourage you to checkout this blog post by a fellow AWS Community Builder.
Please do not hesitate to comment below how you decide to implement CloudFront Functions, this specific function, or better yet how I can make this specific function even better.