I had a recent requirement from one of our clients that took a little bit of tinkering to figure out… we will call our client Contoso LLC. and our project that we host for them we will call the “Cool Widget Project.”
We built a really neat widget of an application for Contoso to use and we are hosting it under a sub-domain of a domain we control. We needed to keep hosting it under this domain. However, our client, Contoso, wanted to hand out a link for their users to the new widget we built using an existing sub-domain from a domain they control. This was of course under their main domain, constosollc.com, and they already had existing users that came to the old version of the widget (built by another vendor) at widget.contosollc.com.
Our company was hosting the new widget app at widgetapp.appworks.net.
To further complicate things… our company appreciates security, likes fast DNS updates, and the app really benefits from using a CDN… so we are using Cloudflare to manage DNS for the appworks.net domain. Better yet, we also like the cloud, and this new widgetapp is actually an Azure Web App.
So there’s the situation…
We essentially need this to happen:
Oh but this is Azure… so actually widgetapp.appworks.net is already a CNAME record and it actually points to widgetapp.azurewebsites.net. So it is this:
To elaborate the above just a little bit more:
Simple right? Just get our client to create a CNAME record that points to widgetapp.appworks.net and move on with life… wrong…
Why? – CloudFlare… Our client isn’t using Cloudflare for THEIR contosollc.com domain. If they put a CNAME record in and direct it to our Cloudflare hosted domain then Cloudflare will pop an error page up and say it doesn’t have a clue regarding the “widget.contosollc.com” domain. Why? Honestly I am not quite sure… I think it is a combination of the fact that OUR record in cloudflare (widgetapp.appworks.net) is a CNAME record and furthermore we are using Cloudflare, technically, as a CDN proxy and getting all of the benefits therein. I think the fact that this “breaks” probably means that some rules in the DNS architecture standard are being broken by cloudflare in order to do what they are doing… But it gets better…
Still simple though… right? Just get our client to create a CNAME record that points to widgetapp.azurewebsites.net and move on with life… wrong again…
Why? – Cloudflare… in this case we are skipping the Cloudflare CDN/Security/Proxy tier all together. Now… this WILL technically work but you have to make sure you setup your Azure Web App to recognize the domain name “widget.contosollc.com” just like you would with any other custom domain you want to use with an Azure Web App… but yes, it will work. But it wouldn’t work for us… because we have a business requirement that users come through the Cloudflare CDN/Proxy.
So… what was the final solution? First a bit about CNAME records vs. HTTP Redirects
CNAME records aren’t really meant to be true “redirects.” At the end of the day, a CNAME record is just pointing some domain to an IP address (just like an “A” record) but they are essentially telling the DNS resolver engine “Hey! Grab the IP for this other domain over here and use it.” vs. directly specifying an IP address. It’s more “reference” than true redirect. Namecheap explains it pretty well here.
It might seem like semantics but it is a real-world difference that leads to no end of confusion, even with people that have been in the IT space for a long time.
What we need is a “true” HTTP redirect. Now, if everything was in Cloudflare then they have a nifty feature that lets you essentially do exactly that through Page Rules. In this case, our client owns and controls the ContosoLLC.com and it is NOT in Cloudflare and this method does not work (I tried it).
So that means I need a redirect rule on a destination web server/service whose endpoint I don’t mind being hit directly (vs. coming through CloudFlare). If I were an actual developer on the project, I could have possibly created a redirect rule in the IIS config of the main Azure Web App service and sorted it out there. I am not an actual developer on the project. Rather, I am the systems admin on the project tasked with figuring this out.
So here is what I did… the solution.
1. Created a new Azure Web App service on the cheapest service plan I could get that supports custom domains (that last part is critical).
This new Azure Web App service (which is dirt cheap) is now alive at widgetappredirect.azurewebsites.net. Azure Web Apps don’t actually have to host any content… they can consist of just a web.config file and work just fine. Hence, I stole the web.config file (and the idea) from the guy who wrote this.
Web.Config code example:
<httpRedirect enabled="true" destination="https://widgetapp.appworks.net" httpResponseStatus="Permanent"/>
2. I put in the code to do a permanent HTTP redirect of ALL incoming requests to the Cloudflare managed domain of my real app at widgetapp.appworks.net. I uploaded this to my new dirt cheap Azure Web App service. I tested it out by visiting the widgetappredirect.azurewebsites.net domain and it works a treat. Great!
3. I then have our client create a CNAME record for widget.contosollc.com that –> widgetappredirect.azurewebsites.net.
4. Once that CNAME record is created, I login to Azure and add widget.contosollc.com as a new custom domain name for my widgetappredirect Azure Web app, wait 10 minutes… and voila! – SUCCESS… So the final solution, which I agree is a bit ugly…
widgetappredirect.azurewebsites.net (the DNS name provided by Azure for my redirect application) -->
does an HTTP 301 redirect to -->
widgetapp.appworks.net (Cloudflare DNS, CNAME) -->
widgetapp.azurewebsites.net (the DNS name provided by Azure for the application).
In addition to allowing me to keep my CloudFlare tier in place, the other beautiful thing about this solution is that I can enforce HTTPS when I do the HTTP 301 redirect in my custom application without getting into messy situations with multiple SSL certificates for multiple domains that often lead to security warnings/errors. HTTP redirects are also a LOT more flexible (vs. just using CNAME records) in that you can spit users out on a specific PAGE in the destination domain if you so desire.
Anyhow, if you didn’t catch it from just the length of this post, I took a rather circuitous route to get this figured out. I realize the above scenario is a bit of an edge case perhaps… but then again the internet is a big place and I doubt I am the first person to run into this issue or something very similar to it. All that to say, I hope this was beneficial.