Skip to content

[EDFI-2887] Add Azure SQL support to the windows-install scripts - #10

Open
analiliagutierrez wants to merge 3 commits into
mainfrom
EDFI-2887_Azure_SQL_Support
Open

[EDFI-2887] Add Azure SQL support to the windows-install scripts#10
analiliagutierrez wants to merge 3 commits into
mainfrom
EDFI-2887_Azure_SQL_Support

Conversation

@analiliagutierrez

@analiliagutierrez analiliagutierrez commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds support for deploying the Admin App database on a managed Azure SQL Database to the windows-install scripts. A non-loopback -SqlServerHost switches the mssql path into remote mode: the local-instance setup is skipped, a contained database user is provisioned as a SQL admin and the server certificate is validated. All new parameters default to the local path, so existing local SQL Server installs are unchanged.

What Changed

  • New parameters across install-all.ps1 / 02-prereqs-sql.ps1 / 05-deploy-api.ps1 / uninstall.ps1 / 00-check-prereqs.ps1: -SqlServerHost, -SqlServerPort, -SqlAdminUsername, -SqlAdminPassword, -TrustServerCertificate. A non-loopback host is the switch into remote mode.
  • 02-prereqs-sql.ps1: for a remote target, skip the local-instance steps (registry Mixed Mode/TCP, service restart) that have no Azure equivalent; verify SQL admin connectivity, then provision a contained user (CREATE USER ... WITH PASSWORD + db_owner) instead of CREATE LOGIN + USE [db], since Azure SQL supports neither.
  • 05-deploy-api.ps1: set MSSQL_DB_HOST/MSSQL_DB_PORT from the parameters and default DB_TRUST_CERTIFICATE to false for a remote target (Azure presents a valid CA certificate); use the resolved host in the encryption-key guard and OIDC reconcile.
  • QUOTED_IDENTIFIER ON (sqlcmd -I) on the installer's MSSQL DML (OIDC reconcile, admin-user upsert), fixing a latent Msg 1934 against the filtered indexes on [user]/[oidc].
  • uninstall.ps1: a remote teardown path drops only the contained user (SQL admin auth) and leaves the managed database intact (operator-owned).
  • 00-check-prereqs.ps1: remote-aware — skips the local-instance checks (which would otherwise FAIL with no local SQL Server) and lists the Azure prerequisites.
  • Fail-fast password check: for a remote target, reject an -AppDbPassword that contains the login name, which Azure rejects with an opaque Msg 40632.
  • README: documents the Azure SQL target, operator prerequisites, and parameters.
  • Retry the remote SQL admin connectivity check (from the self-review): a serverless Azure SQL database resuming from auto-pause is no longer misreported as unreachable, and the failure message hints at a resuming database.
  • Reject -SqlServerHost when -DbEngine is not mssql (from the self-review) instead of silently ignoring it, in install-all.ps1 and 05-deploy-api.ps1.

Architectural Decisions

  • Parameterized the existing scripts instead of a separate Azure path. The DB host and provisioning are the only real divergence; a separate script would still require the same edits to 05/00/install-all/uninstall plus duplicated helpers — more code, not less. Only 02 and uninstall carry real branching.
  • The operator pre-creates the Azure logical server, firewall rule, and empty database (these need the Azure control plane, not sqlcmd); the app self-migrates its schema on first boot, so no manual migration step is required.
  • SQL admin authentication for remote provisioning. The Admin App connects as a SQL-authenticated contained user, so SQL authentication must be enabled on the server anyway, which makes the SQL admin login the natural provisioning credential.
  • The small remote-detection/trust helpers are duplicated per script, matching this folder's existing self-contained (no dot-sourcing) convention.

Testing

Automated

The windows-install scripts have no unit-test harness in this repository. Validation: every changed script parses under Windows PowerShell 5.1 and PowerShell 7; and function-level tests of the new helpers (remote-target detection across localhost/(local)/IP/FQDN/named-pipe/machine-name; the password-vs-username check) pass in both editions.

Manual

Local SQL Server regression (nothing broke):

  1. uninstall.ps1 -Forceinstall-all.ps1 -IdpProvider keycloak (default local mssql).
  2. Sign in via Keycloak and create a Team. All green.

Azure SQL end-to-end:

  1. Create the logical server (SQL auth + admin login), a firewall rule for the client IP, and an empty sbaa database.
  2. install-all.ps1 -IdpProvider keycloak -SqlServerHost <server>.database.windows.net -SqlAdminUsername <admin> -SqlAdminPassword <...> -AppDbPassword <...> ...
  3. Expected: SQL admin connectivity confirmed → contained user provisioned and verified → OIDC connection row reconciledAdmin user present with roleId=2INSTALL COMPLETE with the summary showing the managed server.
  4. Sign in, create a Team, and confirm the row lands in Azure (SELECT name FROM [team] against the Azure DB).
  5. uninstall.ps1 -Force -SqlServerHost <...> -SqlAdminUsername <...> -SqlAdminPassword <...> → drops only the contained user; the managed database is left intact.

Error path: a remote target with no -SqlAdminUsername, an unreachable database, or an -AppDbPassword containing the login name each fail up front with an actionable message.

Known Limitations / Follow-Up

  • Documentation of Azure SQL as a supported Admin App database is tracked separately (EDFI-2888).
  • The URL-safe restriction on the DB password is unchanged (the app does not yet URL-encode its DB credentials); it applies to local and remote alike.

Note: this branch also includes a small, separately-ticketed fix (EDFI-2893, commit 2a19ed9). 04-build.ps1 now compares VITE_API_URL, VITE_BASE_PATH, and VITE_IDP_ACCOUNT_URL when deciding whether the front-end bundle is current, so switching the identity provider or the base path on the same API URL no longer skips the rebuild (previously it baked stale values into the bundle). Touches only windows-install/04-build.ps1, with no overlap with the Azure SQL changes.

Checklist

  • Automated tests added or updated — N/A (no harness for these scripts; see Testing)
  • Manually tested (happy path + error path) — local and Azure SQL E2E
  • Branch is up to date with target branch
  • Commit history is clean and includes ticket ID
  • No commented-out code or TODO comments
  • PR is focused on this ticket only

Allow the installer to target a managed Azure SQL Database while keeping
local SQL Server installs unchanged. A non-loopback -SqlServerHost switches
to remote mode: skip the local-instance setup (registry, TCP, service
restart), provision a contained user as the SQL admin, and validate the
server certificate. All new parameters default to the local path, so
existing invocations are unaffected.

Also set QUOTED_IDENTIFIER ON (sqlcmd -I) for the installer's OIDC/user
DML on MSSQL, fixing the latent Msg 1934 against the filtered indexes.
- Retry the remote SQL admin connectivity check (6x, -l 30) so a serverless
  Azure SQL database resuming from auto-pause is not reported as unreachable,
  and add the serverless hint to the failure message.
- Reject -SqlServerHost when -DbEngine is not 'mssql' (install-all and 05)
  instead of silently ignoring it.
@analiliagutierrez
analiliagutierrez marked this pull request as ready for review August 11, 2026 22:17
04-build.ps1 treated the front-end build as current based only on
VITE_API_URL, so switching the identity provider (VITE_IDP_ACCOUNT_URL)
or the base path (VITE_BASE_PATH) on the same API URL skipped the rebuild
and left stale values baked into the bundle. Compare all three baked Vite
values so a change to any of them triggers a rebuild.
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.

1 participant