Background
Sections
IntroductionFoundations1. Resource Hierarchy2. Resource Manager3. Identity and RBAC4. Regions and Availability5. Naming and TaggingVirtual Machines1. What and Why2. Core Concepts3. Architecture4. Getting Started5. Deployment6. Integrations7. Production8. Interview Questions9. Glossary and CheatsheetVirtual Network1. What and Why2. Core Concepts3. Architecture4. Getting Started5. Deployment6. Integrations7. Production8. Interview Questions9. Glossary and CheatsheetBlob Storage1. What and Why2. Core Concepts3. Architecture4. Getting Started5. Deployment6. Integrations7. Production8. Interview Questions9. Glossary and CheatsheetAzure SQL Database1. What and Why2. Core Concepts3. Architecture4. Getting Started5. Deployment6. Integrations7. Production8. Interview Questions9. Glossary and CheatsheetAzure Kubernetes Service1. What and Why2. Core Concepts3. Architecture4. Getting Started5. Deployment6. Integrations7. Production8. Interview Questions9. Glossary and CheatsheetAzure Container Registry1. What and Why2. Core Concepts3. Architecture4. Getting Started5. Deployment6. Integrations7. Production8. Interview Questions9. Glossary and CheatsheetMicrosoft Entra ID1. What and Why2. Core Concepts3. Architecture4. Getting Started5. Deployment6. Integrations7. Production8. Interview Questions9. Glossary and CheatsheetAzure RBAC1. What and Why2. Core Concepts3. Architecture4. Getting Started5. Deployment6. Integrations7. Production8. Interview Questions9. Glossary and CheatsheetAzure Functions1. What and Why2. Core Concepts3. Architecture4. Getting Started5. Deployment6. Integrations7. Production8. Interview Questions9. Glossary and CheatsheetAPI Management1. What and Why2. Core Concepts3. Architecture4. Getting Started5. Deployment6. Integrations7. Production8. Interview Questions9. Glossary and CheatsheetAzure App Configuration1. What and Why2. Core Concepts3. Architecture4. Getting Started5. Deployment6. Integrations7. Production8. Interview Questions9. Glossary and CheatsheetAzure Machine Learning1. What and Why2. Core Concepts3. Architecture4. Getting Started5. Deployment6. Integrations7. Production8. Interview Questions9. Glossary and CheatsheetAzure Monitor1. What and Why2. Core Concepts3. Architecture4. Getting Started5. Deployment6. Integrations7. Production8. Interview Questions9. Glossary and CheatsheetAzure AI Foundry1. What and Why2. Core Concepts3. Architecture4. Getting Started5. Deployment6. Integrations7. Production8. Interview Questions9. Glossary and Cheatsheet

6. Integrations

7 min read

Functions is glue by design — it is almost never the whole architecture, and it is almost never deployed alone. This page covers the services it's genuinely always paired with, and the two mechanisms that answer most "how do these talk to each other?" questions.

The two glue mechanisms

Learn these once and most integration questions on this page answer themselves.

Managed identity + a role assignment — the keyless way one Azure resource authenticates to another. The function app gets a system-assigned (or user-assigned) identity in Microsoft Entra ID; you assign that identity a data-plane role at the narrowest useful scope; the SDK or binding picks up the identity automatically. No connection string, nothing to rotate, nothing to leak.

# The pattern, once. Everything below is a variation on it.
PRINCIPAL=$(az functionapp identity show -g rg-demo-prod -n func-demo-prod --query principalId -o tsv)
az role assignment create \
  --assignee-object-id $PRINCIPAL --assignee-principal-type ServicePrincipal \
  --role "Storage Blob Data Contributor" \
  --scope /subscriptions/$SUB/resourceGroups/rg-demo-prod/providers/Microsoft.Storage/storageAccounts/stdemoprod

Note --assignee-object-id with --assignee-principal-type rather than --assignee: it avoids a race where the freshly-created identity hasn't replicated through Entra ID yet, which produces a "principal not found" error that goes away on retry and confuses everyone.

Private endpoint + Private DNS zone — the way one Azure resource reaches another without traversing the public internet. A private endpoint places a NIC with a private IP in your VNet, targeting a specific sub-resource of the destination (blob, queue, table, vault, sites, namespace), and a Private DNS zone rewrites the public hostname to that private IP. Two directions matter for Functions and people conflate them:

  • Outbound — your function reaching a private database. Needs VNet integration on the app, which requires Flex Consumption, Premium, or Dedicated. Consumption cannot do this at all.
  • Inbound — callers reaching your function privately. Needs a private endpoint on the function app (sub-resource sites) plus publicNetworkAccess = Disabled. Remember the SCM endpoint is a separate sub-resource; lock it down and your CI/CD needs a path in.

What a function app is nearly always wired to, and what does the wiring on each edge

The companions

