×
Search results provided by Azure Search - read how I built it in this post.
Max Melcher

3 minute read

In Hugo version 0.56 a native deployment command was introduced to deploy your blog/website to various cloud providers - one of them is Azure. In this post I show how I simplified my deployment pipeline with this command.

Hugo deploy

The Hugo deploy command uses Azure CLI and your config.toml / config.yaml file and checks for a [deployment] section. Additionally, you need to have two environment variables present - even tho the documentation says you have to use az login (thats incorrect, it works without). That has the benefit that your config file does not have the secrets and you can still publicly store it on github.

Environment Variables

You must have the environment variable AZURE_STORAGE_ACCOUNT and one of the following: AZURE_STORAGE_KEY or AZURE_STORAGE_SAS_TOKEN.

In powershell you can configure them like this:

$Env:AZURE_STORAGE_ACCOUNT = "<AccountName>"
$Env:AZURE_STORAGE_KEY = "<AccountKey>"

Or if you want to have it dynamic - that requires you to be logged in with Azure CLI:

$Env:AZURE_STORAGE_ACCOUNT = "<AccountName>"
$Env:AZURE_STORAGE_KEY = az storage account keys list -n <AccountName> --query [0].value -o tsv

Deployment Configuration

My deployment configuration looks like this:

[deployment]
order = [".jpg$", ".gif$"]

[[deployment.targets]]
name = "azure"

# Azure Blob Storage; see https://gocloud.dev/howto/blob/#azure
URL = "azblob://$web"

[[deployment.matchers]]
#  Cache static assets for 20 years.
pattern = "^.+\\.(js|css|svg|ttf)$"
cacheControl = "max-age=630720000, no-transform, public"
gzip = true

[[deployment.matchers]]
pattern = "^.+\\.(png|jpg)$"
cacheControl = "max-age=630720000, no-transform, public"
gzip = false

[[deployment.matchers]]
pattern = "^.+\\.(html|xml|json)$"
gzip = true

And in action

Simplified deployment with Azure DevOps

As described in the post RUNNING HUGO ON AZURE FOR 2$ A MONTH, I use Azure DevOps to automatically deploy Hugo to Azure and have everything version-controlled. My old pipeline did the following:

  • Generate Hugo content
  • Sync the content to Azure Storage (upload new files, delete no longer required files)
  • Set the cache header of files
  • Purge the Azure CDN
  • Index the content with Azure Search

I could combine the sync and cache header job with the Hugo native deployment - but as of know, the build task that I use, does not support that.

Update (August 19th, 2019)

I could not wait until the hugo extension is implementing the deploy command, so I thought lets try to use it with the PowerShell tasks of Azure DevOps.

My build server is a windows server (see post “SELF-HOSTED AZURE DEVOPS BUILD/RELEASE AGENT WITH TERRAFORM - WINDOWS-EDITION”) and I installed Hugo on it with Chocolatey. Then I used a powershell task to execute both the ‘hugo’ publish and the ‘hugo deploy’ command - and it worked straight out of the box!

And the commands in a copy&paste-friendly version:

#publish
hugo --source $(Build.SourcesDirectory) --destination $(Build.SourcesDirectory)\public  --enableGitInfo --i18n-warnings --verbose --cleanDestinationDir

#deploy
$Env:AZURE_STORAGE_ACCOUNT = "<storageaccount>"
$Env:AZURE_STORAGE_KEY = "<storageaccountkey>"
hugo deploy azure --maxDeletes -1

Afterwards I installed the chocolatey task to update Hugo to the latest version if there is one - that is not yet tested. Incremental deployment takes roughly 1 minute (for 1094 pages, 650MB) - thats awesome, right?

For local testing, the native deployment is great, too!

Hope it helps,
Max

comments powered by Disqus