Azure Functions for Power Platform
Offload heavy processing to Azure Functions. Learn how to handle long-running operations, configure triggers, and authenticate to Power Platform using managed identities.
When Power Platform needs more power
Think of Azure Functions as a specialist workshop behind your factory.
Your factory (Power Platform) handles most production. But some jobs are too heavy for the main line β generating a 500-page PDF, processing 10,000 images, or running a complex algorithm. You send those jobs to the specialist workshop (Azure Function), which has the tools and time to handle them.
The workshop communicates with the factory through defined channels: HTTP triggers (call the Function directly), timer triggers (scheduled jobs), and event triggers (react when something happens). And the workshop uses a managed identity badge to access factory resources without storing passwords.
When to use Azure Functions
| Scenario | Why Not Plug-in/Flow? | Azure Function Solution |
|---|---|---|
| Generate a complex PDF report | Plug-in: 2-min timeout, sandbox limits. Flow: no PDF generation | HTTP-triggered Function with PDF library |
| Nightly data cleanup (3+ hours) | Plug-in: timeout. Flow: action limits | Timer-triggered Function with batch processing |
| React to Service Bus messages | Plug-in: cannot listen to Service Bus | Service Bus-triggered Function |
| Complex ML model inference | Plug-in: cannot load ML models | HTTP-triggered Function with ML libraries |
| Call 10 APIs and aggregate results | Plug-in: sandbox networking limits | HTTP-triggered Function with parallel API calls |
Trigger types for Power Platform
| Trigger | How It Fires | Power Platform Use Case |
|---|---|---|
| HTTP | External HTTP request | Plug-in or flow calls the Function via HTTP |
| Timer | CRON schedule | Nightly sync, hourly cleanup, weekly reports |
| Service Bus | Message arrives in queue/topic | Process events published by Dataverse business events |
| Event Grid | Azure event published | React to Azure resource events (blob created, etc.) |
| Blob Storage | File uploaded to container | Process uploaded documents (OCR, classification) |
Common pattern: Async plug-in β Azure Function
User saves record
β Post-operation async plug-in fires (does not block user)
β Plug-in sends record ID to Azure Function via HTTP or Service Bus
β Function performs heavy processing (external APIs, computation)
β Function writes results back to Dataverse via Web API
Important: Do NOT call Azure Functions synchronously from a pre-operation plug-in for long-running work β this blocks the user and risks the 2-minute timeout. For short, bounded lookups (under 5 seconds), a synchronous HTTP call is acceptable. For anything heavier, use async patterns.
Managed identity authentication
A managed identity lets your Azure Function authenticate to Dataverse without storing credentials in code or configuration.
How it works
- Enable managed identity on the Azure Function App (System-assigned or User-assigned)
- Create an application user in Dataverse for the managed identityβs client ID
- Assign a security role to the application user (least privilege)
- The Function acquires a token from Entra ID using the managed identity β no secrets needed
// Authenticate to Dataverse using managed identity
var credential = new DefaultAzureCredential(); // Uses managed identity automatically
var token = await credential.GetTokenAsync(
new TokenRequestContext(new[] { "https://orgname.crm.dynamics.com/.default" })
);
var client = new HttpClient();
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", token.Token);
// Now call Dataverse Web API
var response = await client.GetAsync(
"https://orgname.crm.dynamics.com/api/data/v9.2/contacts?$top=10");
Why managed identity over client secrets?
| Feature | Managed Identity | Client Secret |
|---|---|---|
| Credentials stored in code? | No β handled by Azure | Yes β must be stored securely |
| Rotation needed? | No β automatic | Yes β manual rotation |
| Risk of credential leak? | None | Yes β if code/config is exposed |
| Works from Azure only? | Yes | Works from anywhere |
Scenario: Amara offloads PDF generation
Amaraβs healthcare client needs to generate patient discharge summaries β 20-page PDFs with charts, images, and medical data. A plug-in cannot do this (sandbox restrictions, 2-minute timeout).
Solution:
- Post-operation async plug-in fires when a Discharge record is created
- Plug-in sends the record ID to an Azure Function via HTTP trigger
- Function authenticates to Dataverse using managed identity
- Function retrieves patient data via Web API
- Function generates the PDF using a C# library (iText, QuestPDF)
- Function uploads the PDF as a Dataverse annotation (note attachment)
- Function sends a notification email via SendGrid
Total processing time: 45 seconds. No timeout issues, no sandbox restrictions.
A developer needs to process 50,000 records nightly β updating each record based on data from an external API. The process takes approximately 2 hours. What is the best architecture?
π¬ Video coming soon
Next up: Cloud Flows: Dataverse Triggers & Expressions β configuring Dataverse connector triggers and writing complex flow expressions.