Azure Traffic Manager is Azure PaaS service which is helpful in the following scenarios:
1. Directing incoming application traffic to the nearest Azure data center
2. Failover to the other Azure data center (DR) in case of a catastrophic failure
3. Distributing traffic between endpoints according to the assigned endpoint weight value
In this blog post I’m going to discuss scenario #2 (failover) and some implementation specifics in case when failover endpoint is different from a primary endpoint.
Typical implementation scenario for Azure Traffic Manager is a failover mode (or how it’s called in Traffic Manager documentation – priority mode). In this scenario, Traffic Manager is configured to have two (or more) endpoints, each of these having an assigned priority. Traffic Manager is going to be examining the health of each endpoint and then redirect the traffic to the healthy endpoint with a highest priority (i.e. lowest priority value). Under normal conditions that means the main endpoint is getting all traffic while it’s healthy. If it goes down (which usually means a disaster scenario), then traffic is being directed to the next available endpoint with highest priority.
There are the following requirements to Traffic Manager endpoints:
- Each endpoint should be a host. It could either be Azure resource (public IP, app service or cloud service) or external resource (need to provide FQN). It can’t be a url, you can’t specify a path.
- All endpoints should provide health information to traffic manager monitor in uniform manner. Traffic manager health monitor will be doing GET requests to specified resource for each monitored endpoint. You can specify a protocol and a path to resource, but that protocol and a path should be the same for all endpoints, you can’t specify a separate monitor per endpoint.
Normally these limitations don’t pose any problem. A typical failover deployment is where both endpoints representing two copies of the same environment, essentially, deployed in either active-active or active-passive manner. In such case both endpoints are homogeneous.
However, lets consider the following scenario: there is no real failover endpoint, no stand-by DR deployment. All that we want to do in case of Azure region failure is to redirect user to some alternative system or to show him some friendly message, something like “system is not currently available, ETA to recover is such and such”. In this case our failover endpoint is heterogeneous to the main working endpoint and we may not have consistent health monitoring between endpoints. Furthermore, the “failover” endpoint may not even be a host, it could be a page on a web site.
Example:
- let’s say our main endpoint is api.contoso.com. It’s exposing health monitoring endpoint as http://api.constoso.com/health.txt (health.txt is a text file placed in the root of the web site).
- In case if our API is down, we would like to redirect users to www.constoso.com/maintenance page on a public web site. Public web site doesn’t contain health.txt in the root.
How can we implement this scenario using Azure Traffic Manager?
Well, it’s not possible to do directly because endpoints don’t expose uniform health monitors and failover endpoint is just a page on a site. However, it’s possible to simulate main endpoint interface using Azure App Service. I.e. we could create Azure App Service which would provide the same health monitor as main endpoint and also be a host, not a page. And which would be redirecting all incoming requests to the maintenance page.
The easiest way to implement the Redirector app service would be using Node.js. Of course, it could be done using any web development framework, but Node.js with Express is all but made for such task. You could install Node.js development tools for Visual Studio and write something like this:
var express = require('express'); var app = express(); var port = process.env.port || 1337 app.get('/health.txt', function (req, res) { res.send('Healthy'); }); app.get('/*', function (req, res) { res.redirect('http://www.contoso.com/maintenance'); }); var server = app.listen(port, function () { var host = server.address().address; var port = server.address().port; console.log('App listening at http://%s:%s', host, port); });
The code above would return “healthy” when asked for health.txt and redirect to maintenance page otherwise.
Well, this is it. Now you need to publish Node.js application to Azure App Service and register it as failover endpoint with Traffic Manager. And don’t forget to add api.contoso.com to the list of custom domains in your redirector app service, otherwise app service would not be able to respond to it.