Search code examples
azureazure-web-app-serviceazure-resource-managerappsettings

Dynamic appsettings array content in ARM


I have the following simplified ARM template (I left out certain parts to make it more readable). I have a parameter called PrivateKeyCertificateThumbprint. If this parameter is filled in, I want to set the appsetting WEBSITE_LOAD_CERTIFICATES to a certain value. If the parameter is empty, I do not want to set the value. So the elements in the appSettings array are sort of dynamic based on the content of the PrivateKeyCertificateThumbprint parameter.

I do not seem to find a solution for this in ARM. The usecase seems so simple. First I tried to add an additional Microsoft.Web/sites/config/appsettings resource with only the WEBSITE_LOAD_CERTIFICATES key. But doing that removes all the already existing appsettings from the application.

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    ...
    "PrivateKeyCertificateThumbprint": {
      "type": "string",
      "defaultValue": "",
      "metadata": {
        "description": "The thumbprint of the client certificate used by the application"
      }
    }
  },
  "resources": [
    {
      "type": "Microsoft.Web/sites",
      "apiVersion": "2018-11-01",
      "name": "[parameters('AppResourcename')]",
      "identity": {
        "type": "SystemAssigned"
      },
      "Location": "[parameters('Location')]",
      "kind": "[parameters('SitesKind')]",
      "properties": {
        "siteConfig": {
          "appSettings": [
              {
                "name": "APPINSIGHTS_INSTRUMENTATIONKEY",
                "value": "[if(empty(parameters('AppinsResourceName')), '', reference(resourceId('microsoft.insights/components/', parameters('AppinsResourceName')), '2015-05-01').InstrumentationKey)]"
              },
              {
                "name": "ApplicationInsightsAgent_EXTENSION_VERSION",
                "value": "~2"
              },
              {
                "name": "WEBSITE_HEALTHCHECK_MAXPINGFAILURES",
                "value": "5"
              },
              {
                "name": "WEBSITE_LOAD_CERTIFICATES",
                "value": "[parameters('PrivateKeyCertificateThumbprint')]"
              }
          ],
          "healthCheckPath": "[parameters('HealthCheckPath')]"
        }
        ...
    }
  ]
}

Solution

  • For clarity, I used a bicep template.
    Here I've defined a variable with default appsettings. Then if the cert thumbprint is not empty, I'm adding the extra app setting:

    param PrivateKeyCertificateThumbprint string = ''
    param AppResourcename string
    param Location string
    param SitesKind string
    param AppinsResourceName string
    
    // Common app settings
    var defaultAppSettings = [
      {
        name: 'APPINSIGHTS_INSTRUMENTATIONKEY'
        value: (empty(AppinsResourceName) ? '' : reference(resourceId('microsoft.insights/components/', AppinsResourceName), '2015-05-01').InstrumentationKey)
      }
      {
        name: 'ApplicationInsightsAgent_EXTENSION_VERSION'
        value: '~2'
      }
      {
        name: 'WEBSITE_HEALTHCHECK_MAXPINGFAILURES'
        value: '5'
      }
    ]
    
    // if the cert thumbprint is not empty, we add it.
    var appSettings = concat(defaultAppSettings, empty(PrivateKeyCertificateThumbprint) ? [] : [
      {
        name: 'WEBSITE_LOAD_CERTIFICATES'
        value: PrivateKeyCertificateThumbprint
      }
    ])
    
    // create the webapp
    resource webApp 'Microsoft.Web/sites@2018-11-01' = {
      name: AppResourcename
      identity: {
        type: 'SystemAssigned'
      }
      location: Location
      kind: SitesKind
      properties: {
        siteConfig: {
          appSettings: appSettings
        }
      }
    }
    
    

    Using Az CLI, you can then generate the ARM temnplate:

    az bicep build --file .\main.bicep
    

    the generated ARM template looks like that:

    {
      "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
      "contentVersion": "1.0.0.0",
      "parameters": {
        "PrivateKeyCertificateThumbprint": {
          "type": "string",
          "defaultValue": ""
        },
        "AppResourcename": {
          "type": "string"
        },
        "Location": {
          "type": "string"
        },
        "SitesKind": {
          "type": "string"
        },
        "AppinsResourceName": {
          "type": "string"
        }
      },
      "resources": [
        {
          "type": "Microsoft.Web/sites",
          "apiVersion": "2018-11-01",
          "name": "[parameters('AppResourcename')]",
          "identity": {
            "type": "SystemAssigned"
          },
          "location": "[parameters('Location')]",
          "kind": "[parameters('SitesKind')]",
          "properties": {
            "siteConfig": {
              "appSettings": "[concat(createArray(createObject('name', 'APPINSIGHTS_INSTRUMENTATIONKEY', 'value', if(empty(parameters('AppinsResourceName')), '', reference(resourceId('microsoft.insights/components/', parameters('AppinsResourceName')), '2015-05-01').InstrumentationKey)), createObject('name', 'ApplicationInsightsAgent_EXTENSION_VERSION', 'value', '~2'), createObject('name', 'WEBSITE_HEALTHCHECK_MAXPINGFAILURES', 'value', '5')), if(empty(parameters('PrivateKeyCertificateThumbprint')), createArray(), createArray(createObject('name', 'WEBSITE_LOAD_CERTIFICATES', 'value', parameters('PrivateKeyCertificateThumbprint')))))]"
            }
          }
        }
      ]
    }