Production Azure Functions deployment involves automated pipelines, secret management, and zero-downtime updates.

Create Production Resources

  az group create --name my-rg --location eastus

az storage account create \
    --name mystorageacct --resource-group my-rg \
    --sku Standard_LRS

az functionapp plan create \
    --name my-plan --resource-group my-rg \
    --location eastus --sku EP1 --min-instances 1

az functionapp create \
    --name my-function-app --resource-group my-rg \
    --plan my-plan --storage-account mystorageacct \
    --runtime python --runtime-version 3.12 \
    --functions-version 4
  

Application Settings

  az functionapp config appsettings set \
    --name my-function-app --resource-group my-rg \
    --settings \
        ENV=production \
        LOG_LEVEL=INFO \
        FUNCTIONS_WORKER_RUNTIME=python
  

Key Vault Integration

  # Create Key Vault
az keyvault create --name my-keyvault --resource-group my-rg --location eastus

# Store secret
az keyvault secret set --vault-name my-keyvault --name "ApiKey" --value "secret-value"

# Enable managed identity on function app
az functionapp identity assign \
    --name my-function-app --resource-group my-rg

# Grant access
az keyvault set-policy --name my-keyvault \
    --object-id <managed-identity-id> \
    --secret-permissions get

# Reference in app settings
az functionapp config appsettings set \
    --name my-function-app --resource-group my-rg \
    --settings ApiKey="@Microsoft.KeyVault(VaultName=my-keyvault;SecretName=ApiKey)"
  

Access in Python:

  import os
api_key = os.environ["ApiKey"]  # resolved from Key Vault at runtime
  

GitHub Actions Deployment

  # .github/workflows/deploy.yml
name: Deploy Azure Function

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-python@v5
        with:
          python-version: "3.12"

      - run: pip install -r requirements.txt pytest
      - run: pytest tests/ -v

      - uses: Azure/functions-action@v1
        with:
          app-name: my-function-app
          package: .
          publish-profile: ${{ secrets.AZURE_FUNCTIONAPP_PUBLISH_PROFILE }}
  

Get publish profile: Azure Portal → Function App → Get publish profile.

Deployment Slots

  # Create staging slot
az functionapp deployment slot create \
    --name my-function-app --resource-group my-rg --slot staging

# Deploy to staging
func azure functionapp publish my-function-app --slot staging

# Swap to production (zero downtime)
az functionapp deployment slot swap \
    --name my-function-app --resource-group my-rg \
    --slot staging --target-slot production
  

Application Insights

  az monitor app-insights component create \
    --app my-app-insights --resource-group my-rg --location eastus

az functionapp config appsettings set \
    --name my-function-app --resource-group my-rg \
    --settings APPINSIGHTS_INSTRUMENTATIONKEY=<key>
  

Query failures in Application Insights:

  exceptions
| where timestamp > ago(24h)
| summarize count() by type, outerMessage
| order by count_ desc
  

Custom Domain & TLS

  az functionapp config hostname add \
    --webapp-name my-function-app --resource-group my-rg \
    --hostname api.example.com

az functionapp config ssl bind \
    --name my-function-app --resource-group my-rg \
    --certificate-thumbprint <thumbprint> --ssl-type SNI
  

Health Monitoring

Add a health endpoint:

  @app.route(route="health", auth_level=func.AuthLevel.ANONYMOUS)
def health(req: func.HttpRequest) -> func.HttpResponse:
    return func.HttpResponse('{"status": "ok"}', mimetype="application/json")
  

Configure Azure Monitor availability test to ping /api/health every 5 minutes.

Azure Functions integrate with the full Azure ecosystem for enterprise-grade deployments.