Deploy Azure Function V4 .NET 6 on Linux using Bicep

Since running Azure Functions on Linux can be cheaper than running on Windows and I had no particular need of running it on Windows, I tried deploying my Azure Function V4 built on .NET 6 via Bicep to an App Service on Linux. However this appeared to not be as straight forward as I thought it would be.

App Service Plan

First make sure you create a real Linux App Service Plan. When you don’t set all the properties correctly, it might look like you deployed a Linux App Service Plan, but in fact it is running Windows. Even in the portal the icon might show as linux, but the make sure to check the Operating System property. This should say Linux. I experienced having a linux Icon, but Windows as Operating System.

In your bicep file, describe the App Service Plan like below. Make sure to have both kind set to linux and have the property reserved set to true (also see Microsoft documentation on this: “If Linux app service plan {code}true{/code}, {code}false{/code} otherwise.”).

resource appServicePlan 'Microsoft.Web/serverfarms@2020-12-01' = {
  name: 'teching-2022-01-${environmentName}'
  location: location
  kind: 'linux'        // required for using linux
  sku: {
    name: 'Y1'
    capacity: 1
  }
  properties: {
    reserved: true     // required for using linux
  }
  tags: tags
}

Function App

Now you have to create your Function App. Here you have to set a few specific properties as well to make sure you actually deploy an Azure Function using .NET 6 and running on Linux.

Based on Microsofts documentation, you should set the following two properties:

  • kind: ‘functionapp,linux’
  • linuxFxVersion: ‘DOTNET|6.0’

However, this unfortunately didn’t always work. I encountered a couple of times the following error:

The parameter LinuxFxVersion has an invalid value.

On some blog I read you should use the value ‘DOTNETCORE|6.0’ in stead, however, that didn’t work for me.

So I ended up trying to create the function app via the Azure Portal to check the arm template it creates. Here I noticed the version of the API that the portal uses is older than the one I tried to use. I tried to use API version ‘Microsoft.Web/sites@2021-02-01’ where the portal used ‘Microsoft.Web/sites@2018-11-01’. After having changed my bicep file, to use the older version, I managed to successfully deploy the Azure Function to a Linux App Service plan. Below a simplified version of the bicep I used for the successful deployment.

resource functionApp 'Microsoft.Web/sites@2018-11-01' = {
  name: 'teching-test-2022-${environmentName}'
  location: location
  kind: 'functionapp,linux'
  identity: {
    type: 'SystemAssigned'
  }
  properties: {
    serverFarmId: appServicePlan.id
    httpsOnly: true
    siteConfig: {
      linuxFxVersion: 'DOTNET|6.0'
      appSettings: [
        {
          name: 'AzureWebJobsStorage__accountName'
          value: storageAccount.name
        }
        {
          name: 'FUNCTIONS_EXTENSION_VERSION'
          value: '~4'
        }
        {
          name: 'APPINSIGHTS_INSTRUMENTATIONKEY'
          value: appInsightsComponents.properties.InstrumentationKey
        }
        {
          name: 'FUNCTIONS_WORKER_RUNTIME'
          value: 'dotnet'
        }
      ]
    }
  }
}

I hope this helps!