Thumbnail image

Multiple Hugo Environment Configuration in Azure App Service

Test and introduction of new features to development environments first is very usual procedure which works when the testing rigs are as close to production as possible. Hugo provides some very convenient features to structure and apply configuration parameters for different environments for that purpose.

In this article I want to discuss how this features can be used to deploy a Hugo Website to Azure Static Web App Services and how to apply the right configuration (production, development) when building the static web app files using GitHub Actions.

In this article we will start with the following setup:

  • GitHub repository with Hugo project
  • Azure Static Web App Service setup for Hugo auto-deployment with the GitHub project

Check my other blog post on How to deploy a free website and CI/CD-pipeline using Azure and GitHub to learn how to do the setup.

This setup comes with a GitHub Action which can easily be customized. The following example will demonstrate how setup a production configuration for a Hugo app and how to apply it when running the GitHub Action. The following steps will be discussed:

  • Prepare Hugo production configuration files
  • Change GitHub Action workflow to apply production configuration
  • Alternative approach using environment variables

Prepare Hugo environment configuration files for production environment for Azure App Service

The first step is to break down the hugo configuration files into a folder structure separating default (see _default) configs from other environment configuration files e.g. production. Check the folder structure below for reference.

Hugo project
└───.github
│   └───workflows
│           azure-static-web-apps-*.yaml     
└───config
│   └───_default # will be always applied
│   │       hugo.toml
│   │       ... # other config files
│   └───production # will be applied wen hugo is run with '-e production' argument
│           services.toml

Make sure that you follow the same folder structure compliant to hugo specification. In this example we just add a config for Google Analytics for production environment:

# config/production/services.toml
[[googleAnalytics]]
    ID = 'G-MEASUREMENT_ID'

Configs in _default folder will always be applied. Other folders for each environment configuration to gather custom settings. They can be applied using hugo commands with the -e <environment> argument. This means if we want to apply the custom Google Analytics config provided in production we must pass the environment using:

hugo -e production # will apply configs in config/_default/ & config/production 

Apply production environment configuration with GitHub Action

Assuming you have setup Azure App Service deploying your Hugo app from GitHub correctly, Azure should have setup a GitHub Action in your project in .github/workflows/<some_git_action_job>.yaml.

This job will deploy your Hugo app with _default settings as soon as new changes appear on the set git branches. Azure provides a specific Azure/static-web-apps-deploy build step which provides this functionality. To apply additional Hugo configurations we can pass custom commands using app_build_command parameter. This can be done as follows.

- name: Build And Deploy
        id: builddeploy
        uses: Azure/static-web-apps-deploy@v1
        with:
          ...
          app_build_command: "hugo -e production" # adding custom build command

Alternative Solution

An alternative to manipulation of config files is to pass environment specific parameters using environment variables which is also supported by the Azure Build Step for Static Web Apps. This is a convenient way to exploit Hugo’s capability to read config parameters from the OS environment.

This would only require to edit the GitHub Action job as follows:

- name: Build And Deploy
        id: builddeploy
        uses: Azure/static-web-apps-deploy@v1
        with:
          ...
        env: # we only have to add the environment variables here
            HUGO_SERVICES_GOOGLEANALYTICS_ID: G-MEASUREMENT_ID

Mind that environment variables set using this method will only be available during build time.

Conclusion

We have discussed how to separate configurations for different environments for a existing Hugo App. Separating config files involves some work but is quite straight forward. You can reuse default values and reuse the same configs which makes it easy to maintain. This can very helpful to automatically apply custom configs e.g. for production which you don’t want in test stages.

The other option is to pass environment variables during the build step. This is very easy to setup but as configuration efforts increase or the more stages you have, this can get very ugly at some point. But if you don’t require many custom configurations, this can be a lean alternative.

Related Posts