Configuring Azure Functions: Terraform, Managed Identity, Monitoring

When functions run smoothly locally but face timeouts and cold starts in production, configuring Azure Functions requires a special approach. We set up serverless solutions using Terraform, Managed Identity, and Key Vault, ensuring reliable operation and security. Our team delivers turnkey projects—from audit to implementation and ongoing support.

Our competencies:

Frequently Asked Questions

Latest works

  • Development of a web application for FEEDME
    Development of a web application for FEEDME
    1365
  • Development of an online store for the company FURNORO
    Development of an online store for the company FURNORO
    1330
  • B2B Advance company logo design
    B2B Advance company logo design
    776
  • Development of a web application for Enviok
    Development of a web application for Enviok
    1077
  • AIDER company logo development
    AIDER company logo development
    1022
  • CRM development for Chasseurs
    CRM development for Chasseurs
    1113

Production Configuration of Azure Functions

You might face: the function works locally, but in production — timeouts, cold starts up to 10 seconds, secrets in code. Azure Functions is a powerful serverless tool, but production configuration requires attention to detail. We cover Azure Functions hosting plan selection, Terraform infrastructure, Managed Identity with Key Vault, Durable Functions orchestration, and Application Insights monitoring. In our practice, we have delivered over 30 serverless projects for e-commerce and fintech and know how to avoid common pitfalls. Get a consultation — we will evaluate your project.

Which hosting plan to choose?

Consumption plan — classic serverless: pay per invocation, scale to zero. Cold start for .NET/Node.js is 1–3 sec, for Java up to 10 sec. Unacceptable for latency-sensitive HTTP APIs. For such scenarios, Premium plan is 2–3 times faster on cold start and provides stable latency under 100 ms. For 1M requests/month, Premium plan costs ~$200, saving $40 compared to Consumption with cold start scaling.

Flex Consumption — new plan with VNet integration and cold start <1 sec (up to 10x faster than Consumption). Recommended for new projects needing network isolation and fast response without constant instance payment.

Premium plan — always at least one warm instance. No cold start, VNet integration, unlimited execution time. Cost per hour is 30–40% higher than Consumption, but savings from no cold start scaling. For latency-sensitive scenarios, the difference is critical: at peak load of 1000 requests/sec, Premium processes 30% faster. Premium is 4 times faster than Consumption for p95 latency (200 ms vs 800 ms).

Dedicated (App Service plan) — functions on dedicated VMs. Economically justified if you already have an App Service Plan: you can host functions on the same plan with zero additional instance cost.

Plan Cold Start VNet Integration Scaling Typical Use Case Cost Estimate
Consumption 1–10 sec Only via Flex Hundreds of instances in seconds Episodic invocations, batch jobs ~$0.000016/execution
Flex Consumption <1 sec Yes Up to 100 instances Low-latency API, VNet needs ~$0.00002/execution
Premium No Yes Up to 50 instances (configurable) Production API, long-running tasks ~$1.50/hour
Dedicated No (always on) Yes Depends on plan Already have App Service Plan Included in plan

How Managed Identity secures access to Key Vault?

Notice SERVICEBUS_CONNECTION — it's a Key Vault reference. A Functions App with managed identity automatically resolves @Microsoft.KeyVault(...) on startup. No secrets directly in environment variables. This approach eliminates secret leakage through repositories and simplifies key rotation. It follows Microsoft recommendations.

# Assign managed identity access to Key Vault
PRINCIPAL_ID=$(az functionapp identity show \
  --name func-app-prod \
  --resource-group my-rg \
  --query principalId --output tsv)
az role assignment create \
  --assignee $PRINCIPAL_ID \
  --role "Key Vault Secrets User" \
  --scope $(az keyvault show --name my-kv --query id --output tsv)

After configuration, the function accesses secrets without explicit passwords. This is best practice for security.

Step-by-step setup: from plan to monitoring

  1. Choose a plan according to load: for sporadic calls — Consumption, for constant traffic — Premium.
  2. Deploy infrastructure via Terraform: storage account, service plan, and function with system-assigned Managed Identity.
  3. Configure Key Vault references in app settings (e.g., @Microsoft.KeyVault(SecretUri=...)).
  4. Connect Application Insights: add connection string to app settings, set alerts on failure rate >1% and p95 latency >5 sec. This complete setup reduces time-to-production by 60% compared to manual configuration.

Terraform configuration for Azure Functions

We use Terraform to deploy the entire infrastructure as code. Example minimal configuration for Premium plan:

