Using Azure CDN to Specify Custom HTTP Headers for an Azure Static Website Hosted SPA

DevOps

Using a Static Website in Azure Storage to host your single page application (SPA) can be a very cost effective option. We are increasingly using this option to host our Blazor Web Assembly applications to provide very low hosting costs to our clients. Lower cost often means fewer features, and in this case static website hosting in Blob storage doesn’t provide the ability to set custom HTTP headers, such as for Content Security Policy. Fortunately, you can use Azure CDN to set these headers without incurring too much extra expense. In this post I will walk you through the steps to setup Azure CDN in front of your static website and append a custom HTTP header to all responses.

Prerequisites

If you want to follow along with this example, there are a few things you will need.

  1. An Azure Subscription
  2. A Storage Account configured to host a static website
  3. Some kind of content hosted in the static website. This example is based on a Blazor Web Assembly application, but it could just as easily be a single HTML page.

Step 1: Provision an Azure CDN Endpoint for your Static Website

An Endpoint is a separate Azure resource that lives under a CDN Profile resource, but you can create one for your static website directly from the Storage Account blade.

  1. Go to your Storage Account in the Azure Portal Azure Storage Menu

  2. Scroll down the menu until you see Azure CDN (it is under Blob service) and click on it to reveal the Azure Content Delivery Network settings Azure Content Delivery Network Settings

  3. Under New endpoint, we’ll enter details to setup a new CDN profile and endpoint.

    1. Leave Create new selected and enter a name for your CDN profile
    2. Choose Standard Microsoft for the Pricing tier (it is the cheapest and good enough for this example).
    3. Enter a CDN endpoint name (this needs to be unique on azureedge.net)
    4. Select your Static Website in the Origin hostname dropdown
    5. Click on Create. Grab a cup of coffee whilst the CDN endpoint is provisioned.

New Endpoint

Once the provisioning is complete, click on the endpoint. In the Overview of the endpoint that is displayed, you will find the Endpoint hostname (it will be something like https://yourendpointname.azureedge.net). If you browse to this address you should see your static site.

Step 2: Configure a Global Rule to Append an HTTP Header to All Response

Now that our CDN endpoint is provisioned, let’s use the Rules Engine to add a custom HTTP Header to every response.

  1. Go to your newly create Endpoint in the Azure Portal Endpoint Menu

  2. Click on Rules engine in the menu (under Settings)

  3. We want to append a custom header to every response, so we want to use the Global rule rather than adding a new rule. Click on Add Action in the Global Rule and select Modify Response Header. Rules Engine

  4. Enter values for the Modify response header fields. The examples below are for specifying a blazor-environment header with value CI:

    1. Action: Append
    2. HTTP Header Name: blazor-environment
    3. HTTP Header Value: CI

    Append Custom Header Rule

  5. Click on Save in the top menu bar. The portal will inform you that it is saving your endpoint changes. It can take up to 10 minutes for the changes to propagate, so grab some more coffee or read a book for a bit.

Step 3: Check the Results

To test that the changes have worked, we can simply fire up our browser and browse to the Endpoint hostname again with the browser’s developer tools open. If we check the Response headers on the Network tab, we should see our custom header has been applied correctly.

Response Headers

Wrapping up

Azure CDN is a fully featured Content Delivery Network, so it does a lot more than simply allowing us to append some headers to responses from our static website. But in this post we have focussed on that very common requirement and walked through how to add an Azure CDN Endpoint in front of a static website hosted in Azure Storage.