Running your static website in Azure - with Hugo

Hugo + Azure Storage + Azure CDN + Azure DNS

I’ve been planning to create a blog for some time now but never found the right timing for it…now it is the time.

In my current role I work with customers in order to help them overcome all obstacles when moving to Microsoft Azure. I did the same with my blog this time.

While exploring a lot of the available technologies that I could use to create the website I decided to go with:

  • Hugo - easy to use static website generator
  • Azure Storage - very cheap and perfect for hosting files
  • Azure CDN - caching for static files with HTTPS endpoint
  • Azure DNS - custom domain management and hosting directly in Azure
  • Azure DevOps - automate website deployment to Azure Storage

Azure DevOps

Most examples you find online are based on GitHub but for my blog I wanted to implement automation using Azure DevOps for multiple reasons.

If you don’t have an Azure DevOps instance please create it here before moving to the next step.

Create Azure DevOps project

In order to create the project click on the Create Project button on the top right and give your project a name. Make sure you select Git as Version Control for your project.

Azure DevOps Create Project Image

Once the project is created clone the repository to your local environment following the instructions in the main page of the project.

We will create the commit the code to the repository in the last step of this blog post.

Create Build Definition

Since we are going to deploy a static website there is no dependency that we need to have in-place before creating the build definition so we can create the build definition right away.

Navigate to the Builds tab under Azure Pipelines option.

Create Build image

Then, create a new empty build definition and add the following 2 tasks:

  • Hugo - you need to import this one from the Marketplace
  • Azure File Copy

Make sure that you enable the checkout submodules in the Get Sources option as shown below. We will need this in order to support Hugo Themes. Checkout Submodules image

Hugo task

This task will be used to generate the static files that will be published to Azure Storage afterwards. Specify the Source, Destination and Base URL as illustrated in the below image.

It is very important that the Base URL field matches with your final DNS otherwise you will get some errors in your requests.

Hugo task image

Azure File Copy

This task will copy the static files generated on the previous step to a specific path on an Azure Storage Container. Select your own Azure Subscription and Storage Account.

Make sure that you select the preview version (2.*) of the task.

We will be publishing the content to $web container which is specifically designed to support static websites.

Azure File Copy task image

Enable continuous integration

To enable continuous integration you need to change the trigger for you build pipeline.

Enable Build CI image

And that is all for the Azure DevOps.

Azure Storage

Azure Blob Storage is a cheap solution where we will host our static files. In order to create an Azure Storage follow the official documentation here.

We will leverage a preview feature (Static Website) from Azure Storage in this step so we can enable our storage to be able to host static websites.

Enable static websites image

Make sure to copy the Primary Endpoint because we will need it in the next step.

Azure CDN

Since this a static website we can leverage Azure CDN to move our website closer to our users by using the Azure CDN POP locations. And the cool thing is that this magic is all done automatically for us.

Another feature that Azure CDN brings to us is the chance to use HTTPS. At this point in time we cannot have HTTPS in Static Websites directly.

You can choose between multiple profiles and providers in Azure CDN (Akamai, Verizon or Microsoft). In this specific scenario I am going with Azure CDN Standard from Microsoft.

Follow the official documentation here to see how to create an Azure CDN Profile.

Once the Azure CDN Profile is created we need to create an endpoint that points to the storage account where the website is hosted.

Since we are using Static Files feature that is still in preview we cannot map the Azure CDN directly to the Storage Account, we need to use a custom origin and paste the Storage Endpoint generated in the previous step.

Add Azure CDN Endpoint image

Optional - Add a custom DNS

Since I am hosting my production blog I decided not to use the dns provided by Azure CDN but to use my own as you can see in the below image.

Azure CDN Custom DNS image

Azure DNS

In order to support your own custom domain there are multiple ways to do it.

In this case I have purchased my domain in and delegated administration to Azure DNS so I can manage subdomains and other configurations directly in the Azure Portal - see here how to do it.

To create an Azure DNS zone follow the official documentation here.

Once you have the Azure DNS zone created and domain validated you can create a CNAME for the website. In this case I called it blog and pointed to the Azure CDN endpoint.

Azure DNS CNAME image


Now that we have all the “infrastructure” deployed we just need to get our code deployed to our Git repository.

To get Hugo installed locally, create a new site and add a theme just follow the quickstart guide on Hugo’s website.

Make sure you do the tasks above on the folder you cloned earlier from Azure DevOps.

Then we just need to push the code to Azure DevOps and the automated build should start immediately.

> git add -A
> git commit -m "First commit for Hugo Website"
> git push 

This is my end result with some changes to the template and content.

End Result image