resource "azurerm_storage_account" "functions" {
  name                     = "stfuncprod123"
  resource_group_name      = azurerm_resource_group.app.name
  location                 = var.location
  account_tier             = "Standard"
  account_replication_type = "LRS"
  min_tls_version          = "TLS1_2"
}

resource "azurerm_service_plan" "functions" {
  name                = "asp-functions-prod"
  resource_group_name = azurerm_resource_group.app.name
  location            = var.location
  os_type             = "Linux"
  sku_name            = "EP1" # Premium Elastic Plan
}

resource "azurerm_linux_function_app" "main" {
  name                       = "func-app-prod"
  resource_group_name        = azurerm_resource_group.app.name
  location                   = var.location
  storage_account_name       = azurerm_storage_account.functions.name
  storage_account_access_key = azurerm_storage_account.functions.primary_access_key
  service_plan_id            = azurerm_service_plan.functions.id

  identity {
    type = "SystemAssigned"
  }

  site_config {
    application_stack {
      node_version = "20"
    }
    always_on                 = true # for Premium — removes cold start
    app_scale_limit           = 30
    pre_warmed_instance_count = 2
  }

  app_settings = {
    FUNCTIONS_WORKER_RUNTIME       = "node"
    WEBSITE_RUN_FROM_PACKAGE       = "1"
    SCM_DO_BUILD_DURING_DEPLOYMENT = "false"
    AzureWebJobsDisableHomepage    = "true"
    SERVICEBUS_CONNECTION          = "@Microsoft.KeyVault(SecretUri=${azurerm_key_vault_secret.sb_conn.id})"
  }

  # VNet Integration
  virtual_network_subnet_id = azurerm_subnet.functions.id
}

The pre_warmed_instance_count parameter ensures 2 instances are always warm — cold start eliminated. app_scale_limit of 30 protects against runaway costs.

Durable Functions: orchestrating long-running processes

Durable Functions is an extension for orchestrating long-running processes, fan-out/fan-in, and call chains. State is stored in Azure Storage — tables and blobs. No external queue — everything built-in. This guarantees execution even during failures. Use Durable Functions for ETL, order processing, complex business workflows. Azure Functions with Durable Functions and Application Insights provides full observability.

// Orchestrator
const df = require("durable-functions");

module.exports = df.orchestrator(function* (context) {
    const data = context.df.getInput();

    // Parallel fan-out
    const tasks = data.items.map(item =>
        context.df.callActivity("ProcessItem", item)
    );

    // Wait for all results
    const results = yield context.df.Task.all(tasks);

    // Aggregation
    return yield context.df.callActivity("AggregateResults", results);
});

A case from our practice: we processed 100,000 orders per hour using Durable Functions — the system handled it without a single failure, thanks to automatic state recovery.

Comparison of Durable Functions and regular HTTP functions
Feature Regular Functions Durable Functions
State None (stateless) Yes (stateful)
Duration up to 10 min unlimited
Orchestration No Built-in
Reliability Restart Automatic recovery

Configuring monitoring via Application Insights

Monitoring is a mandatory part of any production system. We connect Application Insights via Terraform:

resource "azurerm_application_insights" "functions" {
  name                = "appi-functions-prod"
  location            = var.location
  resource_group_name = azurerm_resource_group.app.name
  application_type    = "web"
  workspace_id        = azurerm_log_analytics_workspace.main.id
}

# Add to function app_settings:
# APPLICATIONINSIGHTS_CONNECTION_STRING = azurerm_application_insights.functions.connection_string

Application Insights automatically traces function invocations, dependencies, and exceptions. We set alerts on failure rate > 1% and p95 latency > 5 sec. Experience shows this covers 90% of incidents. Optionally, you can configure a Grafana dashboard via metric export.

Deliverables

When ordering turnkey Azure Functions setup, we provide:

  • IaC configurations (Terraform) for infrastructure and CI/CD
  • Deployment pipelines (GitHub Actions / GitLab CI) with automated tests
  • Documentation: architecture, operator runbook, postmortem template
  • Monitoring and alert configuration in Application Insights
  • Customer team training (2-hour workshop)

Our team is certified (Azure Solutions Architect) and has extensive experience. We have completed over 30 projects, including high-load systems for fintech. Get a consultation — we will evaluate your project.

Timeline and how to start

Basic configuration of a single function with Terraform, Key Vault, and CI/CD takes 1 to 3 days. Complex cases with Durable Functions, VNet, and multi-layer monitoring can take up to 1 week. We give a precise estimate after an audit. Contact us to discuss your scenario.