azureazure-web-app-serviceazure-resource-managerazure-bicep

Is there a workaround to keep app settings which not defined in Bicep template?


main.bicep


resource appService 'Microsoft.Web/sites@2020-06-01' = {
  name: webSiteName
  location: location
  properties: {
    serverFarmId: appServicePlan.id
    siteConfig: {
      linuxFxVersion: linuxFxVersion

      appSettings: [
        {
          name: 'ContainerName'
          value: 'FancyContainer'
        }
        {
          name: 'FancyUrl'
          value: 'fancy.api.com'
        }
      ]
    }
  }
}

The infrastructure release process is run successfully, and the app settings are set correctly, after that I run the node application build and release where the Azure DevOps release pipeline adds some application-related config to app settings. (API keys, API URLs, for example) and everything works great.

But if I have to rerelease infrastructure, for example, I expand my environment with a storage account, the app settings which the application release set are lost.

Is there a workaround to keep app settings which not defined in Bicep template?


Solution

  • From this article: Merge App Settings With Bicep.

    1. Don't include appSettings inside the siteConfig while deploying.
    2. Create a module to create/update appsettings that will merge the existing settings with new settings.

    appsettings.bicep file:

    param webAppName string
    param appSettings object
    param currentAppSettings object
    
    resource webApp 'Microsoft.Web/sites@2022-03-01' existing = {
      name: webAppName
    }
    
    resource siteconfig 'Microsoft.Web/sites/config@2022-03-01' = {
      parent: webApp
      name: 'appsettings'
      properties: union(currentAppSettings, appSettings)
    }
    

    main.bicep:

    param location string = resourceGroup().location
    param webAppName string = 'thomastest-appsettings-002'
    
    // Create an app service plan
    resource plan 'Microsoft.Web/serverfarms@2023-12-01' = {
      name: '${webAppName}-asp'
      location: location
      sku: {
        name: 'F1'
      }
    }
    
    // Create the webapp without appsettings
    resource webApp 'Microsoft.Web/sites@2023-12-01' = {
      name: webAppName
      location: location
      properties: {
        httpsOnly: true
        serverFarmId: plan.id
        siteConfig: {
          ftpsState: 'Disabled'
          minTlsVersion: '1.2'
          netFrameworkVersion: 'v8.0'
          metadata: [
            {
              name: 'CURRENT_STACK'
              value: 'dotnet'
            }
          ]
          // Dont include the appSettings
        }
      }
    }
    
    // Create-Update the webapp app settings.
    module appSettings 'appsettings.bicep' = {
      name: '${webAppName}-appsettings'
      params: {
        webAppName: webApp.name
        // Get the current appsettings as an object
        currentAppSettings: list(resourceId('Microsoft.Web/sites/config', webApp.name, 'appsettings'), webApp.apiVersion).properties
        appSettings: {
          Foo: 'Bar'
        }
      }
    }