Skip to content

Speed up AAD setup by reconciling transient Graph 404s - #5888

Merged
Mikael Weaver (mikaelweave) merged 5 commits into
mainfrom
personal/mikaelw/speed-up-aad-setup
Oct 2, 2026
Merged

Mikael Weaver (mikaelweave) merged 5 commits into
mainfrom
personal/mikaelw/speed-up-aad-setup

Conversation

@mikaelweave

@mikaelweave Mikael Weaver (mikaelweave) commented Oct 1, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • Retry only transient HTTP 404s from the read-only Microsoft Graph check after an ambiguous delegated-permission POST; preserve the original write error and do not reissue a write without a successful read.
  • Add secret-safe per-phase and per-client elapsed-time markers to Setup AAD so follow-up optimizations can target measured costs.

Evidence

In PR Build & Deploy 51871, Setup AAD took 13m12s. A User.Read consent POST returned Directory_ObjectNotFound, then its reconciliation GET returned NotFound, causing the entire task to retry and replay earlier client provisioning. The retry path is reproduced locally against the real PowerShell function and a fake Graph endpoint; it fails before this fix and passes afterward. Other read errors still fail fast.

This follows merged #5887 on a fresh branch from main. No package or SQL fixture updates are included. A live PR run will establish the new phase timings; it may not hit the intermittent Graph race on every execution.

AB#208533

When a delegated-permission POST fails ambiguously (Directory_ObjectNotFound
or an already-exists conflict), the read-only reconciliation GET can also
return HTTP 404 while the new client service principal replicates. That read
error escaped immediately, surfaced the original POST error, failed the AAD
setup task, and triggered a full task retry (build 51871: +3m18s replay).

Retry only HTTP 404 reconciliation reads whose Graph code is absent,
Request_ResourceNotFound, or Directory_ObjectNotFound, with bounded backoff
(5, 10, 20, 40 seconds). Other read errors and exhausted retries still
surface the original POST error, and a grant is re-POSTed only after a
successful read confirms it is absent.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add "AAD setup timing:" lines for the setup phases and for each of the
test client applications (lookup, credential, delegated grant, Key Vault
write, role assignment, and scratch SecretManagement round-trip time), so
pipeline runs can show where the setup task spends its time. The lines
contain only durations, positions, and test-configuration keys; no
secrets, Graph identifiers, headers, or response bodies.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@mikaelweave

Copy link
Copy Markdown
Contributor Author

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).

The test introduced after the xUnit v3 migration still used SkippableTheory and Skip.IfNot, which fail to compile under the current test framework.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@mikaelweave

Copy link
Copy Markdown
Contributor Author

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).

Each client staged its secret and app ID through the default SecretManagement
vault (the test Key Vault) with Set-Secret/Get-Secret before writing the real
app--<id>--* entries. That cost four Key Vault round trips per client (43-52s
across 15 clients in builds 51877/51880) and left secretSecure/appIdSecure
copies that e2e-set-variables exports with every other test Key Vault secret.

Wrap the in-memory values with ConvertTo-SecureString instead. The values
written to Key Vault are unchanged; Set-FhirServerApiUsers still uses the
registered vault, so the registration stays. Drop the scratchVaultMs timing
field, which no longer measures anything.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@mikaelweave

Copy link
Copy Markdown
Contributor Author

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).

@codecov-commenter

Codecov Comments Bot (codecov-commenter) commented Oct 1, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
⚠️ Please upload report for BASE (main@2ec6878). Learn more about missing BASE report.

Additional details and impacted files

Impacted file tree graph

@@           Coverage Diff           @@
##             main    #5888   +/-   ##
=======================================
  Coverage        ?   79.05%           
=======================================
  Files           ?     1020           
  Lines           ?    37428           
  Branches        ?     5728           
=======================================
  Hits            ?    29589           
  Misses          ?     6393           
  Partials        ?     1446           
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

New client applications now request their password credential in the same
New-MgApplication (POST /applications) call, using the documented
passwordCredentials create body, and read secretText once from the 201
response. This removes the separate Add-MgApplicationPassword call and its
propagation retry loop (18 waits, roughly 136s, across 15 clients in build
51884), which existed only because the new application object was not yet
addressable for addPassword.

If Graph does not return a secret, fail explicitly without echoing any
credential data. The existing-application rotation path, service principal
creation/retry, and Key Vault secret writes are unchanged.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@mikaelweave

Copy link
Copy Markdown
Contributor Author

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).

@mikaelweave Mikael Weaver (mikaelweave) added the Open source This change is only relevant to the OSS code or release. label Oct 2, 2026
@mikaelweave
Mikael Weaver (mikaelweave) merged commit 01f013d into main Oct 2, 2026
49 of 51 checks passed
@mikaelweave
Mikael Weaver (mikaelweave) deleted the personal/mikaelw/speed-up-aad-setup branch October 2, 2026 14:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Build No-ADR ADR not needed No-PaaS-breaking-change Open source This change is only relevant to the OSS code or release.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants