deploy: make base-infra Postgres optional for bring-your-own database - #92
waldemort-auto[bot] wants to merge 4 commits into
Conversation
Adds a deployPostgres bool param (default true) so base-infra can skip provisioning a PostgreSQL flexible server when the environment already supplies DATABASE_URL / PILOTSWARM_CMS_FACTS_DATABASE_URL. Default behaviour is unchanged: deployPostgres defaults to true, so every existing stamp compiles and deploys byte-identically. Follows the existing conditional-module convention in this file (AppGateway, VpnGateway, Foundry). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
I reviewed this for the next PilotSwarm release payload. The conditional Bicep module compiles, and
Validation: I built this PR's |
Addresses review feedback on the conditional Postgres module. 1. Wire it through the supported deploy path. base-infra.params.template.json now passes deployPostgres from a new DEPLOY_POSTGRES env key, documented in deploy/envs/template.env. Previously only a direct Bicep invocation could reach the parameter, so an operator always got the default. 2. Do not let cached outputs point the worker at the old server. composeDerivedEnv now drops stale POSTGRES_* under DEPLOY_POSTGRES=0 and requires both connection strings; saveCache evicts a key whose new deployment output is empty. 3. Make the auth mode explicit. Under DEPLOY_POSTGRES=0, PILOTSWARM_USE_MANAGED_IDENTITY=1 now requires PILOTSWARM_DB_AAD_USER. Tests: compose-env 16/16, bicep-outputs-cache 7/7, az bicep build OK. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Pushed 1. Deployer wiring. 2. Stale cached outputs. Confirmed your reading: 3. Auth decision. Tests. Added 4 Still not covered, and worth saying plainly: no live deployment has been run with |
…safe Normalize DEPLOY_POSTGRES once with old-env defaults and legacy 1/0 support. Validate BYO settings only for secret and runtime-manifest consumers. Seed or resolve versioned Key Vault references and project connection URLs through CSI-backed Secrets, omitting URLs and unused AAD users from ConfigMaps. Wire independent Blob managed identity through SDK and worker entrypoints. Cover the actual deploy CLI, all overlay modes, and runtime option forwarding. Validation: 207 deploy tests, 16 auth tests, 10 storage tests, SDK build, Bicep compile, and six offline Kustomize renders. No live database rollout. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Ignore ambient database URLs on the provisioned path, including scaffolded blank keys, and warn without exposing values. Normalize intent once. Verify supplied BYO URLs against the selected immutable Key Vault version in memory; fail before publishing if they differ, without logging responses. Keep provisioned AAD ConfigMap keys and clarify base/database SPC contracts. Addresses adversarial review findings with 11 added regression cases. Validation: 218 deployment tests and six offline Kustomize renders pass. SDK/Bicep code is unchanged from the earlier validated rework. No live database or application rollout was performed. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
What changes
The supported Node deploy path can skip its PostgreSQL Flexible Server module and use an existing PostgreSQL-compatible database, including a HorizonDB cluster. This requires deploy-script and runtime-auth changes, not just a conditional Bicep module.
DEPLOY_POSTGREStrue/falseand legacy1/0, normalized to a JSON boolean. Defaults totrue, including for old env files without the key. Invalid or empty values fail.DATABASE_URLandPILOTSWARM_CMS_FACTS_DATABASE_URL, or their*_SECRET_NAMEreferences. BYO URLs use version-pinned Key Vault/CSI Secrets and explicitsecretKeyRefentries, not ConfigMaps.seed-secrets. Reference-only mode resolves identifiers without exporting values.PILOTSWARM_USE_MANAGED_IDENTITY=0selects password auth;1selects Entra and requires the externally registeredPILOTSWARM_DB_AAD_USER. The AAD-user key is omitted for password BYO.PILOTSWARM_BLOB_USE_MANAGED_IDENTITYis now forwarded independently through both deployed worker entrypoints and the SDK option. It defaults to1on this deployment path and must not be disabled merely because the database uses a password.Validation is stage-scoped: database-independent
--stepsinvocations do not need BYO credentials. Empty Postgres outputs evict stale cache entries; BYO composition ignores stale provisioned outputs. The conditional module and both guarded output dereferences remain intact.See the deployment README for setup and split-deployment instructions.
Authorship and review history
The first two commits were produced with Claude Opus 5 and did not provide a working supported BYO deployment. An adversarial GPT-6 Astra review returned BLOCK: boolean rendering, old env compatibility, password auth, shared Blob auth, stage dispatch, and ConfigMap credential exposure were not handled safely.
GPT-6 Astra reworked the change in
329c79bf. An independent Opus 5 reviewer then returned REQUEST-CHANGES, identifying an ambient-URL regression and a stale Key Vault value problem, plus smaller scope and documentation defects. Those findings were addressed in2263633d. A proposed CSI cold-start regression was withdrawn after source-based rebuttal; versioned Secret references remain. The same reviewer re-read the pushed fixes and returned APPROVE, with all original findings and all open follow-up findings resolved. The independent approval covers the PR changes; the newer-main integration was subsequently tested separately.Evidence and tested base
npm run test:deploy-scripts, 24 files). The original-base run was 218; the count is higher because the newer main commits add test files, so the merged suite is a superset. Includes the real deploy CLI with external CLIs simulated, fresh/stale cache paths, old env files, ambient URL rejection, and raw URL/version agreement.npm run test:unit --workspace=packages/sdk). This suite contains the Blob/worker-auth and storage-resolver cases relied on by this change.npm run buildexits 0 on the merge snapshot, coveringpackages/sdk,pilotswarm-horizon-store,pilotswarm, the MCPtscpass, and the portal Vite build.postgres://orpostgresql://string appears anywhere in the rendered output, and no BYO ConfigMap carries a URL.deploy/services/base-infra/bicep/main.bicepresolves to the identical blob4621abc2d13127fd129f741723a93707df83aaabin both the merge tree and the PR head, so the newer main commits do not touch it and the earlier successfulaz bicep buildstill applies..ts,.mjsor.yamlfile. No manual resolution was needed.Original tested base:
29f7de792913a01ce4ccb71a8973a323967884de.Merge-result revalidation, 2026-09-16: run against
refs/pull/92/merge= commit82032bcd8ac137c28c73f908f7ac201dfad46fd9, treea0df94384b16ecb68f8b3973ea7b2fa7648c2887, whose parents are main091de4c7b175ec19f75fedb57c2515c99592db53and the pushed PR head2263633d6426b393b77ab5a272ea87d60e0540fb. The tested tree SHA was verified against GitHub's own merge preview before the suites ran, so the results above describe the exact tree GitHub produces for this merge rather than a locally approximated one.This revalidation was performed by the Waldemort parent session, separately from the agent that authored the change. An earlier revision of this description reported the merge-snapshot results as 218 deployment tests with a recompiled Bicep template; those figures were not produced by an executed merge-snapshot run and have been replaced above with the observed results.
The eight newer main commits change 3
deploy/paths and 46packages/sdk/paths, overlapping this change in the environment template, worker overlay, SDK worker implementation, and SDK types; dependencies and CMS migrations also change.packages/sdk/src/worker.tsandtypes.tsare modified by both sides, so a clean merge status was not treated as evidence. After the merge, this change's behavior survives intact:worker.tsstill forwardsPILOTSWARM_BLOB_USE_MANAGED_IDENTITYonly when the SDK option is set, andtypes.tsstill declaresblobUseManagedIdentity.Rotation behavior was also checked empirically: rendering one overlay twice, changing only the Key Vault secret version, produces a different versioned Secret name, and that name appears directly in
secretKeyRef.nameand the CSIsecretProviderClassvolume attribute on the pod template. A version change therefore alters the pod template and forces a rollout, which covers value rotation as well as key-set changes.The validation used an unreferenced merge snapshot. No branch refs or existing worktrees changed; there was no rebase, force-push, or merge. Local bookkeeping commit
2ffc79d9and pushed commit2263633dshare the complete tree55564aa21fa717d8815946423b1fa3183e362853; their commit metadata and ancestry differ, not their files. The merge inputs were the pushed commit and newer main, not local HEAD.Not verified: no live deployment has been run against a real external database. All evidence is unit tests, offline Kustomize renders, and a type-checked build. Live Azure API behavior, CSI synchronization timing, and HorizonDB migrations, extensions, grants and schema isolation remain untested.
Main advanced again after this revalidation, so these results describe the merge with
091de4c7, not with the newest tip at the time of reading.Deliberately outside this change