I’m writing this post not because I’m an expert in CDN configuration but because I found the process of setting up URL redirects using Azure CDN (Verizon Premium) incredibly frustrating due to poor/lack of documentation and examples.
In my scenario I had an Amazon Web Services S3 (file storage) that contained installation files for different releases of a product. I wanted to migrate these files across to Microsoft Azure Blob Storage. Due to a limitation in the naming of Blob Containers in Azure (they can’t contain a period ‘.’) I wasn’t going to be able to keep the file paths identical and just point the old custom domain at the new Azure Blob Storage. Instead I introduced a top level folder (container) in Azure called “desktop-releases” and then copied the contents from the root level of my AWS S3 into the “desktop-releases” container.
Once I changed my custom domain to point at Azure rather than AWS I would then just need a way to handle redirecting requests for those root level folders to look inside the desktop-releases folder instead. I also want to be able to create other top level folders in Azure (at the same level as desktop-releases), so I needed to be able to only redirect if it was one of those numbered release folders or the “redist” folder.
Azure Blob Storage itself doesn’t contain a mechanism for being able to handle URL redirection, but I was going to put a CDN in-front of the Azure storage for better performance in global delivery of the files and found that Azure CDN does have the ability to do redirection. When you create an Azure CDN you can choose from multiple types of Azure CDN providers/products:
- Azure CDN Standard from Microsoft <= Has a rules engine capable of URL redirection
- Azure CDN Standard from Akamai
- Azure CDN Standard from Verizon
- Azure CDN Premium from Verizon <= Has a rules engine capable of URL redirection
As indicated above only the Microsoft and Verizon Premium CDN offerings are able to do URL redirection. I started with the Microsoft CDN but found that it didn’t have support for regex pattern matching of the incoming URL path which I would need to detect all those release folders (without having to put lots of rules in place for the exact folder names – and those images above are abbreviated, there’s a lot more version folders!). So I moved to the Verizon Premium CDN offering.
The documentation for the Verizon Premium Rules Engine is really lacking in examples of how to setup redirects.
Firstly, there’s two menu option to open the rules engine, HTTP Large and ADN. These are completely different things and if you configure the wrong one it won’t do anything. When serving static files from Azure Blob Storage it’s the HTTP Large Rules Engine that you will need to configure.
The URL Redirect Feature
This is what we will use in all the example rules to achieve the redirects but there’s some things you should know about it up front.
This is a regex statement that identifies which requests will be redirected. Weirdly it must start with some identifier that Verizon CDN is using internally. This bit I don’t fully understand, but here’s where you get it from.
Create a new rule and in the IF condition select Origin | Customer Origin and drop down the Value selector.
When defining the source use this value (/80108648/verizoncdncam/) to represent the host and then everything after that is your relative path.
This specifies where users will be redirected to if the source regex is matched.
Let’s dive into creating some rules and I’ll explain more about what we can specify in the Source and Destination to achieve some common redirect scenarios.
Redirect a specific file from one complete path to another
This will just redirect the URL https://verizoncdncam.azureedge.net/1.0/widget-setup.exe to https://verizoncdncam.azureedge.net/desktop-releases/1.0/widget-setup.exe
Redirect all files beneath a path to a different path
This will redirect all files (and subfolders) beneath the https://verizoncdncam.azureedge.net/1.0 path to https://verizoncdncam.azureedge.net/desktop-releases/1.0.
The magic here is that the Source is actually a regex statement, the brackets () are used to capture matching values and .* in regex means match any character any number of times. So this will capture anything that comes after https://verizoncdncam.azureedge.net/1.0. When I say capture, it gets stored in a variable $1 that you can then use in the Destination.
Redirect paths based on regex patterns
Regex is super powerful and we can use it to redirect all paths starting with the number 1 rather than having to write individual rules for each folder (e.g 1.0, 1.1, 1.2)
Extending that regex a bit more we can handle all of the release folders by matching any path starting with the numbers 1 to 3 and redirecting to within the desktop-releases path.
Finally here’s the regex that will redirect all the release folders and the redist folder from the root path to the desktop-releases path in a single rule.
Multiple redirect rules
You can create multiple redirect rules under the same IF condition. Here I’m also redirecting a request from /latest-release to /desktop-releases/3.0/widget-setup.exe
Redirect all HTTP traffic to HTTPS
I had existing links to the files in AWS that use the HTTP scheme so I wanted to redirect those to use HTTPS instead. This can be implemented as a new rule, and I put it as the first rule because I want it applied to all traffic before other rules are evaluated. This time we use the Request | Request Scheme IF condition to just match traffic that uses HTTP and then use a URL Redirect rule to match any path, and then in the Destination we specify to use HTTPS. Notice I’ve used another variable %(host) which is provided by the Rules Engine instead of hardcoding the incoming host name (verizoncdncam.azureedge.net).
Mistakes I Made (Don’t do this)
I assumed that since I wanted to identify a certain pattern in the URL to redirect (e.g. those starting with 7. or 8.) that I should use an IF clause and match on the URL Path. Then when I find a match I’d implement a feature to do a simple URL redirect of the whole path. This didn’t work as I’d expect, especially when I multiple rules configured.
What struck me as odd here is that I found it didn’t work unless I also had a regex statement in the Source of the URL Redirect which was effectively the same as the IF statement (and I had all manner of problems if they didn’t exactly match). It turns out you just don’t need the IF statement. The URL redirect only gets triggered if the regex in the source finds a match, this is why I’ve used the IF condition General | Always in the correct examples in this article.
In retrospect I feel like trying to do both the IF statement and the URL Redirect was actually causing more overhead because every URL was being evaluated against the IF statement and then if a match was found, the URL Redirect was evaluating against the Source to look for a match again.