3 min read

Use Bicep and Azure Static Site for your Blog Deployment

Use Bicep and Azure Static Site for your Blog Deployment

I have been a user of Vercel for a long time, but recently I wanted more control over the deployment process of my blog! Which is why I decided to move everything to Azure for this, seeing that they have a new Static Site hosting option which is simply AMAZING (and free 😉).

Typical Blog Setup

Typically when setting up a blog, we need to take care of a couple of things:

  • Storage Account (expose this to allow public access)
  • CDN (for fast worldwide delivery)
  • CI/CD setup (e.g. GitHub Actions)

Azure Static Site with Bicep

Now recently a new offering was made available that bundles all of the above and automatically bundles your application and publishes your website. The only thing we have to do is provide the repository URL and how to build our website! 🤯 Now let's create our Azure setup with an Infrastructure-as-a-Code tool named Azure Bicep

Creating Bicep Files

The first file we have to create is our main file that contains the modules we want to deploy and some general overview. In here we use subscription scoping to define what has to happen at a subscription level

We split up subscription level resources and resource group level resources in different files. Resource groups are created at a subscription level, while resources are created at a resource group level.

Our main.bicep file will thus define some parameters and their defaults and create a resource group. After creating this resource group we will tell it to initiate our static-website.bicep module that takes care of creating the static website setup itself.

main.bicep

param environment string = 'dev'
param location string = 'westeurope'
param resourcePrefix string = 'yourresourceprefix'

// Parameters for static website
param repositoryUrl string
param repositoryToken string // the repository token to setup actions workflow and api secrets (https://github.com/settings/tokens)
param repositoryBranch string = 'master'

// This file operates at a subscription level
targetScope = 'subscription'

resource MainRG 'Microsoft.Resources/resourceGroups@2021-04-01' = {
  name: 'rg-${resourcePrefix}-${environment}'
  location: location
}

module ModuleStaticWebsite 'static-website.bicep' = {
  // Change deployment context to RG
  name: 'static-website'
  scope: resourceGroup(MainRG.name)
  params: {
    environment: environment
    resourcePrefix: resourcePrefix
    repositoryUrl: repositoryUrl
    repositoryBranch: repositoryBranch
    repositoryToken: repositoryToken
  }
}

Now our resource group is created, we define our static-website.bicep module. This module is quite straightforward as we just have to define the SKU, the Tier and our repository settings as well as how to build our application!

Note: I am using a Next.js deployment, so I define that my site output will be situated in the out folder starting from the / after building through npm run build

static-website.bicep

param environment string
param resourcePrefix string
param location string = resourceGroup().location

param repositoryBranch string
param repositoryUrl string

// the repository token to setup actions workflow and api secrets (https://github.com/settings/tokens)
// needs to have repo and workflow access
param repositoryToken string
param skuName string = 'Free'
param skuTier string = 'Free'

// https://docs.microsoft.com/en-us/azure/templates/microsoft.web/staticsites?tabs=bicep
resource staticWebApp 'Microsoft.Web/staticSites@2021-01-15' = {
  name: 'ss-${resourcePrefix}-${environment}'
  location: location
  sku: {
    name: skuName
    tier: skuTier
  }
  properties: {
    provider: 'GitHub' // required to ensure success in follow up deployments
    repositoryUrl: repositoryUrl
    repositoryToken: repositoryToken
    branch: repositoryBranch
    buildProperties: {
      outputLocation: 'out' // next.js will export to the out directory
      appLocation: '/'
      apiLocation: ''
    }
  }
}

// Outputs
output deployment_token string = listSecrets(staticWebApp.id, staticWebApp.apiVersion).properties.apiKey

And that's it! 😱 in just these few lines I have automated the entire infrastructure definition and can run this.

What is even more amazing is that the Static Website implementation on Azure will add a .github workflow that automatically deploys our website to it!

Deploying Bicep Template

As a last step we have to deploy all of the code we just wrote. So execute the code below to deploy this to your Azure account:

# Login to Azure
az login

# Set Subscription
az account set --subscription <your_sub_id>

# Deploy Bicep
az deployment sub create --location westeurope --template-file ./main.bicep

Conclusion

In almost under 10 minutes you should have been able to:

  1. Deploy new Cloud Infrastructure
  2. Take code from your (private) repository
  3. Build this code
  4. Deploy the result on a static website
  5. Automate all of it through a CI/CD pipeline

Which is now powering my personal blog! 😍