Introduction
Use Azure Functions for Power Platform workloads by separating submission from execution: accept a bounded request, persist an identifiable job, and let a scheduled or event-driven worker process it independently of the caller. Return the job identifier after durable acceptance; expose an authorized way to observe its state and result. The Function's managed identity authenticates outbound calls to Microsoft Dataverse, while a separate inbound authorization decision determines who may submit or inspect work.
This architecture suits work whose duration, dependencies or scheduling do not fit an interactive request. It requires more than moving a slow method into a Function: define who owns each job, how duplicate delivery is handled, where progress survives interruption, and what evidence proves completion. The following service-request assessment example is a proposed application design, not a built-in Power Platform service or an executed deployment.
Architecture Overview: Put a Job Boundary Around the Work
Suppose a Power Apps interface asks for a service-request assessment that reads Dataverse records, calculates a result and saves an assessment summary. Some requests need substantial processing; a nightly run must also assess newly eligible requests. The design uses four responsibilities:
- An intake component validates the caller and request, then records a job.
- A dispatch mechanism makes accepted jobs available to a worker.
- An Azure Function reads bounded work units and records outcomes.
- A status reader returns only the jobs the authenticated caller may inspect.
The application-defined job store is the authority for business completion. It can be implemented with Dataverse tables, provided the design supplies suitable authorization, uniqueness and concurrency controls. A queue is useful for dispatch, but deleting a message is not the business definition of success. Similarly, an HTTP response from intake establishes acceptance, not that the assessment exists.
Keep synchronous validation where it belongs. Reject a malformed identifier or forbidden operation before creating work. If a rule must prevent a Dataverse transaction from committing, a separately hosted worker cannot retroactively make that transaction atomic. Use the worker for the subsequent processing and represent its pending or failed result explicitly in the application.
Core Components and Trigger Choices
Azure Functions supports HTTP entry points, timed execution and message-based processing, among other trigger scenarios. Its overview also identifies Durable Functions for workflows composed of functions. Choose the entry point from the event that makes work eligible, then design persistence independently of the trigger.
| Entry point | Fit in the proposed assessment service | Contract that the application must supply |
|---|---|---|
| HTTP-triggered intake | A person or flow requests an assessment now | Authenticate and authorize the request, persist acceptance, then return a job identifier |
| Timer-triggered discovery | A scheduled pass identifies eligible service requests | Define the evaluation window, checkpoint and duplicate-run policy |
| Queue/message-triggered worker | Accepted work is ready to run without a waiting caller | Validate the message, claim a job, tolerate replay and record the result |
An HTTP-triggered intake should do bounded work. Returning early while leaving the real work only in an untracked in-memory task gives no recoverable ownership contract. Persist the work before acknowledging it. A timer is a scheduling signal; the application's saved state must determine what the run has already covered. For messages, design as though the same logical job can reach the worker again after an uncertain outcome.
Choose the host after defining the work unit
The current Functions overview describes Flex Consumption for event-driven scaling, Premium with always-warm instances, Dedicated using an App Service plan, and containerized hosting in Azure Container Apps. These are different operational choices, not interchangeable labels for infinite background execution.
Evaluate the chosen language/runtime, trigger support, networking, start latency, execution behavior and cost against the current hosting documentation before provisioning. Avoid copying a timeout value from another plan or assuming that a longer execution allowance guarantees uninterrupted processing. For this assessment service, measure the largest bounded work unit and save a checkpoint between units. A host restart should require redoing only safe work, rather than rediscovering the entire job's history.
Scaling is also a downstream design decision. More worker instances can create more Dataverse traffic. Set a deliberate concurrency budget and tune it from observed completion rate and downstream pressure; do not let the number of queued messages become an instruction to issue all Dataverse requests simultaneously. Detailed Dataverse request retries and bulk-operation choices are covered in AB-400: Reliable Dataverse Bulk and Background Operations.
How Components Work Together: Acceptance, Progress and Completion
The example intake accepts an application-defined request such as:
{
"contractVersion": 1,
"requestKey": "assessment-SR1042-r3",
"serviceRequestId": "<Dataverse row identifier>",
"assessmentRevision": 3
}
These fields are illustrative contracts, not Microsoft API fields. requestKey identifies one logical submission; it is not an authorization credential. Scope its uniqueness to the authenticated tenant, caller and operation, and compare the normalized business payload on a repeat. The same key with different content should be rejected as a conflict. Otherwise a legitimate retry can silently request a different assessment under an existing job.
The server generates a separate jobId. Store the authenticated requester, target environment, target row, accepted payload version, creation time, state, checkpoint and result reference with that identifier. Do not accept an arbitrary Dataverse environment address or callback destination from an untrusted request. Bind destinations to deployment configuration and authorized operation types.
Close the persistence-to-dispatch gap
Job creation and message publication are separate effects unless a deliberately implemented mechanism coordinates them. If the job is saved and publication fails, work can remain undispatched. If a message is published before the job is committed, a worker can receive an identifier it cannot resolve.
For this design, make the saved job recoverable without the original caller. One option is a persisted dispatch marker scanned by a dispatcher, which marks publication after sending and safely tolerates a repeated send. Another is a reconciliation pass that finds accepted jobs without progress. Neither description establishes a distributed transaction; the implementation must account for failure between each step. Return the acceptance response only after the recovery path owns the job.
An illustrative response has jobId and state: "Accepted"; an HTTP design can use 202 Accepted. A subsequent status operation returns the same identifier plus progress and, eventually, a result reference. Keep the original request key stable when retrying a submission after a lost response so that the caller can recover the existing job instead of creating another assessment.
Make progress monotonic and terminal states meaningful
Use an explicit application state model, for example:
| State | Meaning in this design | Required evidence |
|---|---|---|
| Accepted | Work is durably recorded and recoverable | Stored request and dispatch/reconciliation ownership |
| Running | A worker owns a bounded processing attempt | Current claim/lease and last progress time |
| Succeeded | All intended work is committed | Result reference and completion time |
| Failed | Automatic recovery has ended | Sanitized failure code, last checkpoint and operator action |
Implement an atomic claim or equivalent concurrency control so that competing workers do not both own the same job. Include ownership expiry and recovery rules; a permanent Running flag is not a recovery strategy. Prevent an older worker from overwriting a newer attempt's completion by checking ownership when saving progress.
The most revealing failure occurs after the result is saved but before completion is recorded. A restarted worker must recognize that the result for the same logical job and revision already exists. Use a stable result identity and an idempotent write strategy; then finish recording completion. Marking Succeeded before saving the result creates the opposite failure: the interface reports success while the result is missing. The implementation must verify the chosen data store's actual uniqueness and conditional-write behavior rather than relying on a preliminary read alone.
For scheduled discovery, save the last completed evaluation window and identify runs by that window. Define whether eligibility is evaluated from a snapshot or from current data. If discovery stops midway, resume from a persisted checkpoint and deduplicate the jobs already created. A timer firing again should not mean that every record must be processed again.
Design Considerations: Two Identity Directions
Inbound: authorize the caller's requested operation
Treat the intake and status reader as protected application interfaces. For an implementation using Microsoft Entra ID tokens, require validation of the intended API audience and trusted tenant/issuer, then enforce the allowed submitting identity and operation. This is a recommended trust contract; this article does not prescribe a connector definition or a particular authentication middleware configuration.
Derive the requester from validated identity claims rather than trusting a requestedBy field. Authorize access to the target service request before accepting work. The status reader must perform its own ownership or role check: possession of a jobId alone should not reveal another user's business data. Apply equivalent restrictions to who may publish messages to the worker's input. Keep tokens and credentials out of queue payloads and logs.
Outbound: give the Function a Dataverse application user
An Azure Functions managed identity represents the application when it requests access to another protected resource. Microsoft manages its credentials. A system-assigned identity follows the app's lifecycle; a user-assigned identity is a separate resource that can be attached to apps. Choose deliberately, record the selected identity, and remember that identity configuration is specific to a deployment slot.
For Dataverse access, configure an application user in the target environment for that identity and assign the security roles required by the workload. In the Power Platform admin center, select the environment, then Settings, Users + permissions, Application users, and New app user. When adding a managed identity, Microsoft's instructions require its Application ID rather than its name. Select the business unit and appropriate security roles, then create the application user.
Configure the worker to acquire a Dataverse-targeted token through its managed identity and use it for Dataverse requests. Microsoft's OAuth guidance distinguishes server-to-server application access from interactive delegated access. Do not forward the caller's API token as the worker's Dataverse credential, and do not infer that Azure subscription permissions grant Dataverse table privileges. An application user and its environment-specific security roles are a separate authorization boundary.
For the example, grant the worker only the data access needed to read eligible requests and create/update job progress and assessment results. Test a deliberately forbidden table operation as well as an allowed one. If different submitting users have different data access, the service must enforce the submission policy itself: running as an application identity does not automatically preserve each person's Dataverse permissions. Review this potential elevation before exposing an assessment operation.
Keep development and production mappings explicit. A local developer credential that can read Dataverse does not prove that the deployed Function's identity can do so. After deployment, verify the selected identity, environment and minimal data operation together. When decommissioning the example, stop intake and scheduling, drain or cancel outstanding work under the stated policy, and remove obsolete application-user access and dedicated resources after preserving needed results. Do not delete a shared user-assigned identity without checking its consumers.
Common Mistakes and Observable Failures
The following are expected diagnostic observations for this proposed design, not test results from a tenant:
| Observation | Boundary to investigate | Useful discriminator |
|---|---|---|
| Intake rejects a request before a job exists | Inbound identity or request validation | Compare expected audience/caller and operation permissions; retain a sanitized correlation identifier |
| Job remains Accepted | Dispatch or worker activation | Establish whether a message was sent, a worker received it and a claim was obtained |
| Worker obtains a token but cannot perform the data operation | Dataverse authorization or identity/environment mapping | Check the actual application user, assigned role and requested table/row operation |
| Work is Running with no recent progress | Worker interruption, dependency stall or expired ownership | Compare last progress and claim expiry before permitting recovery |
| A replay creates another assessment | Missing result idempotency | Look for a stable logical result key and an enforced uniqueness/concurrency mechanism |
| Status says Succeeded but the result cannot be retrieved | Incorrect completion ordering or result-reader permissions | Check result existence separately from the reader's authorization |
Before production use, deliberately lose the intake response, deliver the same work twice, stop a worker after a result write, and deny one required Dataverse permission in an isolated environment. Acceptance requires one recoverable job per logical request, no duplicate business result, correct terminal state and a diagnosable failure. Correlate the application job identifier with each worker attempt and dependency call; do not substitute a single invocation's successful execution log for business completion.
Certification Relevance
The selected AB-400 study-guide scope includes long-running workloads, scheduled and event-driven triggers, and managed identity authentication to Microsoft Power Platform. These skills fit together as one architecture: select what starts the work, choose where it runs, authenticate its data access and make completion observable. The series retains the scope verified on October 15, 2026; the announced exam availability date was October 16, 2026, and that baseline is not evidence of a completed live launch.
Conclusion
A useful Functions boundary leaves the caller with a durable job identifier and the worker with explicit ownership, constrained permissions and recoverable progress. Trigger selection controls when processing begins; hosting controls its execution environment; the application contract determines whether retries, interruptions and completion mean what the user expects. Validate all three before treating a background assessment as reliable.
Authoritative Sources
- AB-400 study guide
- Use OAuth authentication with Microsoft Dataverse
- Azure Functions overview
- Use managed identities in App Service and Azure Functions
- Manage application users

