Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Publishing orchestration lifecycle events to Azure Event Grid enables DevOps automation (such as blue/green deployments), real-time monitoring dashboards, and tracking of long-running background processes.
Note
This guide uses .NET examples, but the concepts and Azure CLI commands apply to all supported Durable Functions languages.
Tip
If you already have an Event Grid custom topic and managed identity configured, skip to Configure the Durable Functions publisher app.
Prerequisites
A Durable Functions project deployed to Azure. If you don't have one, create one using the quickstart for your preferred language:
The correct Durable Functions extension version. For .NET, update your extension to the latest version:
2.7.0+ (in-process)
dotnet add package Microsoft.Azure.WebJobs.Extensions.DurableTask1.1.0+ (isolated worker)
dotnet add package Microsoft.Azure.Functions.Worker.Extensions.DurableTask
For other languages, check your
package.json,requirements.txt,pom.xml, orrequirements.psd1.Managed identity enabled and configured on your function app.
A running storage provider or the local Azurite storage emulator.
An HTTP test tool that keeps your data secure.
Create a custom Event Grid topic
You can create an Event Grid topic for sending events from Durable Functions by using the Azure CLI, PowerShell, or the Azure portal.
This guide uses the Azure CLI.
Create a resource group
Create a resource group with the az group create command. Pick a location that supports Event Grid and matches where you want to deploy your resources.
Note
Currently, Azure Event Grid doesn't support all regions. For information about which regions are supported, see the Azure Event Grid overview.
az group create --name <resource-group-name> --location <location>
Enable the Event Grid resource provider
If this is the first time you're using Event Grid in your Azure subscription, you might need to register the Event Grid resource provider. Run the following command to register the provider:
az provider register --namespace Microsoft.EventGridIt might take a moment for the registration to finish. To check the status, run the following command:
az provider show --namespace Microsoft.EventGrid --query "registrationState"When
registrationStateisRegistered, you're ready to continue.
Create a custom topic
An Event Grid topic provides a user-defined endpoint that you post your event to. Replace <topic-name> in the following command with a unique name for your topic. The topic name must be unique because it becomes a DNS entry.
az eventgrid topic create --name <topic-name> --location <location> --resource-group <resource-group-name>
Get the topic endpoint
Get the endpoint of the topic. Replace <topic-name> in the following commands with the name you chose.
az eventgrid topic show --name <topic-name> --resource-group <resource-group-name> --query "endpoint" --output tsv
Save this endpoint for later.
Configure Event Grid publishing with Managed Identity (recommended)
Managed identities in Azure allow resources to authenticate to Azure services without storing credentials, simplifying security and identity management. Assign the managed identity associated with your Durable Function app to your Event Grid custom topic.
Configure the Durable Functions publisher app
Although your Durable Functions app automatically publishes orchestration lifecycle events to Event Grid, you need to configure the connection settings. Add the following to the extensions.durableTask section in your host.json:
{
"version": "2.0",
"extensions": {
"durableTask": {
"eventGridTopicEndpoint": "%EventGrid__topicEndpoint%",
"eventGridKeySettingName": "EventGrid__credential"
}
}
}
Note
The eventGridTopicEndpoint setting references the Event Grid custom topic endpoint you saved earlier. The credential setting handles both managed identity and connection string scenarios.
Assign Event Grid Data Sender role
Grant your managed identity permission to publish events to the Event Grid topic.
az role assignment create \
--assignee <client-id-of-managed-identity> \
--assignee-principal-type ServicePrincipal \
--role "EventGrid Data Sender" \
--scope /subscriptions/<subscription-id>/resourceGroups/<resource-group-name>/providers/Microsoft.EventGrid/topics/<topic-name>
Replace the following values:
<client-id-of-managed-identity>: The client ID of your user-assigned managed identity<subscription-id>: Your Azure subscription ID<resource-group-name>: The name of the resource group containing your Event Grid topic<topic-name>: The name of your Event Grid topic
Note
Role assignments can take 5-10 minutes to propagate. You may see authentication errors if you proceed immediately after assignment.
Configure app settings
Once you've enabled managed identity for your function app and topic, configure the Event Grid app settings on your Durable Functions function app.
Add the following app settings:
EventGrid__topicEndpoint— the Event Grid topic endpoint.EventGrid__credential— set tomanagedidentity.EventGrid__clientId— the user-assigned managed identity client ID.
az functionapp config appsettings set --name <function app name> --resource-group <resource group name> --settings EventGrid__topicEndpoint="<topic endpoint>" EventGrid__credential="managedidentity" EventGrid__clientId="<client id>"
Subscribe to events
To receive the published lifecycle events, create an Event Grid subscription that routes events from your custom topic to a subscriber. Common subscriber types include Azure Functions (with an Event Grid trigger), Logic Apps, and webhooks.
The following example creates a subscriber function app with an Event Grid trigger using the Azure CLI. If you already have a subscriber, skip to Create an Event Grid subscription.
Create a listener function app
Create a function app to host the Event Grid trigger. The listener must be in the same region as the Event Grid topic.
# Create a resource group
az group create --name <listener-resource-group-name> --location <location>
# Create a storage account
az storage account create \
--name <storage-account-name> \
--resource-group <listener-resource-group-name> \
--location <location> \
--sku Standard_LRS \
--allow-blob-public-access false
# Create the function app
az functionapp create \
--resource-group <listener-resource-group-name> \
--consumption-plan-location <location> \
--runtime <preferred-runtime> \
--functions-version 4 \
--name <listener-function-app-name> \
--storage-account <storage-account-name>
Create and deploy an Event Grid trigger function
Scaffold a local project, add an Event Grid trigger, and publish it:
mkdir EventGridListenerFunction && cd EventGridListenerFunction
func init --name EventGridListener --runtime dotnet-isolated
func new --template "Event Grid trigger" --name EventGridTrigger
func azure functionapp publish <listener-function-app-name>
Note
Replace dotnet-isolated with your preferred runtime (node, python, java, or powershell). For detailed deployment instructions, see Publish to Azure.
Create an Event Grid subscription
Create the subscription using the azurefunction endpoint type, which automatically handles webhook validation:
az eventgrid event-subscription create \
--name <subscription-name> \
--source-resource-id /subscriptions/<subscription-id>/resourceGroups/<resource-group-name>/providers/Microsoft.EventGrid/topics/<topic-name> \
--endpoint /subscriptions/<subscription-id>/resourceGroups/<listener-resource-group-name>/providers/Microsoft.Web/sites/<listener-function-app-name>/functions/EventGridTrigger \
--endpoint-type azurefunction
Tip
Using --endpoint-type azurefunction with the function's resource ID is the recommended approach. It automatically handles webhook validation and is more reliable than using --endpoint-type webhook with a URL.
Event schema
When an orchestration state changes, the Durable Functions runtime publishes an event with the following structure. Events are generated automatically for each state transition — you don't need to add any code.
| Field | Description |
|---|---|
id |
Unique identifier for the Event Grid event. |
subject |
durable/orchestrator/{orchestrationRuntimeStatus} — the status can be Running, Completed, Failed, or Terminated. |
eventType |
Always orchestratorEvent. |
eventTime |
Event time (UTC). |
data.hubName |
TaskHub name. |
data.functionName |
Orchestrator function name. |
data.instanceId |
Unique orchestration instance ID. |
data.runtimeStatus |
Running, Completed, Failed, or Canceled. |
data.reason |
Additional tracking data. For more information, see Diagnostics in Durable Functions. |
Event Grid ensures at-least-once delivery, so you may receive duplicate events in rare failure scenarios. Consider adding deduplication logic using the instanceId if needed.
Verify event delivery
To verify the end-to-end setup, deploy your Durable Functions app and trigger an orchestration:
Publish the function code to Azure and verify your function app shows "Running" in the Azure portal.
In the Azure portal, verify your app settings under Settings > Environment variables include
EventGrid__topicEndpointand (if using managed identity)EventGrid__credential.Trigger an orchestration using an HTTP client:
curl -X POST https://<function_app_name>.azurewebsites.net/api/HelloOrchestration_HttpStartIn the Azure portal, navigate to your listener function app > EventGridTrigger > Monitor to view received events. You should see events with subjects like
durable/orchestrator/Runninganddurable/orchestrator/Completed.
Verify in Application Insights (optional)
For a more comprehensive view, run this KQL query in your function app's Application Insights Logs:
traces
| where message contains "Event type" or message contains "Event subject"
| project timestamp, message
| order by timestamp desc
Troubleshooting
Events are not being published to Event Grid
Problem: The listener function is not receiving events.
Solutions:
- Verify the Durable Functions function app has the correct app settings:
EventGrid__topicEndpointmust point to your custom topic endpointEventGrid__credentialmust be set tomanagedidentityEventGrid__clientIdmust be set if using a user-assigned identity
- Verify the managed identity has the EventGrid Data Sender role assigned to the Event Grid custom topic.
- Check the Durable Functions function app logs in Application Insights for errors.
- Verify the Event Grid topic exists and is accessible in the same subscription.
Listener function is not being triggered
Problem: The listener function exists but isn't executing when events are published.
Solutions:
- Verify the Event Grid subscription was created and is enabled:
- In the Azure portal, navigate to your Event Grid topic → Subscriptions
- Confirm your listener function's subscription is listed with status Enabled
- Verify the Event Grid subscription is using the correct endpoint type:
- For Azure Functions, use
--endpoint-type azurefunctionwith the function's resource ID - If you used
--endpoint-type webhook, ensure the webhook URL is in the correct format:https://<function-app>.azurewebsites.net/runtime/webhooks/eventgrid?functionName=<function-name>&code=<system-key>
- For Azure Functions, use
- Check the listener function app logs for errors or delivery issues.
- In the Event Grid topic → Metrics, check for Dropped Events which may indicate delivery failures.
"Forbidden" or authentication errors in logs
Problem: Authentication errors when publishing to Event Grid.
Solutions:
- Verify the managed identity is properly configured and enabled on the Durable Functions function app:
- In the Azure portal, navigate to your function app → Identity
- Confirm "Status" shows On for either system-assigned or user-assigned identity
- Verify the role assignment is correct:
- Navigate to your Event Grid topic → Access Control (IAM)
- Confirm your managed identity has the EventGrid Data Sender role (note: no space between "Event" and "Grid")
- The role assignment may take 5-10 minutes to propagate
"Connection refused" or "endpoint not found" errors
Problem: Connection errors to the Event Grid topic.
Solutions:
- Verify the Event Grid topic endpoint in your app settings is correct and includes the full URL (for example,
https://my-topic.eventgrid.azure.net/api/events) - Verify the Event Grid topic resource exists in the same subscription and region
- Check that your Durable Functions app has network access to the Event Grid endpoint
Test locally
To test locally, see Local testing with viewer web app. When testing locally with managed identity, use your developer credentials to authenticate against the Event Grid topic. See Configure Durable Functions with managed identity - Local development for details.
Clean up resources
If you're not going to continue to use the resources created in this tutorial, delete them to avoid incurring charges.
Delete the resource groups
Delete both resource groups and all their contained resources:
az group delete --name <resource-group-name> --yes
az group delete --name <listener-resource-group-name> --yes
Delete individual resources
If you want to keep some resources, you can delete them individually:
Delete the Event Grid subscription:
az eventgrid event-subscription delete \ --name <subscription-name> \ --source-resource-id /subscriptions/<subscription-id>/resourceGroups/<resource-group-name>/providers/Microsoft.EventGrid/topics/<topic-name>Delete the Event Grid topic:
az eventgrid topic delete --name <topic-name> --resource-group <resource-group-name>Delete the function apps:
az functionapp delete --name <publisher-function-app-name> --resource-group <resource-group-name> az functionapp delete --name <listener-function-app-name> --resource-group <listener-resource-group-name>Delete the storage accounts:
az storage account delete --name <storage-account-name> --resource-group <resource-group-name> --yes az storage account delete --name <listener-storage-account-name> --resource-group <listener-resource-group-name> --yes
Next steps
Learn more about: