Skip to content

02 - First Deploy (Flex Consumption)

Deploy the app to Azure Functions Flex Consumption (FC1) using long-form CLI commands only.

Prerequisites

Tool Version Purpose
Python 3.11+ Local runtime
Azure Functions Core Tools v4 Local host and publishing
Azure CLI 2.61+ Azure resource provisioning and management
Azure subscription Active Target for deployment

Flex Consumption plan basics

Flex Consumption (FC1) supports VNet integration, identity-based storage, per-function scaling, and remote build workflows.

What You'll Build

You will provision a Linux Function App on the Flex Consumption plan, publish your Python v2 app, and validate trigger discovery.

Network Scenario Choices

This tutorial deploys with public networking. FC1 supports VNet integration and private endpoints:

Scenario Description Guide
Public Only No VNet (this tutorial) Current page
Private Egress VNet + Storage PE Private Egress
Private Ingress + Site Private Endpoint Private Ingress
Fixed Outbound IP + NAT Gateway Fixed Outbound

Looking for a private egress deployment (VNet + Storage PE)? See 02 - First Deploy (Private Egress).

Infrastructure Context

Plan: Flex Consumption (FC1) | Network: VNet integration supported | Storage auth: SystemAssigned MI

Flex Consumption uses blob-based deployment storage with managed identity authentication, unlike Consumption which uses Azure Files with connection strings.

flowchart TD
    INET[Internet] -->|HTTPS| FA[Function App\nFlex Consumption FC1\nLinux Python 3.11]

    FA -->|"SystemAssigned MI"| ST[Storage Account\nBlob deployment]
    FA --> AI[Application Insights]

    subgraph STORAGE[Storage Services]
        ST --- DEPLOY["Blob Container\napp-package"]
    end

    style FA fill:#0078d4,color:#fff
    style STORAGE fill:#FFF3E0
flowchart TD
    A[Set variables + login] --> B[Create RG + storage]
    B --> C[Create deployment container]
    C --> D[Create function app]
    D --> E[Assign Storage Blob Data Contributor]
    E --> F[Wait for role propagation]
    F --> G[Set placeholder settings]
    G --> H["func azure functionapp publish"]
    H --> I[Validate endpoints]

Steps

Step 1 - Set variables and sign in

export RG="rg-func-python-flex-demo"
export APP_NAME="func-pyflex-$(date +%m%d%H%M)"
export STORAGE_NAME="stpyflex$(date +%m%d)"
export LOCATION="koreacentral"

az login
az account set --subscription "<subscription-id>"
Command/Parameter Purpose
export RG="rg-func-python-flex-demo" Sets the resource group name for the deployment.
export APP_NAME="..." Defines a globally unique name for the Function App using a timestamp.
export STORAGE_NAME="..." Sets a unique name for the storage account.
export LOCATION="koreacentral" Chooses the Azure region for the deployment.
az login Authenticates your CLI session with Azure.
az account set --subscription Targets the specific Azure subscription for resource creation.

Step 2 - Create resource group and storage account

az group create --name "$RG" --location "$LOCATION"

az storage account create \
  --name "$STORAGE_NAME" \
  --resource-group "$RG" \
  --location "$LOCATION" \
  --sku Standard_LRS \
  --kind StorageV2
Command/Parameter Purpose
az group create Provisions a new Azure resource group container.
--name "$RG" Specifies the resource group name.
--location "$LOCATION" Sets the geographical region for the group.
az storage account create Provisions a new Azure Storage account.
--sku Standard_LRS Selects locally-redundant storage for cost-efficiency.
--kind StorageV2 Uses the general-purpose v2 storage account type.

Step 3 - Create the deployment container

az storage container create \
  --name app-package \
  --account-name "$STORAGE_NAME" \
  --auth-mode login
Command/Parameter Purpose
az storage container create Creates a new blob container within the storage account.
--name app-package Names the container that will store deployment zip files.
--auth-mode login Uses your Entra ID credentials instead of a connection string.

Container must exist before function app creation

Flex Consumption requires a pre-existing blob container for deployment packages. If the container does not exist, az functionapp create fails with a ContainerNotFound error.

Step 4 - Create function app

az functionapp create \
  --name "$APP_NAME" \
  --resource-group "$RG" \
  --storage-account "$STORAGE_NAME" \
  --runtime python \
  --runtime-version 3.11 \
  --functions-version 4 \
  --flexconsumption-location "$LOCATION" \
  --deployment-storage-name "$STORAGE_NAME" \
  --deployment-storage-container-name app-package \
  --deployment-storage-auth-type SystemAssignedIdentity
