Setting up a CDN in front of your application can sometimes cause the host the application sees to be different than what the user requests. An example with Azure CDN would be (user requests yourdomain.com and App Service sees yourdomain.azurewebsites.net).
The objective of this post is to show a scenario allowing an Azure App service to use an Azure CDN resource and have the origin still receive the request with its original host header, HTTP_HOST. This will allow the use case of being able to have our application contain redirect logic to redirect all “www” request to the naked domain (yourdomain.com)
There are the many reasons you may do this and other workarounds available in Azure. An example use case is an application that requires the actual host the user enters, the domain, for internal logic like link generation, multi-site differentiation or redirects.
We will focus on Azure’s resource types:
- CDN – Azure Content Delivery Network (CDN) which is used for caching and offloading costs and traffic – specifically the Standard Microsoft offering. Each offering comes with different costs and features available
- App Service – also known as “Web App” used for application hosting
- DNS – DNS Zone is a product for managing DNS records for a Zone in Azure and integrates nicely with other Azure services
What considerations do we have?
- Custom domains – for this post we plan on using yourdomain.com as our SEO canonical example domain. This is also an apex or naked domain which we will see has some DNS implications. Our App Service will need a custom domain registered, will need SSL configured and certificates uploaded.
- DNS Zone in Azure means we need to let our registrar know what nameservers to use before we can begin adding our custom records
- Apex domain – since I want my canonical domain to be yourdomain.com we will have to find a way to make DNS work with Azure App services which have IP’s that are subject to change. We cannot use a CNAME record since they are not allowed at apex root zones. Remember our use case us redirect from www to non-www. If you want www as your canonical you will also see advantages of Alaias A records as this post describes as they hide the actual IP of your application server.
- We are not planning to use a CDN provider or other Azure services like Front Door that allows custom headers to be passed through or other alternatives, this is meant to be a simple and cost-effective solution.
So the first thing we will run into is we need to create our Custom domains in our CDN profile. When we go to add the domain yourdomain.com it asks us to create a CNAME in our DNS provider from yourdomain.com to yourdomain.azureedge.net which is the CDN edge domain. This is a problem because we cannot have a CNAME for the apex domain, we need an A Record. You could just keep your apex domain with an A Record to the App Service and script an Azure Function to monitor for changes updating the DNS and then use www. for your canonical domain – but that would be too easy and has other implications.
Luckily Azure has
solved provided a solution for this, as have other DNS and cloud providers, with solutions like Alias records and CNAME flattening. Just go into the DNS Zone and add an Alias A record and select the CDN profile from the resource drop down. Now in the CDN profile when validating a custom domain it will be recognized. *Remember we can’t use a CNAME here.
What they seem to do is let the authoritative DNS Server handle recognizing the special record type and handle any IP mapping to the resource in question. So basically the Azure DNS servers should give back the correct geo located CDN edge server IP, or App Service, or Traffic Manager, etc.
Now I did not test in great detail how this differs in Azure if you use Alias CNAME records vs Alias A records but I would assume its easier for them in the CNAME instances to give more geolocated edge servers back from the DNS query. That is out of scope for this blog and something I would like to read up on if anyone has researched this or Microsoft, Amazon, Cloudfare want to release a white paper on how it works :). From what I have seen with the Microsoft CDN provider and doing DNS A record lookups from different regions for this most part the same IP is returned, this was also the case when using the “.azureedge.net” domain which would typically be the case – CNAME www.yourdomain.com to yourdomain.azureedge.net. Regardless we can now have a Zone Apex domain and have Azure handle all the IP management.
Getting our App Service to receive and recognize our custom domains. First, we need to tell the CDN to pass through the original host and then make sure the App Serice recognizes it.
- In my case, I want to use redirection through my application as the use case so I’m going to create another Alias A record for the www subdomain and add the custom domain in the CDN profile – also used a custom SSL certificate that was stored in blob storage
- Go to your CDN Profile and under the Origin settings tab make sure the “Origin host header” field is empty – this will pass through the original host to the origin server
- Go to your App Service and try to add the custom domains “yourdomain.com” and “www.yourdomain.com” – if it fails for the “www” domain then add a TXT record with host “www” and value “” and now it should validate fine
Note that using a Alias CNAME record or CNAME for the www did not allow the App Service custom domain validation. The way the DNS lookup works is by following CNAME’s until it finds an A record and checking for the TXT record in that zone, which in this case would be a zone Azure manages that you would have no way of adding that record.
Thats it, out App Service hosted application now has the correct HTTP_HOST header value that the user requested and our redirect logic can look for www. and redirect it to the canonical domain.
This post was written solely to show a way to get the hostname to pass through to an App Service using Microsoft CDN and DNS. It’s not meant to say you should use this strategy for your site and better ways to handle this in a large scale production environment. Decisions like making the apex domain the canonical again was just to show its possible, in most cases you can just have your Alias A record for the apex, use redirection to the canonical, www in most cases and other features of the different CDN providers and Azure services to form the ideal hosting architecture for your requirements.
I covered a decent amount of info at a high level or just referenced so here are a few links that may help if you are unsure of how to configure any of these topics:
- DNS Alias record – http://bit.ly/31OjVqJ
- CDN to map custom domain – http://bit.ly/31RfoUq
- CDN & SSL – http://bit.ly/31P062C