Azure Functions on Container Apps — the native kind=functionapp model, the legacy Microsoft.Web model, scaling, identity and limits

Hosting a containerized function app in a Container Apps environment — the recommended V2 model (a Microsoft.App container app with kind functionapp) versus the legacy V1 Microsoft.Web proxy, Bicep with identity-based AzureWebJobsStorage and ACR pull, which triggers scale from zero (Durable only with MSSQL or the Durable Task Scheduler), ingress and storage requirements, multi-revision cautions, and what isn't supported (slots, proxies, portal keys).

markdownreferencev1JR0F-RJ74stage: designtrust: officialservice: functionsinterface: iacinterface: cliAzure Functions on Azure Container Appskind functionappcontainerapp create kind functionappFunctions on Container Apps V1 legacyFunctions on Container Apps V2Microsoft.App/containerApps functionappmigrate Functions on Container AppsallowScalingRuleOverrideKEDA scale rules FunctionsAdd scale rules disabledAzureWebJobsStorage Container Appsdeployment slots not available Container AppsFunctions proxies not supportedFunctions access keys portal Container AppsWEBSITES_PORTappservice-kube extension conflictFunctionsScalerError

Created 21 Oct 2026 · Modified 23 Oct 2026 · 1 version

Azure Functions on Container Apps

Two models; use the native one

V2, native (recommended)V1, legacy
ResourceOne Microsoft.App/containerApps with kind: functionappA Microsoft.Web/sites function app proxying a hidden container app
Createaz containerapp create with --kind functionapp (a flag from the containerapp CLI extension; core CLI 2.91 lacks it), or Bicep belowaz functionapp create --environment <env> --image …
Container Apps features (revisions, secrets, probes, custom domains, sidecars)YesNo
Future features (function listing, keys, invocation counts)PlannedNot planned

A plain container app running a Functions image without kind: functionapp is unsupported: no automatic scale rules. Migrating V1 to V2 needs no code change; redeploy the same image as a V2 app. Both models need a Linux container image you build and push (func init --docker writes the Dockerfile); code changes mean a new image.

Bicep

// Azure Functions on Container Apps (V2, native): a container app with kind 'functionapp'
param location string = resourceGroup().location
param environmentId string
param image string
param identityId string
param storageAccountName string
param identityClientId string

resource fn 'Microsoft.App/containerApps@2026-07-01' = {
  name: 'func-orders'
  location: location
  kind: 'functionapp'
  identity: {
    type: 'UserAssigned'
    userAssignedIdentities: { '${identityId}': {} }
  }
  properties: {
    environmentId: environmentId
    configuration: {
      ingress: { external: true, targetPort: 80 }
      registries: [ { server: split(image, '/')[0], identity: identityId } ]
    }
    template: {
      containers: [
        {
          name: 'func'
          image: image
          env: [
            { name: 'AzureWebJobsStorage__accountName', value: storageAccountName }
            { name: 'AzureWebJobsStorage__credential', value: 'managedidentity' }
            { name: 'AzureWebJobsStorage__clientId', value: identityClientId }
          ]
        }
      ]
      scale: { minReplicas: 0, maxReplicas: 10 }
    }
  }
}

The identity needs AcrPull on the registry and the storage roles for the Functions host (reference/functions/hosting-and-host-storage.md). Microsoft's own walkthrough passes a storage connection string; identity-based AzureWebJobsStorage__* settings avoid the key.

Scaling

The platform writes the KEDA rules from your triggers, so the portal's Add scale rules is disabled; opt out with allowScalingRuleOverride to write your own. Scale events log as FunctionsScalerInfo / FunctionsScalerError in Log Analytics. Up to 1,000 replicas (default maximum 10), scale to zero.

  • Ingress must be enabled (external or internal) for event-driven scaling.
  • Blob triggers scale only with the Event Grid source. Durable Functions scale only with the MSSQL or Durable Task Scheduler backend (reference/functions/durable-functions.md). Azure Cache for Redis and Azure SQL triggers don't autoscale: set fixed replicas.

Requirements and gaps

  • A storage account is mandatory. With several active revisions, give each revision its own storage account and, for pull triggers (Queue, Event Hubs, Service Bus, Durable), its own event source, or revisions compete for messages.
  • No deployment slots (use revisions and traffic splitting), no Functions proxies (use API Management), and no portal-generated function keys: use Easy Auth, internal ingress, a VNet, or API Management.
  • Scale-from-zero means cold starts. Environment CPU, memory and replica quotas apply (reference/container-apps/apps-ingress-and-scale.md).
  • Legacy model only: the app listens on port 80 unless WEBSITES_PORT says otherwise; it can't move between resource groups or subscriptions; and the CLI containerapp extension conflicts with appservice-kube (remove it).

Read this document as markdown — the same bytes an agent receives.