Using Azure Front Door in a multi-tenant application

Henk van de Crommert
8 min readMay 6, 2020

--

Considerations when routing users to a globally deployed, multi-tenant application

Introduction

If you’re building commercial software, you should be thinking about making your web application multi-tenant. As you do, you realize that this goes beyond white-labeling your stylesheets and automating the onboarding of new tenants. Part of the challenge is to (infinitely) scale out and have a presence in multiple geographies.

This article will explore how Azure Front Door can help route individual users in a multi-tenant, globally deployed application. It is focussed on concepts and strategy — it will not include scripts or templates.

A multi-tenant application in, globally deployed

To start with, having a multi-tenant web application is a great way to optimize costs and effort. For example:

  • Optimized resource usage, as resource capacity claimed is shared over a larger number of customers
  • Reduced management overhead, as there is an application deployment for a group of customers — not per customer
  • Reduced costs, as a result of the optimized resource usage and reduced management overhead.

A multi-tenant application does not imply that there is a single application deployment supporting all tenants. In fact, going for a single deployment would introduce limitations to scalability, configuration, versioning management.

Instead of going for a single instance for everyone, it is a common practice to distribute tenants across different instances of your application. These different instances are typically referred to as deployment stamps or scale units, representing a deployable, independent version of your application aimed to support a subset of the tenants.

Having multiple deployments allows the architecture to:

  • Address scalability limitations of the application and / or the underlying infrastructure
  • Isolate particular tenants that have more stringent security requirements / customizations
  • Provision tenants in a particular region / geo, allowing the application to support data sovereignty and other legislation

Having multiple deployments also introduces challenges. As part of architecture and product strategy and the focus for this article, we need a plan to direct end-users to the deployment stamp or scale unit that supports their tenant.

The application

Assume that the application is build on Azure App Services and deployed in 6 geographies: EastUS, WestUS, Europe, France, Norway and Australia. The application’s architecture caters for disaster recovery scenarios by having a secondary (active) deployment in the paired region.

Out of the box, this means that the user can choose from 6 primary + 6 secondary URLs:

Routing

Needless to say, these default URLs are not user friendly. They are hard to remember, easy to mistype, impossible to change without impacting the users and simply do no justice to the quality of the actual product.

Instead, a DNS record will be created. Such a record provides a great opportunity to route individual users to the appropriate stamp — or does it?

Let’s look at the different strategies that are possible, and evaluate their appeal (subjectively):

https://app.contoso.com

  • Very user friendly
  • Can be routed via Azure Front Door and Traffic Manager (DNS-based)
  • Does not provide sufficient information to route users to a particular stamp / geo.

This URL works great in combination with a tenant discovery service, where the discovery service provides a redirection to one of the other, more routable URLs — or add a request header that allows the request to be routed to the desired tenant / stamp via the Azure Front Door Rules Engine (Preview)

https://stamp.app.contoso.com

  • Not very user friendly
  • Routable to the appropriate stamp
  • Can be routed via Azure Front Door and Traffic Manager

As the initial URL, this approach is undesirable. But even when used for redirection, the approach is not very appealing. It exposes internal details of the system and potentially limits the options in rebalancing tenants across stamps.

https://tenant.app.contoso.com

  • Fairly user friendly
  • Routable to the appropriate stamp
  • Can be routed via Azure Front Door and Traffic Manager

Nothing really bad about this approach — the URL contains sufficient information to support routing, is fairly recognizable and effectively hides the underlying infrastructural details.

https://app.contoso.com/tenant

  • Fairly user friendly
  • Routable to the appropriate stamp
  • Can only be routed via a solution like Azure Front Door, not via DNS / Traffic Manager

https://app.contoso.com/?tenant=Tenant

  • Not user friendly
  • Routable only via a solution like Azure Front Door in combination with the Rules Engine (currently in preview)

This is included for completeness sake only and may have a purpose somewhere — the reader is encouraged to look at the alternatives.

Tenant discovery service

Where the initial URL is not routable enough, part of the routing challenge we are evaluating here can be addressed by a tailored (micro) service.

A Tenant Discovery Service acts as the default landing zone for the application, responsible for mapping (authenticated) users to the corresponding tenant capacity.

The flow would look as follows:

  1. User navigates to https://app.contoso.com
  2. The initial request is generic and not yet mapped to a tenant. The system forwards the request to the tenant discovery service.
  3. The tenant discovery service attempts to find the corresponding tenant.
  4. Once the tenant is identified, the discovery service responds with a HTTP 302 (redirect).
  5. The browser follows the redirect and the user ends up a the target location.

This implementation of step 3 could be done via a reference table or an algorithm based on the user’s identity, or otherwise. In addition, users that are associated with more than one tenant could be presented with a web page that lists their options.

To redirect, the tenant discovery service can:

  • Redirect to a routable URL (e.g. stamp.app.contoso.com, tenant.app.contoso.com, app.contoso.com/tenant, app.contoso.com/?tenant=tenant)
  • Define a routable header value. This is only possible if the discovery service and the application are under the same domain, as it depends on a domain-level cookie.

Intermezzo: Azure Front Door overview

