Skip to content

Migrate sample to Azure Durable Task Scheduler (DTS) backend#29

Open
torosent wants to merge 7 commits into
Azure-Samples:masterfrom
torosent:feat/migrate-to-dts
Open

Migrate sample to Azure Durable Task Scheduler (DTS) backend#29
torosent wants to merge 7 commits into
Azure-Samples:masterfrom
torosent:feat/migrate-to-dts

Conversation

@torosent
Copy link
Copy Markdown

@torosent torosent commented Apr 23, 2026

Migrate to Azure Durable Task Scheduler (DTS) + modern Node SDK

This PR brings the JavaScript fan-out/fan-in API-scraping sample onto the modern stack:

  1. Azure Storage backend → Azure Durable Task Scheduler (DTS).
  2. Deprecated azure-storage SDK → @azure/data-tables + @azure/identity for the Repositories Table read/write, with managed-identity auth in cloud.

What changed

  • FanOutFanInCrawler/host.jsonstorageProvider.type: "azureManaged" + connectionStringName: "DURABLE_TASK_SCHEDULER_CONNECTION_STRING". Default Azure-Storage bindings remain enabled.
  • FanOutFanInCrawler/package.json — dropped azure-storage@^2.10.4 (deprecated, no MI support); added @azure/data-tables@^13.3.1 + @azure/identity@^4.5.0. durable-functions retained.
  • FanOutFanInCrawler/SaveRepositories/index.js — rewritten to use TableClient from @azure/data-tables with this precedence:
    1. Explicit StorageConnectionString env var (test/local override).
    2. Managed identity via AzureWebJobsStorage__tableServiceUri + optional AzureWebJobsStorage__clientId and DefaultAzureCredential (cloud).
    3. Bare AzureWebJobsStorage connection string (Azurite/local fallback).
      Inserts now use Table Storage transactional batches in chunks of 100 (the service limit).
  • FanOutFanInCrawler/local.settings.json.sample — added DURABLE_TASK_SCHEDULER_CONNECTION_STRING + TASKHUB_NAME.
  • infra/ — new app/dts.bicep provisioning Microsoft.DurableTask/schedulers@2026-02-01 + taskHubs@2026-02-01. UAMI gets Durable Task Data Contributor on the task hub and Storage Table Data Contributor on the Storage account. vnetEnabled defaults to false.
  • provision.ps1 — removed (legacy pre-DTS provisioning script).
  • README.md — DTS-first instructions.

Verification

  • npm install clean.
  • ✅ Both new packages import without errors.
  • ✅ Local: emulator + func start + Azurite, fan-out/fan-in completes, Repositories table populated.
  • ✅ Cloud: azd up, orchestration completes, table populated under managed identity, run appears in DTS dashboard, azd down --force --purge clean.

Notes

  • API version 2026-02-01 (DTS GA).
  • Dead skuCapacity parameter removed from dts.bicep and main.bicep.

Copilot AI and others added 7 commits April 23, 2026 10:19
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Drop .Preview suffix from extension bundle id (Microsoft.Azure.Functions.ExtensionBundle)
  where the standard bundle already provides azureManaged support.
- Bump .NET package versions to match GA samples in Azure-Samples/Durable-Task-Scheduler:
  Worker 2.1.0, Worker.Sdk 2.0.7, Worker.Extensions.DurableTask 1.2.2,
  Worker.Extensions.DurableTask.AzureManaged 0.4.1-alpha.
- Add TaskHub=default segment to the emulator connection string in local.settings.json.sample.
- Update README wording to reflect DTS GA status (not preview).

Refs: https://github.com/Azure-Samples/Durable-Task-Scheduler/tree/main/samples/durable-functions

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Update Microsoft.DurableTask/schedulers and
Microsoft.DurableTask/schedulers/taskHubs from 2025-04-01-preview to
the GA API version 2026-02-01 in dts.bicep / dts-Access.bicep.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Switching the Durable Task backend to DTS does not eliminate the
need for queue and table services on the AzureWebJobsStorage
account. They are still required by the Functions host and by
several non-Durable triggers/bindings (timer singleton leases,
host metadata, OpenAI bindings, MCP trigger, etc.).

Revert enableQueue/enableTable to true and update the surrounding
comment accordingly.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The migration commit accidentally bumped durable-functions from ^1.5.3
to ^3.1.0, but durable-functions v3 requires the v4 programming model
(app.generic registrations) — incompatible with this sample's v2 model
(folder-per-function with function.json + df.orchestrator()).

DTS support flows through the host extension bundle / storageProvider
config, NOT the npm package, so v2 of durable-functions works perfectly
with DTS as long as the host loads a DTS-aware extension bundle.

Verified locally with the DTS emulator: blob_trigger, orchestrator,
and activity functions all execute through the DTS task hub.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…-tables + DefaultAzureCredential; default vnetEnabled=false; drop dead skuCapacity plumbing; remove legacy provision.ps1

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Round-2 review found that principalType was parameterized for the DTS
dashboard role assignment but the four deployer storage/queue/table/
appInsights role assignments in app/rbac.bicep still hardcoded 'User'.
Under a service-principal deployer in CI this can fail with
PrincipalNotFound. Threaded principalType -> userIdentityPrincipalType
through the rbac module to keep the principal-type story consistent
across all deployer assignments.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants