|
| 1 | +--- |
| 2 | +title: "Quickstart: Host a .NET Durable Task SDK app on Azure Kubernetes Service" |
| 3 | +description: Learn how to deploy a .NET Durable Task SDK sample and Durable Task Scheduler to Azure Kubernetes Service (AKS) using Azure Developer CLI. |
| 4 | +author: hhunter-ms |
| 5 | +ms.author: hannahhunter |
| 6 | +ms.reviewer: azfuncdf |
| 7 | +ms.service: azure-functions |
| 8 | +ms.subservice: durable-task-scheduler |
| 9 | +ms.topic: quickstart |
| 10 | +ms.date: 02/27/2026 |
| 11 | +--- |
| 12 | + |
| 13 | +# Quickstart: Host a .NET Durable Task SDK app on Azure Kubernetes Service |
| 14 | + |
| 15 | +In this quickstart, you deploy an existing .NET Durable Task SDK sample to Azure Kubernetes Service (AKS), with Durable Task Scheduler as the orchestration backend. Deployment uses [Azure Developer CLI (`azd`)](/azure/developer/azure-developer-cli/install-azd) and the [document processing sample](https://github.com/Azure-Samples/Durable-Task-Scheduler/tree/main/samples/scenarios/DocumentProcessingOnAKS). |
| 16 | + |
| 17 | +You learn how to: |
| 18 | + |
| 19 | +> [!div class="checklist"] |
| 20 | +> |
| 21 | +> - Set up and run the Durable Task Scheduler emulator locally. |
| 22 | +> - Run the .NET client and worker projects in the AKS scenario sample. |
| 23 | +> - Deploy the sample infrastructure and apps to AKS with `azd up`. |
| 24 | +> - Verify orchestration execution in AKS by reviewing pod logs. |
| 25 | +
|
| 26 | +## Prerequisites |
| 27 | + |
| 28 | +Before you begin: |
| 29 | + |
| 30 | +- Install: |
| 31 | + - [.NET 10 SDK](https://dotnet.microsoft.com/download/dotnet/10.0). |
| 32 | + - [Docker Desktop](https://www.docker.com/products/docker-desktop/). |
| 33 | + - [Azure CLI](/cli/azure/install-azure-cli) and [Azure Developer CLI](/azure/developer/azure-developer-cli/install-azd). |
| 34 | + - [kubectl](https://kubernetes.io/docs/tasks/tools/). |
| 35 | +- Clone the [Durable Task Scheduler sample repository](https://github.com/Azure-Samples/Durable-Task-Scheduler). |
| 36 | +- Sign in to Azure and the [Azure Developer CLI](/azure/developer/azure-developer-cli/install-azd): |
| 37 | + |
| 38 | + ```bash |
| 39 | + az login |
| 40 | + azd auth login |
| 41 | + ``` |
| 42 | + |
| 43 | +## Prepare and run the sample locally |
| 44 | + |
| 45 | +1. From the repository root, go to the AKS scenario sample: |
| 46 | + |
| 47 | + ```bash |
| 48 | + cd samples/scenarios/DocumentProcessingOnAKS |
| 49 | + ``` |
| 50 | + |
| 51 | +1. Start the Durable Task Scheduler emulator: |
| 52 | + |
| 53 | + ```bash |
| 54 | + docker run --name dts-emulator -d -p 8080:8080 -p 8082:8082 mcr.microsoft.com/dts/dts-emulator:latest |
| 55 | + ``` |
| 56 | + |
| 57 | + The emulator exposes: |
| 58 | + - `8080` for gRPC app connectivity. |
| 59 | + - `8082` for the scheduler dashboard. |
| 60 | + |
| 61 | +1. Build the solution: |
| 62 | + |
| 63 | + ```bash |
| 64 | + dotnet build DurableTaskOnAKS.sln |
| 65 | + ``` |
| 66 | + |
| 67 | +1. In one terminal, run the worker: |
| 68 | + |
| 69 | + ```bash |
| 70 | + cd Worker |
| 71 | + dotnet run |
| 72 | + ``` |
| 73 | + |
| 74 | +1. In a second terminal, run the client: |
| 75 | + |
| 76 | + ```bash |
| 77 | + cd Client |
| 78 | + dotnet run |
| 79 | + ``` |
| 80 | + |
| 81 | +1. Confirm output similar to the following in the client terminal: |
| 82 | + |
| 83 | + ```output |
| 84 | + Endpoint: http://localhost:8080 | TaskHub: default |
| 85 | + Submitting 3 documents... |
| 86 | +
|
| 87 | + Scheduled [...] 'Cloud Migration Strategy' |
| 88 | + -> Processed 'Cloud Migration Strategy': Sentiment=Positive, Topic=Technology, Priority=Normal |
| 89 | +
|
| 90 | + Scheduled [...] 'Quarterly Incident Report' |
| 91 | + -> Processed 'Quarterly Incident Report': Sentiment=Positive, Topic=Technology, Priority=Normal |
| 92 | +
|
| 93 | + Scheduled [...] 'ML Model Evaluation' |
| 94 | + -> Processed 'ML Model Evaluation': Sentiment=Positive, Topic=Technology, Priority=Normal |
| 95 | +
|
| 96 | + Done. |
| 97 | + ``` |
| 98 | + |
| 99 | +## Deploy to AKS with Azure Developer CLI |
| 100 | + |
| 101 | +1. From `samples/scenarios/DocumentProcessingOnAKS`, run: |
| 102 | + |
| 103 | + ```azdeveloper |
| 104 | + azd up |
| 105 | + ``` |
| 106 | + |
| 107 | +1. When prompted, provide: |
| 108 | + |
| 109 | + | Parameter | Description | |
| 110 | + | --- | --- | |
| 111 | + | Environment Name | Prefix used for your deployment resources. | |
| 112 | + | Azure Subscription | Azure subscription for deployment. | |
| 113 | + | Azure Location | Azure region for the resources. | |
| 114 | + |
| 115 | +`azd up` provisions and deploys the full solution, including: |
| 116 | + |
| 117 | +- AKS cluster for the client and worker workloads. |
| 118 | +- Azure Container Registry (ACR) for container images. |
| 119 | +- Durable Task Scheduler for orchestration state and execution. |
| 120 | +- User-assigned managed identity and federated credentials for AKS workload identity authentication. |
| 121 | + |
| 122 | +## Verify the AKS deployment |
| 123 | + |
| 124 | +1. Get AKS credentials: |
| 125 | + |
| 126 | + ```bash |
| 127 | + az aks get-credentials --resource-group <resource-group-name> --name <aks-cluster-name> |
| 128 | + ``` |
| 129 | + |
| 130 | + You can get these values from `azd env get-values`. |
| 131 | + |
| 132 | +1. Confirm pods are running: |
| 133 | + |
| 134 | + ```bash |
| 135 | + kubectl get pods |
| 136 | + ``` |
| 137 | + |
| 138 | +1. Check client logs: |
| 139 | + |
| 140 | + ```bash |
| 141 | + kubectl logs -l app=client --tail=30 |
| 142 | + ``` |
| 143 | + |
| 144 | +1. Check worker logs: |
| 145 | + |
| 146 | + ```bash |
| 147 | + kubectl logs -l app=worker --tail=30 |
| 148 | + ``` |
| 149 | + |
| 150 | +When deployment is working, the client logs show scheduled orchestrations and completed document-processing results. |
| 151 | + |
| 152 | +### Verify using the Durable Task Scheduler dashboard |
| 153 | + |
| 154 | +You can also verify your task hub and orchestration status using the [Durable Task Scheduler dashboard](./durable-task-scheduler-dashboard.md). |
| 155 | + |
| 156 | +You can view the orchestration status and history via the [Durable Task Scheduler dashboard](./durable-task-scheduler-dashboard.md). By default, the dashboard runs on port 8082. |
| 157 | + |
| 158 | +1. Navigate to http://localhost:8082 in your web browser. |
| 159 | +1. Click the **default** task hub. The orchestration instance you created is in the list. |
| 160 | +1. Click the orchestration instance ID to view the execution details. |
| 161 | + |
| 162 | + :::image type="content" source="./media/quickstart-aks-durable-task-scheduler/orchestration-instance.png" alt-text="Screenshot showing the orchestration instance's details."::: |
| 163 | + |
| 164 | + |
| 165 | +## Understand the code |
| 166 | + |
| 167 | +### Client app |
| 168 | + |
| 169 | +The client creates a Durable Task client, schedules orchestrations, and waits for completion: |
| 170 | + |
| 171 | +```csharp |
| 172 | +foreach (var doc in docs) |
| 173 | +{ |
| 174 | + string id = await client.ScheduleNewOrchestrationInstanceAsync( |
| 175 | + "DocumentProcessingOrchestration", doc); |
| 176 | + |
| 177 | + var meta = await client.WaitForInstanceCompletionAsync(id, getInputsAndOutputs: true); |
| 178 | + if (meta.RuntimeStatus == OrchestrationRuntimeStatus.Completed) |
| 179 | + Console.WriteLine($" -> {meta.ReadOutputAs<string>()}\n"); |
| 180 | +} |
| 181 | +``` |
| 182 | + |
| 183 | +The sample builds the connection string from environment variables (`ENDPOINT`, `TASKHUB`, `AZURE_CLIENT_ID`), using local emulator defaults when those variables aren't set. |
| 184 | + |
| 185 | +### Worker app |
| 186 | + |
| 187 | +The worker registers the orchestration and activities, then connects to Durable Task Scheduler: |
| 188 | + |
| 189 | +```csharp |
| 190 | +builder.Services.AddDurableTaskWorker() |
| 191 | + .AddTasks(r => |
| 192 | + { |
| 193 | + r.AddOrchestrator<DocumentProcessingOrchestration>(); |
| 194 | + r.AddActivity<ValidateDocument>(); |
| 195 | + r.AddActivity<ClassifyDocument>(); |
| 196 | + }) |
| 197 | + .UseDurableTaskScheduler(connectionString); |
| 198 | +``` |
| 199 | + |
| 200 | +### Orchestration flow |
| 201 | + |
| 202 | +The `DocumentProcessingOrchestration` demonstrates activity chaining and fan-out/fan-in: |
| 203 | + |
| 204 | +```csharp |
| 205 | +bool isValid = await context.CallActivityAsync<bool>(nameof(ValidateDocument), doc); |
| 206 | + |
| 207 | +var tasks = new[] |
| 208 | +{ |
| 209 | + context.CallActivityAsync<ClassificationResult>(nameof(ClassifyDocument), new ClassifyRequest(doc.Id, doc.Content, "Sentiment")), |
| 210 | + context.CallActivityAsync<ClassificationResult>(nameof(ClassifyDocument), new ClassifyRequest(doc.Id, doc.Content, "Topic")), |
| 211 | + context.CallActivityAsync<ClassificationResult>(nameof(ClassifyDocument), new ClassifyRequest(doc.Id, doc.Content, "Priority")), |
| 212 | +}; |
| 213 | + |
| 214 | +ClassificationResult[] results = await Task.WhenAll(tasks); |
| 215 | +``` |
| 216 | + |
| 217 | +## Clean up resources |
| 218 | + |
| 219 | +To avoid charges, delete deployed Azure resources: |
| 220 | + |
| 221 | +```azdeveloper |
| 222 | +azd down |
| 223 | +``` |
| 224 | + |
| 225 | +To stop and remove the local emulator: |
| 226 | + |
| 227 | +```bash |
| 228 | +docker stop dts-emulator |
| 229 | +docker rm dts-emulator |
| 230 | +``` |
| 231 | + |
| 232 | +## Next step |
| 233 | + |
| 234 | +- Learn more in [Durable Task SDK overview](./durable-task-overview.md). |
0 commit comments