Command/Parameter Purpose
az functionapp create Provisions the core Function App resource.
--runtime python Selects the Python execution environment.
--runtime-version 3.11 Pins the Python version to 3.11.
--functions-version 4 Uses version 4 of the Azure Functions runtime host.
--flexconsumption-location Specifies the region for the Flex Consumption plan.
--deployment-storage-name Links the app to the deployment storage account.
--deployment-storage-container-name Targets the specific container for package storage.
--deployment-storage-auth-type Uses Managed Identity for secure access to deployment blobs.

Flex Consumption vs Consumption CLI differences

Flex Consumption uses --flexconsumption-location instead of --consumption-plan-location. It also requires --deployment-storage-name, --deployment-storage-container-name, and --deployment-storage-auth-type parameters.

Step 5 - Assign Storage Blob Data Contributor role

The managed identity needs explicit permission to upload deployment packages to blob storage:

PRINCIPAL_ID=$(az functionapp identity show \
  --name "$APP_NAME" \
  --resource-group "$RG" \
  --query principalId \
  --output tsv)

STORAGE_ID=$(az storage account show \
  --name "$STORAGE_NAME" \
  --resource-group "$RG" \
  --query id \
  --output tsv)

az role assignment create \
  --assignee "$PRINCIPAL_ID" \
  --role "Storage Blob Data Contributor" \
  --scope "$STORAGE_ID"

# Wait for role assignment propagation (30-60 seconds)
echo "Waiting for role assignment propagation..."
sleep 60
Command/Parameter Purpose
az functionapp identity show Retrieves the principal ID of the function app's managed identity.
az storage account show Retrieves the Azure resource ID of the deployment storage account.
az role assignment create Grants the function app permission to upload deployment packages to blob storage.
sleep 60 Waits for Azure RBAC propagation before attempting the first publish.

Wait before publishing

If you run func azure functionapp publish immediately after the role assignment, the deployment can fail with a blob storage 403 error while RBAC changes are still propagating. Wait 30-60 seconds first.

Step 6 - Set placeholder trigger settings

STORAGE_CONN=$(az storage account show-connection-string \
  --name "$STORAGE_NAME" \
  --resource-group "$RG" \
  --output tsv)

az functionapp config appsettings set \
  --name "$APP_NAME" \
  --resource-group "$RG" \
  --settings \
    "QueueStorage=$STORAGE_CONN" \
    "TIMER_LAB_SCHEDULE=0 */5 * * * *"
Command/Parameter Purpose
az storage account show-connection-string Retrieves the full connection string for the storage account.
az functionapp config appsettings set Updates the application settings for the Function App.
--settings Defines the key-value pairs required by the function triggers.

Placeholder settings prevent host errors

The Python v2 reference app includes triggers for Queue and Timer. If these connection settings are missing, the Functions host enters an Error state and cannot index any functions.

Step 7 - Publish app

cd apps/python && func azure functionapp publish "$APP_NAME"
Command/Parameter Purpose
cd apps/python Moves the terminal into the source code directory.
func azure functionapp publish Bundles, uploads, and triggers a remote build for the app.

Upload size

Python function apps are typically smaller than Node.js (~6.5 MB vs ~49 MB) as dependencies are installed remotely.

Step 8 - Validate deployment

# List deployed functions
az functionapp function list \
  --name "$APP_NAME" \
  --resource-group "$RG" \
  --output table

# Test the health endpoint
curl --request GET "https://$APP_NAME.azurewebsites.net/api/health"

# Test the hello endpoint
curl --request GET "https://$APP_NAME.azurewebsites.net/api/hello/FlexTest"
Command/Parameter Purpose
az functionapp function list Queries ARM to retrieve the list of indexed functions.
--output table Formats the function list as a readable text table.
curl --request GET Sends an HTTP GET request to verify the live endpoints.

Step 9 - Review Flex Consumption-specific notes

  • Flex Consumption routes all traffic through the integrated VNet by default once configured.
  • Flex Consumption does not support custom container hosting for Function Apps.
  • Use long-form CLI flags for maintainable runbooks.

Verification

Function list output (showing key fields):

[
  {
    "name": "helloHttp",
    "type": "Microsoft.Web/sites/functions",
    "invokeUrlTemplate": "https://<app-name>.azurewebsites.net/api/hello/{name?}",
    "language": "python",
    "isDisabled": false
  }
]

Health endpoint response:

{"status":"healthy","timestamp":"2026-04-11T10:00:00.000Z","version":"1.0.0"}

Hello endpoint response:

{"message":"Hello, FlexTest"}

Next Steps

Next: 03 - Configuration

See Also

Sources