A Content Delivery Network (CDN) is a sure-fire way to improve the performance of content accessed globally. For a while now I’ve contemplated using one; both to improve the performance of this site, and as an opportunity to experiment with Azure CDN. On the back of a Twitter conversation with a colleague Dale / @blackforce, I decided today was the day I’d take a look at configuring Azure CDN 🙂
The back-story to this is a minor tale of woe. When I set up this site, I did so (being a “Microsoft guy”) using Azure Ap Service. Simple, reliable, and nicely scalable as things grow. In doing so I also used Let’s Encrypt to provide the site’s SSL certificate. The obvious advantage of Let’s Encrypt is the fact that they allow you to generate certificates for free… The caveat is a short life-time of 90 days. This would be a pain if they didn’t provide mechanisms for automating the request / renewal of site certificates. Fortunately they do, and in the case of Azure App Service this takes the form of an extension.
For the last 6 months or so this has worked like a charm. Come renewal time the extension pings a request off to Let’s Encrypt, renews the certificate, and then applies it to my site. In the most recent case, this didn’t happen, resulting in my site reporting an SSL error to visitors for a few days before I noticed 🙁 The fix was simple. The extension needed an update and I just needed to apply the update before triggering a manual renewal. Job done, certificate goodness restored! 🙂
When I posted about this on Twitter Dale pointed me at Cloudflare as an alternative, with the added benefit of them providing CDN services. Now, I do use Cloudflare on another site I’m involved with for just that. For the most part it’s fantastic, but I do have some mild gripes with the way they implement their free SSL service. The CDN point is valid though, and prompted me to get on and take a proper look at Microsoft’s offering. I went through the motions of configuring Azure CDN today and figured I’d jot some thoughts down into a post on it’s implementation…
Enabling CDN for App Service
Unsurprisingly, Microsoft make the process of adding CDN capabilities to sites hosted in App Service super simple. Equally unsurprisingly, there are some caveats and things to be aware of in the process…
As a starting point, it’s possible to configure the CDN independently of the App Service. Triggering creation from inside the App provides some advantage though, in that some settings are pre-configured. You can find the option to enable CDN within the Networking section of your App:
Selecting the “configure Azure CDN for your app” link leads on to a simple wizard with a handful of fields to complete. If you already publish your site externally and have configured SSL there are additional steps to consider. I’ll cover those later on in this post. Initially though you will need to provide:
- The name for the CDN profile
- Your choice of pricing tier (Microsoft, Akami, Verizon, or Premium Verizon - see below for further information on this)
- The public CDN endpoint name (this presents on “azureedge.net”, but we can assign a custom name later on)
- The “Origin Hostname”. This is the host that provides the content to the CDN, and will be pre-populated if you’ve initiated creation within the App Service
In the case of the “Origin”, the “azurewebsites.net” address assigned to your App Service will be used by default. This will be invisible to users accessing your site, who will interact with a hostname that resolves to the CDN. Using this default configuration SSL is maintained end-to-end should users need to communicate with the App Service directly after CDN is enabled. You can change this address later should you wish, but be conscious of maintaining end-to-end SSL if you do.
Configuring Azure CDN
Once the CDN has been created you will fairly quickly be able to access your site using the new “azureedge.net” address. This isn’t immediate and can take up to a couple of hours according to documentation. In my case, it was around 30 minutes before things kicked into life.
A point I said I would come to relates to the tiers of service. Azure CDN isn’t as simple as on / off. There are considerations around the type(s) of content you will be distributing which will have a bearing on which of the options is best for you. I highly recommend reviewing this link which provides a detailed overview of the functionality within each “flavour” of Azure CDN. In my case, I opted for “Standard Verizon”. This provides the best mix of features for the content I’m likely to be hosting, whilst also supporting an upgrade to Premium should additional rule customisation, or reporting become a requirement. I won’t go into detail on the different editions within this post, but would be happy to provide some additional commentary / feedback on each if needed - just contact me via the comments.
As far as configuration is concerned, there are a handful of things you will want (and are able) to do once you’re up and running. Initially, review caching rules. Caching rules allow you define exceptions for content that is best served directly from the host. In my case, I’ve excluded paths relating to sign-in and administration by specifying that they should bypass the cache:
You’ll also want to review “Custom domains”. This section allows you to bind hostnames that you own to the CDN service. To do this, you need to add each domain name, validating ownership as through the creation of CNAME records. These resolve to the azureedge.net CDN address, and will remain in place on completion:
A word on SSL
Much like Cloudflare, Microsoft allow you to enable SSL on custom domains. This is an inclusive service (in the context of paying for CDN), with certificates issued by DigiCert. Subsequent processing and renewal of certificates is managed by the CDN service.
The astute of you will have noticed the “pending” nature of my HTTPS status in the above screenshot. Where you elect to use Microsoft issued SSL certificates, expect a wait. Potentially a long one (up to 24 hours, assuming no issues based on my reading). In the case of a live site this is obviously disruptive and needs to coincide with a maintenance window. The CNAME records for your custom domains need to resolve to the CDN for the validation to succeed.
As I write this, I’m awaiting validation of my domain certificates. I can access my site using an alternative SSL secured custom domain (which I’ve chosen to use for my “Origin” address). I can also access using my App Service’s “azurewebsites.net” domain. Those visiting my site on my usual URL’s in the meantime will be seeing a certificate error… which isn’t ideal. Update: This process took around 14 hours to complete in my case…
Obviously this is a one-time thing, but is a nuisance none the less. You can avoid this by using / uploading your own SSL certificates, but that obviously carries a cost vs. using the integrated service from Microsoft. A minor complaint in an otherwise straightforward setup.
I was surprised at the simplicity of CDN configuration within Azure. My experience has been focussed on App Service integration, but the steps and points mentioned are universally applicable. Azure CDN is a really straightforward service, as it should be to compete effectively with others.
The shine has been removed slightly for me with the delay in SSL validation. That aside, it’s doing what it should do. Page load times are reduced (based on some initial testing), performance for those accessing overseas should be improved, I have enhanced DDoS protection, and I (almost) have a free SSL solution to boot. Great success!
I haven’t made reference to pricing. Obviously Azure CDN isn’t a free service, but it is a comprehensive one. For those interested, pricing is available here. For all “standard” options, a tiered pricing structure based on data served is used. This is also true of the “premium” offering, albeit at an inflated cost. I’ll be continuing to use CDN for at least a few months, if not permanently, to gauge it’s effectiveness. Feel free to contact me for an update if / when you read this if interested.
I hope you’ve found this post useful. As always, feel free to contact on Twitter if you have any questions or feedback. It’s always welcome!