Pairs with Why The glue
Azure Storage Mandatory host dependency, plus the most common trigger and output target AzureWebJobsStorage (identity-based), blob/queue/table bindings, Storage Blob Data Owner + Storage Queue Data Contributor + Storage Table Data Contributor on the identity
Application Insights Without it, a failed invocation is nearly invisible APPLICATIONINSIGHTS_CONNECTION_STRING app setting; the Functions host emits requests, dependencies, traces, and live metrics automatically
Key Vault Holds the secrets that shouldn't be in app settings Key Vault reference in an app setting, resolved by the app's managed identity at startup: @Microsoft.KeyVault(SecretUri=https://kv-x.vault.azure.net/secrets/db-password/). Needs Key Vault Secrets User
Service Bus The grown-up queue: sessions, dead-lettering, scheduled delivery, transactions Service Bus trigger/output binding + Azure Service Bus Data Receiver / Data Sender on the identity
Event Grid Push-based reaction to Azure resource events — including the modern blob trigger Event Grid system topic → event subscription → function endpoint (or the Event Grid–based blob trigger)
Event Hubs High-throughput streaming ingestion Event Hubs trigger with checkpointing in AzureWebJobsStorage; Azure Event Hubs Data Receiver. Parallelism is bounded by partition count
Cosmos DB Serverless compute in front of serverless data Change-feed trigger with a lease container (a real container you pay for), or input/output bindings; Cosmos DB Built-in Data Contributor
API Management Puts a real API in front of key-protected functions — versioning, rate limits, Entra ID validation, a stable hostname Import the function app as an API; APIM holds the function key and presents proper auth outward
Azure SQL / PostgreSQL The relational store the function writes to Managed identity as a database user, plus VNet integration + private endpoint; watch connection-pool exhaustion under scale-out
Front Door / Application Gateway Global routing, WAF, TLS, caching in front of HTTP functions Origin pointing at the app, with access restrictions so the app only accepts traffic from the front door
Microsoft Entra ID Replaces function keys with real identity on inbound calls App Service Authentication (Easy Auth) validating tokens before your code runs
Durable Functions Long-running, stateful orchestration without a long-running function An extension on the same app, with its task hub in AzureWebJobsStorage — name it per environment or two apps will corrupt each other
Azure Monitor / Log Analytics Where the diagnostic logs and metrics go, and where KQL lives Diagnostic setting on the app → Log Analytics workspace. Off by default

Four patterns worth knowing by name

1. Event Grid → Function, not Blob trigger → Function. The original blob trigger polls the container and scans for changes. On a large or busy container it lags — sometimes by minutes — and it costs storage transactions to do it. The Event Grid–based blob trigger is push-driven, near-real-time, and scales with the event system rather than with a scan. If you are writing a new blob-reactive function, use the Event Grid path. If you inherit a polling blob trigger with a latency complaint, this is your first suspect.

2. Queue in front of the sensitive dependency. The default Functions failure mode is scaling out enthusiastically into a database that cannot take it. Putting Service Bus between the ingress and the work turns an unbounded burst into a bounded drain: the queue absorbs the spike, per-instance concurrency and maxConcurrentCalls in host.json cap the pressure, and the dead-letter queue catches what fails. This is the single most useful architectural pattern in this topic.

3. API Management in front, function keys behind. Function keys are shared secrets with no identity, no rate limiting, and no expiry. Fronting the app with API Management lets you present OAuth or subscription keys outward while APIM holds the function key inward, and gives you throttling, versioning, and a hostname that survives moving the backend. The cost is a substantial extra service — for one function, use Easy Auth instead; for an API surface several teams consume, APIM pays for itself.

4. Durable fan-out/fan-in instead of a long-running function. When the work is "process 5,000 items and then summarise", the wrong answer is one function with a raised timeout. The right one is an orchestrator that fans out 5,000 activity invocations, each of which is short and independently retried, and fans the results back in. You get checkpointing, parallelism, and a resumable workflow. The cost lands in storage transactions, not compute — budget accordingly.

The integration anti-patterns

  • Connection strings in app settings. They're encrypted at rest but visible to anyone with control-plane access to the app, they appear in ARM exports, and nobody rotates them. Use managed identity; where a service genuinely has no identity support, use a Key Vault reference so the secret has one home and one rotation story.
  • Granting Contributor because a data-plane role didn't work. Contributor is a control-plane role. For storage it does not grant blob data access — that's Storage Blob Data Contributor — and reaching for Contributor to "make it work" grants far more than you intended while often not fixing the actual problem.
  • A private endpoint without the Private DNS zone. The endpoint exists, the name still resolves publicly, the traffic still leaves. The DNS zone link to the VNet is half the mechanism and it's the half people forget.
  • Firewalling the trigger source without runtime-driven scaling. Covered in Architecture: the scale controller reads your trigger source directly. Lock it to a private endpoint and the app can stop scaling while the code appears fine.
  • One function app integrating with everything. Each integration adds identity, network reach, and failure surface to a single app that scales as one unit. Split by blast radius.

Next: Production →

← Back to the Azure Functions overview · ← Previous: Deployment