--- name: azure-resource-manager-durabletask-dotnet description: | Azure Resource Manager SDK for Durable Task Scheduler in .NET. Use for MANAGEMENT PLANE operations: creating/managing Durable Task Schedulers, Task Hubs, and retention policies via Azure Resource Manager. Triggers: "Durable Task Scheduler", "create scheduler", "task hub", "DurableTaskSchedulerResource", "provision Durable Task", "orchestration scheduler". package: Azure.ResourceManager.DurableTask --- # Azure.ResourceManager.DurableTask (.NET) Management plane SDK for provisioning and managing Azure Durable Task Scheduler resources via Azure Resource Manager. > **⚠️ Management vs Data Plane** > - **This SDK (Azure.ResourceManager.DurableTask)**: Create schedulers, task hubs, configure retention policies > - **Data Plane SDK (Microsoft.DurableTask.Client.AzureManaged)**: Start orchestrations, query instances, send events ## Installation ```bash dotnet add package Azure.ResourceManager.DurableTask dotnet add package Azure.Identity ``` **Current Versions**: Stable v1.0.0 (2025-11-03), Preview v1.0.0-beta.1 (2025-04-24) **API Version**: 2025-11-01 ## Environment Variables ```bash AZURE_SUBSCRIPTION_ID= AZURE_RESOURCE_GROUP= # For service principal auth (optional) AZURE_TENANT_ID= AZURE_CLIENT_ID= AZURE_CLIENT_SECRET= ``` ## Authentication ```csharp using Azure.Identity; using Azure.ResourceManager; using Azure.ResourceManager.DurableTask; // Always use DefaultAzureCredential var credential = new DefaultAzureCredential(); var armClient = new ArmClient(credential); // Get subscription var subscriptionId = Environment.GetEnvironmentVariable("AZURE_SUBSCRIPTION_ID"); var subscription = armClient.GetSubscriptionResource( new ResourceIdentifier($"/subscriptions/{subscriptionId}")); ``` ## Resource Hierarchy ``` ArmClient └── SubscriptionResource └── ResourceGroupResource └── DurableTaskSchedulerResource ├── DurableTaskHubResource └── DurableTaskRetentionPolicyResource ``` ## Core Workflow ### 1. Create Durable Task Scheduler ```csharp using Azure.ResourceManager.DurableTask; using Azure.ResourceManager.DurableTask.Models; // Get resource group var resourceGroup = await subscription .GetResourceGroupAsync("my-resource-group"); // Define scheduler with Dedicated SKU var schedulerData = new DurableTaskSchedulerData(AzureLocation.EastUS) { Properties = new DurableTaskSchedulerProperties { Sku = new DurableTaskSchedulerSku(DurableTaskSchedulerSkuName.Dedicated) { Capacity = 1 // Number of instances }, // Optional: IP allowlist for network security IPAllowlist = { "10.0.0.0/24", "192.168.1.0/24" } } }; // Create scheduler (long-running operation) var schedulerCollection = resourceGroup.Value.GetDurableTaskSchedulers(); var operation = await schedulerCollection.CreateOrUpdateAsync( WaitUntil.Completed, "my-scheduler", schedulerData); DurableTaskSchedulerResource scheduler = operation.Value; Console.WriteLine($"Scheduler created: {scheduler.Data.Name}"); Console.WriteLine($"Endpoint: {scheduler.Data.Properties.Endpoint}"); ``` ### 2. Create Scheduler with Consumption SKU ```csharp // Consumption SKU (serverless) var consumptionSchedulerData = new DurableTaskSchedulerData(AzureLocation.EastUS) { Properties = new DurableTaskSchedulerProperties { Sku = new DurableTaskSchedulerSku(DurableTaskSchedulerSkuName.Consumption) // No capacity needed for consumption } }; var operation = await schedulerCollection.CreateOrUpdateAsync( WaitUntil.Completed, "my-serverless-scheduler", consumptionSchedulerData); ``` ### 3. Create Task Hub ```csharp // Task hubs are created under a scheduler var taskHubData = new DurableTaskHubData { // Properties are optional for basic task hub }; var taskHubCollection = scheduler.GetDurableTaskHubs(); var hubOperation = await taskHubCollection.CreateOrUpdateAsync( WaitUntil.Completed, "my-taskhub", taskHubData); DurableTaskHubResource taskHub = hubOperation.Value; Console.WriteLine($"Task Hub created: {taskHub.Data.Name}"); ``` ### 4. List Schedulers ```csharp // List all schedulers in subscription await foreach (var sched in subscription.GetDurableTaskSchedulersAsync()) { Console.WriteLine($"Scheduler: {sched.Data.Name}"); Console.WriteLine($" Location: {sched.Data.Location}"); Console.WriteLine($" SKU: {sched.Data.Properties.Sku?.Name}"); Console.WriteLine($" Endpoint: {sched.Data.Properties.Endpoint}"); } // List schedulers in resource group var schedulers = resourceGroup.Value.GetDurableTaskSchedulers(); await foreach (var sched in schedulers.GetAllAsync()) { Console.WriteLine($"Scheduler: {sched.Data.Name}"); } ``` ### 5. Get Scheduler by Name ```csharp // Get existing scheduler var existingScheduler = await schedulerCollection.GetAsync("my-scheduler"); Console.WriteLine($"Found: {existingScheduler.Value.Data.Name}"); // Or use extension method var schedulerResource = armClient.GetDurableTaskSchedulerResource( DurableTaskSchedulerResource.CreateResourceIdentifier( subscriptionId, "my-resource-group", "my-scheduler")); var scheduler = await schedulerResource.GetAsync(); ``` ### 6. Update Scheduler ```csharp // Get current scheduler var scheduler = await schedulerCollection.GetAsync("my-scheduler"); // Update with new configuration var updateData = new DurableTaskSchedulerData(scheduler.Value.Data.Location) { Properties = new DurableTaskSchedulerProperties { Sku = new DurableTaskSchedulerSku(DurableTaskSchedulerSkuName.Dedicated) { Capacity = 2 // Scale up }, IPAllowlist = { "10.0.0.0/16" } // Update IP allowlist } }; var updateOperation = await schedulerCollection.CreateOrUpdateAsync( WaitUntil.Completed, "my-scheduler", updateData); ``` ### 7. Delete Resources ```csharp // Delete task hub first var taskHub = await scheduler.GetDurableTaskHubs().GetAsync("my-taskhub"); await taskHub.Value.DeleteAsync(WaitUntil.Completed); // Then delete scheduler await scheduler.DeleteAsync(WaitUntil.Completed); ``` ### 8. Manage Retention Policies ```csharp // Get retention policy collection var retentionPolicies = scheduler.GetDurableTaskRetentionPolicies(); // Create or update retention policy var retentionData = new DurableTaskRetentionPolicyData { Properties = new DurableTaskRetentionPolicyProperties { // Configure retention settings } }; var retentionOperation = await retentionPolicies.CreateOrUpdateAsync( WaitUntil.Completed, "default", // Policy name retentionData); ``` ## Key Types Reference | Type | Purpose | |------|---------| | `ArmClient` | Entry point for all ARM operations | | `DurableTaskSchedulerResource` | Represents a Durable Task Scheduler | | `DurableTaskSchedulerCollection` | Collection for scheduler CRUD | | `DurableTaskSchedulerData` | Scheduler creation/update payload | | `DurableTaskSchedulerProperties` | Scheduler configuration (SKU, IPAllowlist) | | `DurableTaskSchedulerSku` | SKU configuration (Name, Capacity, RedundancyState) | | `DurableTaskSchedulerSkuName` | SKU options: `Dedicated`, `Consumption` | | `DurableTaskHubResource` | Represents a Task Hub | | `DurableTaskHubCollection` | Collection for task hub CRUD | | `DurableTaskHubData` | Task hub creation payload | | `DurableTaskRetentionPolicyResource` | Retention policy management | | `DurableTaskRetentionPolicyData` | Retention policy configuration | | `DurableTaskExtensions` | Extension methods for ARM client | ## SKU Options | SKU | Description | Use Case | |-----|-------------|----------| | `Dedicated` | Fixed capacity with configurable instances | Production workloads, predictable performance | | `Consumption` | Serverless, auto-scaling | Development, variable workloads | ## Extension Methods The SDK provides extension methods on `SubscriptionResource` and `ResourceGroupResource`: ```csharp // On SubscriptionResource subscription.GetDurableTaskSchedulers(); // List all in subscription subscription.GetDurableTaskSchedulersAsync(); // Async enumerable // On ResourceGroupResource resourceGroup.GetDurableTaskSchedulers(); // Get collection resourceGroup.GetDurableTaskSchedulerAsync(name); // Get by name // On ArmClient armClient.GetDurableTaskSchedulerResource(id); // Get by resource ID armClient.GetDurableTaskHubResource(id); // Get task hub by ID ``` ## Best Practices 1. **Use `WaitUntil.Completed`** for operations that must finish before proceeding 2. **Use `WaitUntil.Started`** when you want to poll manually or run operations in parallel 3. **Always use `DefaultAzureCredential`** — never hardcode keys 4. **Handle `RequestFailedException`** for ARM API errors 5. **Use `CreateOrUpdateAsync`** for idempotent operations 6. **Delete task hubs before schedulers** — schedulers with task hubs cannot be deleted 7. **Use IP allowlists** for network security in production ## Error Handling ```csharp using Azure; try { var operation = await schedulerCollection.CreateOrUpdateAsync( WaitUntil.Completed, schedulerName, schedulerData); } catch (RequestFailedException ex) when (ex.Status == 409) { Console.WriteLine("Scheduler already exists"); } catch (RequestFailedException ex) when (ex.Status == 404) { Console.WriteLine("Resource group not found"); } catch (RequestFailedException ex) { Console.WriteLine($"ARM Error: {ex.Status} - {ex.ErrorCode}: {ex.Message}"); } ``` ## Complete Example ```csharp using Azure; using Azure.Identity; using Azure.ResourceManager; using Azure.ResourceManager.DurableTask; using Azure.ResourceManager.DurableTask.Models; using Azure.ResourceManager.Resources; // Setup var credential = new DefaultAzureCredential(); var armClient = new ArmClient(credential); var subscriptionId = Environment.GetEnvironmentVariable("AZURE_SUBSCRIPTION_ID")!; var resourceGroupName = Environment.GetEnvironmentVariable("AZURE_RESOURCE_GROUP")!; var subscription = armClient.GetSubscriptionResource( new ResourceIdentifier($"/subscriptions/{subscriptionId}")); var resourceGroup = await subscription.GetResourceGroupAsync(resourceGroupName); // Create scheduler var schedulerData = new DurableTaskSchedulerData(AzureLocation.EastUS) { Properties = new DurableTaskSchedulerProperties { Sku = new DurableTaskSchedulerSku(DurableTaskSchedulerSkuName.Dedicated) { Capacity = 1 } } }; var schedulerCollection = resourceGroup.Value.GetDurableTaskSchedulers(); var schedulerOp = await schedulerCollection.CreateOrUpdateAsync( WaitUntil.Completed, "my-scheduler", schedulerData); var scheduler = schedulerOp.Value; Console.WriteLine($"Scheduler endpoint: {scheduler.Data.Properties.Endpoint}"); // Create task hub var taskHubData = new DurableTaskHubData(); var taskHubOp = await scheduler.GetDurableTaskHubs().CreateOrUpdateAsync( WaitUntil.Completed, "my-taskhub", taskHubData); var taskHub = taskHubOp.Value; Console.WriteLine($"Task Hub: {taskHub.Data.Name}"); // Cleanup await taskHub.DeleteAsync(WaitUntil.Completed); await scheduler.DeleteAsync(WaitUntil.Completed); ``` ## Related SDKs | SDK | Purpose | Install | |-----|---------|---------| | `Azure.ResourceManager.DurableTask` | Management plane (this SDK) | `dotnet add package Azure.ResourceManager.DurableTask` | | `Microsoft.DurableTask.Client.AzureManaged` | Data plane (orchestrations, activities) | `dotnet add package Microsoft.DurableTask.Client.AzureManaged` | | `Microsoft.DurableTask.Worker.AzureManaged` | Worker for running orchestrations | `dotnet add package Microsoft.DurableTask.Worker.AzureManaged` | | `Azure.Identity` | Authentication | `dotnet add package Azure.Identity` | | `Azure.ResourceManager` | Base ARM SDK | `dotnet add package Azure.ResourceManager` | ## Source Reference - [GitHub: Azure.ResourceManager.DurableTask](https://github.com/Azure/azure-sdk-for-net/tree/main/sdk/durabletask/Azure.ResourceManager.DurableTask) - [NuGet: Azure.ResourceManager.DurableTask](https://www.nuget.org/packages/Azure.ResourceManager.DurableTask)