Back to Blog
DevOps
3 min read

Azure Functions with .NET Isolated Worker - Terraform Configuration

AzureFunctionsTerraform.NETIaC

Trying to deploy an Azure Function App with the latest .NET version in Terraform? You've probably hit the "unsupported value" error.

The azurerm provider often lags behind Azure's latest runtime support. Here's how to work around it.

The Problem

You want to deploy a .NET 8 (or 9, or 10) isolated worker function:

resource "azurerm_linux_function_app" "this" {
  # ...
  site_config {
    application_stack {
      dotnet_version              = "8.0"  # Error!
      use_dotnet_isolated_runtime = true
    }
  }
}

Terraform throws:

Error: expected site_config.0.application_stack.0.dotnet_version
to be one of ["3.1" "6.0" "7.0"], got "8.0"

The provider version you're using doesn't know about .NET 8 yet.

Solution 1: Update the Provider

First, try updating to the latest azurerm provider:

terraform {
  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = "~> 3.85"  # Or latest
    }
  }
}

Run terraform init -upgrade and try again. This often fixes it for recent .NET versions.

Solution 2: The azapi Provider

For bleeding-edge versions that azurerm doesn't support yet, use azapi to patch the configuration:

# First, create the function app with a supported version
resource "azurerm_linux_function_app" "this" {
  name                = "func-myapp"
  resource_group_name = azurerm_resource_group.this.name
  location            = azurerm_resource_group.this.location
  service_plan_id     = azurerm_service_plan.this.id

  storage_account_name       = azurerm_storage_account.this.name
  storage_account_access_key = azurerm_storage_account.this.primary_access_key

  site_config {
    application_stack {
      dotnet_version              = "7.0"  # Temporary
      use_dotnet_isolated_runtime = true
    }
  }
}

# Then patch it with azapi to set the actual version
resource "azapi_update_resource" "function_dotnet_version" {
  type        = "Microsoft.Web/sites@2023-01-01"
  resource_id = azurerm_linux_function_app.this.id

  body = jsonencode({
    properties = {
      siteConfig = {
        linuxFxVersion = "DOTNET-ISOLATED|8.0"
      }
    }
  })

  depends_on = [azurerm_linux_function_app.this]
}

Understanding linuxFxVersion

The linuxFxVersion string format is:

  • DOTNET|7.0 - .NET 7 in-process
  • DOTNET-ISOLATED|8.0 - .NET 8 isolated worker
  • DOTNET-ISOLATED|9.0 - .NET 9 isolated worker
  • Node|18 - Node.js 18
  • Python|3.11 - Python 3.11

For Windows function apps, use netFrameworkVersion in siteConfig instead.

The azapi Provider Setup

Add azapi to your providers:

terraform {
  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = "~> 3.80"
    }
    azapi = {
      source  = "azure/azapi"
      version = "~> 1.10"
    }
  }
}

provider "azapi" {}

Full Example: .NET 8 Isolated Function

resource "azurerm_service_plan" "this" {
  name                = "asp-myapp"
  resource_group_name = azurerm_resource_group.this.name
  location            = azurerm_resource_group.this.location
  os_type             = "Linux"
  sku_name            = "Y1"  # Consumption plan
}

resource "azurerm_linux_function_app" "this" {
  name                = "func-myapp"
  resource_group_name = azurerm_resource_group.this.name
  location            = azurerm_resource_group.this.location
  service_plan_id     = azurerm_service_plan.this.id

  storage_account_name       = azurerm_storage_account.this.name
  storage_account_access_key = azurerm_storage_account.this.primary_access_key

  site_config {
    application_stack {
      dotnet_version              = "7.0"
      use_dotnet_isolated_runtime = true
    }
  }

  app_settings = {
    "FUNCTIONS_WORKER_RUNTIME" = "dotnet-isolated"
  }

  identity {
    type = "SystemAssigned"
  }
}

resource "azapi_update_resource" "dotnet8" {
  type        = "Microsoft.Web/sites@2023-01-01"
  resource_id = azurerm_linux_function_app.this.id

  body = jsonencode({
    properties = {
      siteConfig = {
        linuxFxVersion = "DOTNET-ISOLATED|8.0"
      }
    }
  })
}

When to Use azapi

The azapi provider is useful when:

  • azurerm doesn't support a new feature yet
  • You need to set a property that azurerm doesn't expose
  • You're working with preview features

But prefer azurerm when possible - it has better state management and drift detection.

Checking Current Configuration

Verify what's actually deployed:

az functionapp config show \
  --name func-myapp \
  --resource-group rg-myapp \
  --query "linuxFxVersion"

Need help with Azure Functions or Infrastructure as Code? Get in touch - we help teams build and deploy cloud applications.

Need help with your Azure environment?

Get in touch for a free consultation.

Get in Touch