I was preparing a talk called Azure Static Web Apps and the Api Multiverse in which I wanted to hook up external apis instead of the managed functions. The first thing I wanted to do is have a front-end that I could deploy that calls some kind of api on the backend. I did not want to create the Static Web App ’the magic way’ but I wanted to start with IaC, so for this I created a bicep file.

param location string = resourceGroup().location

resource swamv_ui 'Microsoft.Web/staticSites@2022-03-01' = {
  name: 'swamv'
  location: location
  sku: {
    name: 'Standard'
    tier: 'Standard'
  }
  properties: {
    stagingEnvironmentPolicy: 'Enabled'
    allowConfigFileUpdates: true
    provider: 'Custom'
    enterpriseGradeCdnStatus: 'Disabled'
  }
}

Build and deploy

Next up I created a simple WASM Blazor app from the template and started a build/deployment pipeline. In this pipeline the code is built and the Azure CLI is used to create the resource using Bicep. Now for publishing the app to the Static Web App resource, a way to do a push deployment is using the SWA cli. This publish command needs a deployment token, you could save it to some secret variable in the pipeline but I decided to just query it because we have de Azure CLI here anyway.

trigger:
- main

pool:
  vmImage: ubuntu-latest

steps:
- script: |
    cd swamv-ui
    dotnet publish -o bin/publish    
  displayName: 'build blazor app'

- task: AzureCLI@2
  displayName: 'Create SWA (IaC)'
  inputs:
    azureSubscription: 'REDACTED'
    scriptType: 'pscore'
    scriptLocation: 'inlineScript'
    inlineScript: |
      az deployment group create -g swamv-rg -f swamv.bicep      

- task: AzureCLI@2
  displayName: 'Deploy Blazor app to SWA'
  inputs:
    azureSubscription: 'REDACTED'
    scriptType: 'pscore'
    scriptLocation: 'inlineScript'
    inlineScript: |
      npm install -g @azure/static-web-apps-cli
      $token = az staticwebapp secrets list --name swamv --query "properties.apiKey"
      swa deploy -d $token -a ./swamv-ui/bin/publish/wwwroot/ --env production      

Linking an api with Bicep

I wanted to hook up multiple apis in the demo I’m doing, the first one is a simple Azure Function. In the Azure Portal you can just link a backend by clicking a button and choosing your backend from a dropdown. If you want to define the link in Bicep it is its own resource. You need three components, the Static WebApp which we already created, a resource (reference) to the backend you want to connect and you describe the link resource itself.


resource swamv_backend_azure_functions 'Microsoft.Web/sites@2021-03-01' existing = {
  name: 'funcapiapp'
  scope: resourceGroup('functions-api-app-rg')
}

resource swamv_ui_backend_functions 'Microsoft.Web/staticSites/linkedBackends@2022-03-01' = {
  parent: swamv_ui
  name: 'swamv_backend_functions'
  
  properties: {
    backendResourceId: swamv_backend_azure_functions.id
    region: 'westeurope'
  }
}

Linking an api to an other Environment

But in my talk I wanted to show multiple different backends, I found out if you redefine the link it seems that Azure will not allow you to deploy it because it is trying to add multiple backends.

I decided to use different environments (which basically are staging slots) for the other backends, I was a bit confused because the linked backend resource did not have any field in there where you can specify the Environment.

But wait! I did not specify any environment in the Bicep, I just published directly using the SWA cli and it auto created them. As it turns out the environments are sub resources and called ‘Builds’ because of ‘history’ and naming is hard?


resource swamv_backend_appservice 'Microsoft.Web/sites@2022-03-01' existing = {
  name: 'swamv-appservice-api'
  scope: resourceGroup('swamv-appservice-api')
}

resource swamv_ui_environment_appservice 'Microsoft.Web/staticSites/builds@2022-03-01' existing = {
  parent: swamv_ui
  name: 'appservice'
}

resource swamv_ui_linkedbackend_appservice 'Microsoft.Web/staticSites/builds/linkedBackends@2022-03-01' = {
  name: 'swamv_backend_appservice'
  parent: swamv_ui_environment_appservice
  properties: {
    backendResourceId: swamv_backend_appservice.id
    region: 'westeurope'
  }
}

In this last part you can see that the bicep is referencing an exsiting app service resource called swamv-appservice-api, in this case it is using an existing environment resource (build) called appservice and it is creating a link between the two in the defined resource called swamv_ui_linkedbackend_appservice.

oscarvantol.nl