Setting up Backstage.io on Azure App Services with Github Actions, Azure AD Authentication, Terraform and Azure Container Registry

Backstage.io is a platform to build developer portals, made by the people over at Spotify. In this post, you'll get a complete guide to setting it up with Azure, Github and Terraform.

Backstage.io is a platform to build developer portals, made by the people over at Spotify. Here, I'll go through everything needed to set it up to run as a containerized App Service in Microsoft Azure, using your already existing Azure AD. We're going to be utilizing Terraform for creating and managing all our infrastructure.

We will need to set up a few different things:

  • A Github repo to house the Backstage-app itself
  • Github Actions to build and push the Backstage app container to Azure Container Registry.
  • All required resources in Azure, listed below. Whatever user you run Terraform as, need to have access to create all of this.
    • Resource group to hold all of our stuff
    • Service principal to run on behalf of
    • App Service Plan with an App Service to actually run the container
    • Storage account, to hold content for the Techdocs-plugin
    • PostgreSQL database for backstage storage
  • We'll also set up an Azure Container Registry to push images to. Skip this if you already have a container registry available for you.

The Backstage-app repo

  1. Create your new repository, and name it something appropriate.
  2. Create a new app as described in the official docs. Basically run npx @backstage/create-app from the root of your new repository.
  3. Tweak the config to use a PostgreSQL database, like described in official docs. Just stick with those environment variables (for example ${POSTGRES_HOST}) for now. We'll get to those later.
  4. After this, add config to the Azure AD provider (but don't manually create that Azure app, we'll get to that below), like the docs say.

To make it a bit cleaner, we can split our app-config.yaml in two; one base file, and one specific for the production environment.

In the end, you should be left with two files like shown below:

Also, modify the packages\backend\Dockerfile to include the production config by changing the very last line to CMD ["node", "packages/backend", "--config", "app-config.yaml", "--config", "app-config.production.yaml"]. It should now look like this:

GitHub application for authenticating Backstage

To let Backstage authenticate against your GitHub organization and read the data it needs, we'll start by setting up a GitHub app. To do this, go to Settings for your organization → Developer settings → New GitHub app.

At the top, you'll find an App Id and a clientId. These will be added as variables in Terraform later on. Let the Home page url be the intended URL you want to reach your app on in the end. This can be modified later in case you need to wait for a proper domain to be set up.

A little farther down, you'll find the webhook URL and you can create a secret. Uncheck the "Active" checkbox under Webhooks, it's not needed for now. Terraform-variables are already added and hooked up for it if it becomes relevant in the future, though.

Then, the app needs to have Read-only access to Contents and Metadata under Repository Permissions.

Below the permissions list, make sure the app can only be installed "On this account". Hit create app.

When you now look at the app, we need to do two things: Create a Client secret and a Private Key. We'll need these later on, so keep it somewhere visible for now - it'll disappear if you reload this page.

Now, go to Install App and install the application into your organization.

Setup required Azure resources with Terraform

The following Terraform files contains all resources you need, including an AzureAD application, and injects all necessary information as secrets into GitHub organization and repository for the build and deployment to work.

  • The user running Terraform must have access to create all these things.
  • Depending on tenant wide settings in your AzureAD, admin consent and/or permissions need to be given regardless of the setup done here. Ask your administrator for help if people cannot log in when all is set up and done.

See explanation to the variables in vars.tf below.

When these have run successfully, you should see some new secrets if you look under the Secrets section of your organization settings in GitHub. These will be used by the build step to push new container images to the container registry, as well as to push techdocs content to its database.

Optional: Azure Container Registry

Below you'll find the necessary Terraform scripts to create a resource group with an Azure Container Registry resource, as well as the necessary service principal, access, and necessary secrets pushed to GitHub.

See explanation to the variables in vars.tf below.

GitHub action to build and push Backstage app

In the repository you have set up your Backstage installation, add the following file in this location: .github\workflows\build-docker-image.yml. This will add the build and deploy step as a GitHub Action triggering whenever something is pushed to the main branch.

GitHub action to build and push techdocs content

The TechDocs plugin is one of the fundamental things in Backstage, and is included if you use npx @backstage\create-app. Add the following file in .github\workflows\build-and-publish.yml in the GitHub repositories in which you keep your techdocs documentation. Also note you'll need an mkdocs.yml in that repository. For example, take a look at Backstage's own file. Oh, and remember to put the content in docs/ as is the default for mkdocs.

Phew! That's a lot of stuff. But at least now, you should be able to visit whateveryouchose.azurewebsites.net, and see your brand new Backstage installation up'n'running! It might not be perfect yet, but it's a start, and from here on out, you're free to customize it in every way you want.