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:
https://www.allrecipes.com/recipe/11679/homemade-mac-and-cheese/
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:
https://www.allrecipes.com/recipe/11679/* to push all requests to https://www.allrecipies.com/summer21/
What happens is now https://www.allrecipes.com/recipe/11679/homemade-MOUSE-and-cheese/ 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.