📅 October 16, 2022

Azure Static Web Apps

I was recently tasked with researching and implementing a better hosting solution for our frontend Vue application at work. This was a great way for me to get more familiar with Azure and its various offerings. Below are some of the things I researched and the path I took which led to utilizing an Azure Static Web App.

The problem

The main issues we were trying to solve were:

  • Easier management of the SSL certificates
  • Reducing the complexity of the existing build and deploy steps.

Alternatives

In researching what route to take, I came across an informative Microsoft blog post that compared Azure Static Web Apps, Azure Web Apps, and Azure blob storage. After reading that, it seemed like experimenting with an Azure Static Web App would be a good first step to try.

What are Azure Static Web Apps

Some of the key features of Azure Static Web Apps are:

  • Web hosting for static content like HTML, CSS, JavaScript, and images.
  • Integrated API support provided by Azure Functions with the option to link an existing Azure Functions app using a standard account.
  • First-class GitHub and Azure DevOps integration where repository changes trigger builds and deployments.
  • Globally distributed static content, putting content closer to your users.
  • Free SSL certificates, which are automatically renewed.
  • Custom domains to provide branded customizations to your app.

The SSL certificates and GitHub integration for builds and deployments checked the two boxes we were trying to solve. Fantastic!

Authentication

Authentication is one of the necessary evils when it comes to web development. It always seems to be more challenging than anticipated. Azure Static Web Apps provides managed authentication to streamline auth. The current pre-configured providers are Azure Active Directory, GitHub, and Twitter. Those did not meet our requirements so I needed something more custom. There is the ability to configure custom providers that support OpenID Connect. Unfortunately, that didn't meet expectations either as I wasn't able to find a way to retrieve the user access token. Running the Azure Static Web App locally with custom authentication also appeared to be a not-so-great experience.

What I ended up doing was bypassing all of that and just continued to use the authentication that was pre-existing in our Vue app. This all functioned as expected locally and when deployed. 🔐

CI/CD | GitHub Actions

Speaking of deployments. Azure Static Web Apps integrates nicely with GitHub Actions. When you create a new static app in Azure, it will automatically create a GitHub Action workflow file for you to build and deploy the app. The default one is a fine default, but I like to separate out the build and deploys. This was relatively easy after getting some help from a blog post by Aaron Powell. I ran into an issue with the staticwebapp.config.json file not getting copied to the output directory after separating out the build and deploy jobs. This was solved by moving the staticwebapp.config.json file to the public directory of the Vue app. This made it so that file was in the published artifact. Separating out the build and deploy jobs is nice, as it also gets you easier access to the published artifact(s) in the instance you want to revert to a previous deployment.

An example workflow that I ended up with is below.

name: Dev - Build & Deploy

on:
  push:
    branches:
      - main

jobs:
  build:
    if: github.event_name == 'push'
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repo
        uses: actions/checkout@v2
      - name: Setup Node.js
        uses: actions/setup-node@v3
      - name: npm install and run build
        run: npm install && npm run build
      - name: Upload artifact
        uses: actions/upload-artifact@v3.1.0
        with:
          name: app
          path: dist/

  deploy:
    runs-on: ubuntu-latest
    needs: build
    steps:
      - name: Download artifact
        uses: actions/download-artifact@v3.0.0
        with:
          name: app

      - name: Deploy to Azure
        id: deploy
        uses: Azure/static-web-apps-deploy@v1
        with:
          azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN }}
          repo_token: ${{ secrets.GITHUB_TOKEN }} # Used for GitHub integrations (i.e. PR comments)
          action: "upload"
          ###### Repository/Build Configurations ######
          app_location: "" # App source code path relative to repository root
          api_location: "" # Api source code path relative to repository root - optional
          skip_app_build: true
          config_file_location: ''
          ###### End of Repository/Build Configurations ######

Conclusion

Using an Azure Static Web App seems to have met all of our requirements and greatly reduces the management burden placed on the team. The tight integration between Azure and GitHub is fantastic. Getting up to speed wasn't too challenging as the documentation was instructive. I would definitely recommend checking out this service if you are looking for frontend hosting!

Resources

#development#devops
An unhandled error has occurred. Reload 🗙