In the previous sections, there have been few references to Azure Front Door to support the required routing. Azure Front Door is a complete application delivery controller, offering features beyond request routing.

Azure Front Door is used to add a variety of performance, security and availability-related features to your application. The documentation describes it as follows (link):

Azure Front Door enables you to define, manage, and monitor the global routing for your web traffic by optimizing for best performance and instant global failover for high availability. With Front Door, you can transform your global (multi-region) consumer and enterprise applications into robust, high-performance personalized modern applications, APIs, and content that reaches a global audience with Azure.Front Door works at Layer 7 or HTTP/HTTPS layer and uses anycast protocol with split TCP and Microsoft's global network for improving global connectivity. So, per your routing method selection in the configuration, you can ensure that Front Door is routing your client requests to the fastest and most available application backend. An application backend is any Internet-facing service hosted inside or outside of Azure. Front Door provides a range of traffic-routing methods and backend health monitoring options to suit different application needs and automatic failover models. Similar to Traffic Manager, Front Door is resilient to failures, including the failure of an entire Azure region._

It is flexible and allows to be configured in various ways, to support your application needs.

Azure Front Door configuration is defined around the following concepts:

  • Frontend endpoints, defining the public URLs / domains that are processed via Front Door. E.g. ‘contoso.azurefd.net’ is a frontend endpoint.
  • Backend pools, define a logical grouping of backend server endpoints. Strategies on load balancing, priority routing and health monitoring are defined here. E.g. “EastUSStamp1” can be a backend pool, where “https://app-eastus-stamp1-region1.azurewebsites.net" and “https://app-eastus-stamp1-region2.azurewebsites.net" are the backend servers.
  • Routing rules, map incoming requests to a particular backend pool. Uses the host name (contoso.azurefd.net, app.contoso.com) domain and path to forward or redirect a request.
  • Web Application Firewall, a set of security policies that can be associated with a frontend-endpoint or domain. Rules can allow, block, log or redirect requests based on their geo, IP and other criteria.
  • Rules Engine (Preview), to modify the incoming requests based on request-specific conditions. This is evaluated after WAF and initial routing has been completed, but before the request is actually forwarded or redirected.

These concepts are combined to define the desired behavior, only limited by the scaling limits of Azure Front Door are documented here.

Every plan has its limitations

Having a Tenant Discovery Service addresses most practical limitations, but may not be possible.

Given that the URL should be user friendly and ruling out the Tenant Discovery Service, there are 2 options remaining: https://tenant.app.contoso.com and/or https://app.contoso.com/tenant.

Both can be routed directly via Azure Front Door; but both will have a slightly different approach and limits:

Routing https://tenant.app.contoso.com

Azure Front Door routing when the tenant information is part of the hostname

This strategy is based on a combination of Azure Front Door and DNS-based request routing. It considers Azure Front Door to be a scale unit itself, defining a group of related stamps / tenants routes to optimize manageability and scalability. For example: start with an Azure Front Door resource per geography, supporting up to 500 tenants in that single resource — linearly scaling up to 100 resources (50,000 tenants) per subscription (and before contacting support).

There are some downsides to this approach. Although Azure Front Door scaling is practically limitless in the setup, there are other considerations:

  • DNS Limits. This may vary, depending on the DNS provider but as as an example, Azure DNS allows you to create up to 10,000 record sets per public zone — well below the theoretical maximum of Azure Front Door.
  • Costs. The approach implies an additional cost per tenant (of approx. $5/month) for the domain. This adds up.
  • Effort. The approach requires management of both DNS and Azure Front Door, for every tenant onboarding. Wildcard DNS entries do not provide a solution here: these entries can only map to a single Azure Front Door endpoint and can only be associated with a single Azure Front Door resource.

Routing https://app.contoso.com/tenant

Routing based on the request path, for a single global URL

This strategy centralizes management within Azure Front Door. In DNS, a single entry is registered, mapping app.contoso.com to the Azure Front Door resource.

Within the resource, routing rules are defined per stamp. Each routing rule will forward appropriate requests when the /tenant part of the path matches match the rule's condition .

As the configuration is centralized in a single Azure Front Door resource, scalability is limited in this approach. It supports up to 50 backend pools and up to 12,500 tenants (i.e. 500 routing rules per resource, 25 patterns per routing rule).

Conclusion

Building a globally deployed service takes time and effort. Making it multi-tenant adds to that complexity, but greatly improves the manageability and margin of the product.

In many situations, the application can incorporate a Tenant Discovery Service. Such a service offers the benefit of having a single, user friendly URL and is most flexible towards the management of stamps, users and tenants, cost effective and offers practically limitless scalability.

There are cases where having a central Tenant Discovery Service is not possible or desirable. The reasons will differ: it may be a legacy application that does not support it, time or capacity is too constrained or there is a strong (legal) preference NOT to have a centralized store (or method) to map users to their tenants.

In those scenarios, one should look at the 2 alternatives that best balance a user friendly URL with being routable over the internet, consider their limitations and decide on the option that is most appropriate given the unique criteria of the application at hand.

Happy routing!

--

--

Henk van de Crommert

Cloud Solution Architect @ Microsoft, working on globally deployed, cloud-native applications. Opinions expressed are my own, facts potentially outdated.