Skip to content

0004 — Cloud/hosting stack, CI/CD, and free-tier path ​

Status: Accepted — compute and database choices partially superseded by ADR 0024 (2026-06-18: API compute Azure Functions → containerized on Azure Container Apps; database Azure SQL Serverless → Postgres on Azure DB for PostgreSQL Flexible Server). CI/CD, web app hosting, storage, and Key Vault choices below remain in force. The public/marketing site decision has been superseded: there is no public or marketing site — see Web app hosting below.

Date: 2026-06-17

ADO work item: AB#3073

Deciders: Kristopher Turner (platform owner)


Context ​

The platform needs compute (API), a relational database, file/media storage, web app hosting, and a CI/CD pipeline. The community is small (~200 members) and cost-sensitive — the constraint is free or near-free tiers, with a path to scale once Microsoft Nonprofits Azure credits (~$3,500/yr) are approved.

Two questions were evaluated in Phase-0 research:

  1. CI/CD: GitHub Actions vs ADO Pipelines — the code already lives on GitHub (Heritage-Virginia org); ADO Boards is the work-tracking tool (separate concern).
  2. Compute/DB stack fork: Azure-native vs Supabase-native — affects the database, API compute, and storage layer. This question was not resolved in Phase-0 (all Supabase-specific claims were refuted for lack of independent sourcing; Azure specifics similarly sparse). Requires a dedicated second research pass.

Decision — decided items ​

CI/CD: GitHub Actions (decided) ​

We will use GitHub Actions (.github/workflows/) for all CI/CD. The existing workflow files remain; ADO Pipelines is not adopted for this repository.

Research basis (Phase-0, verified 2026-06-17):

  • ADO Pipelines free tier for private projects: 1,800 min/month cap, 60-min per-run limit. The free parallel-jobs grant is not given by default to new organizations — it must be requested and takes several business days to activate. Source: Microsoft Learn (updated 2026-05-07), verified 3-0.
  • GitHub Actions reduced hosted-runner pricing by up to 39% (by machine type), effective 2026-01-01. Source: GitHub changelogs (Dec 2025 + Jan 2026), verified 3-0.
  • The code is already on GitHub. Keeping CI/CD there eliminates cross-system token management and event routing.

Note: ADO Boards remains the work-tracking tool (separate from CI/CD). AB# links in commits trigger ADO work-item updates via the GitHub + ADO integration — this works regardless of which CI/CD system is used.

Web app hosting: Azure Static Web Apps Free — heritageva.app (decided) ​

We will host apps/web (the community web app) on Azure Static Web Apps (Free) with the custom domain heritageva.app (HTTPS-only). The web app is an installable PWA: it includes a web app manifest (standalone display, icons including maskable, start_url=/, theme/background colour), a service worker for installability and offline shell, and appropriate icons. Users may install it to the desktop or home screen via the browser's Install prompt; it opens in its own window exactly like a native app.

There is no public or marketing site. No separate landing page. No "coming soon" gate. Going to heritageva.app opens directly to the sign-in / register screen — the same entry point as opening the iOS or Android app. The web app (apps/web) is the first usable client of the platform API and serves as the testbed before the iOS app ships.

Since Clerk handles auth client-side (ADR 0003), the custom OIDC restriction on SWA Free is not a blocker. Azure SWA Free provides 100 GB bandwidth/month and 0.5 GB storage — adequate for a ~200-member community.

Infrastructure naming (CAF/WAF, HCS tenant, heritageva workload token):stapp-heritageva-prod-<region> hosted in resource group rg-heritageva-prod-<region> in the existing HCS Azure tenant/subscription. Custom domain heritageva.app is wired in Cloudflare DNS at deploy time (CNAME/TXT validation against the live SWA endpoint). All resources carry tags: workload=heritageva, env=prod, owner=Kristopher Turner.

Note: New ADRs for the web frontend client model and the heritageva.app domain assignment are to be authored separately; they will supersede the earlier GitHub Pages decision recorded in the Phase-0 research notes.

Compute/DB stack: Azure-native (decided) &ZeroWidthSpace;

Azure Functions (Consumption) + Azure SQL Serverless + Azure Blob Storage.

⚠️ Superseded in part by ADR 0024 (2026-06-18): on portability grounds, API compute moved from Azure Functions to a containerized API on Azure Container Apps, and the database moved from Azure SQL Serverless to Postgres on Azure Database for PostgreSQL Flexible Server. Azure Blob Storage (behind a StorageProvider interface), Key Vault, Azure SWA (now confirmed as the web app host with custom domain heritageva.app), and GitHub Actions are unchanged. Read the table below with those two substitutions in mind.

Rationale:

  • kv-hcs-vault-01 already exists in Azure; the team is Azure-native (Microsoft MVP).
  • Microsoft Nonprofits credits (~$3,500/yr once approved) cover all costs — Supabase has no equivalent credit path.
  • Since Clerk handles auth (ADR 0003), Supabase's primary advantage (bundled auth + DB) does not apply. Choosing Supabase without its auth layer is just a Postgres host — Azure SQL Serverless is equally free and keeps everything in one platform.
  • Simplest ops at ~200 members: one portal, one billing account, one IaC tool (Bicep), one set of alerts. Supabase managed adds a second platform; Supabase self-hosted on Azure adds real ops overhead.
  • Azure Functions Consumption: 1M free executions/month — sufficient for a community of 200.
  • Azure SQL Serverless: pauses when idle, free tier covers early-stage usage.
ServiceTierNotes
Web app (apps/web)Azure SWA Free — custom domain heritageva.appInstallable PWA; opens to sign-in/register; 100 GB BW/month; Clerk handles auth client-side; named stapp-heritageva-prod-<region>
API (apps/api)Azure Functions Consumptioncontainerized on Azure Container Apps (ADR 0024)Portable OCI image; Container Apps free tier covers low traffic; named ca-heritageva-api-prod-<region>
DatabaseAzure SQL ServerlessPostgres on Azure DB for PostgreSQL Flexible Server (ADR 0024)Portable dialect; burstable low-cost tier; Nonprofits credits cover production; named psql-heritageva-prod-<region>
File/media storageAzure Blob Storage (Hot)Pennies at small scale
SecretsKey Vaultkv-heritageva-prod-<region> (dedicated, heritageva-branded); existing kv-hcs-vault-01 used during development
CI/CDGitHub ActionsFree for public repos; 2,000 min/month for private

Alternatives considered (CI/CD) &ZeroWidthSpace;

OptionProsConsWhy not chosen
GitHub Actions (chosen)Code already on GitHub; 39% price reduction Jan 2026; no grant friction; existing workflowsSeparate from ADO Boards (by design)— chosen
ADO PipelinesUnified with ADO Boards; enterprise featuresFree grant not given by default; 1,800 min/month cap; multi-day activation waitFriction not justified; CI/CD and work-tracking are separate concerns

Consequences &ZeroWidthSpace;

Positive &ZeroWidthSpace;

  • GitHub Actions is immediately usable (no grant request, no wait).
  • Azure SWA Free + Clerk sidesteps the custom OIDC plan gate.
  • Azure SWA Free with the custom domain heritageva.app keeps all web hosting in one platform at zero incremental cost.
  • The web app as an installable PWA gives members a native-app-like experience before the iOS and Android apps ship.
  • The API-first architecture (ADR 0001) means the compute layer can be swapped without touching web or mobile clients.

Negative / trade-offs &ZeroWidthSpace;

  • Azure SWA Free has no SLA and is taken offline on quota overage. Acceptable for a community of ~200; monitor bandwidth usage and upgrade to Standard if needed under nonprofit credits.
  • Azure SQL Serverless has a cold-start pause delay after idle periods. Acceptable for a small community; document in the DR runbook.

Risks &ZeroWidthSpace;

  • Microsoft Nonprofits Azure credits — the research claim that Microsoft offers nonprofits $2,000–$3,500/yr in Azure credits was refuted 0-3 for lack of independent sourcing. Verify eligibility directly at microsoft.com/nonprofits before assuming Azure credits are available.
  • ADO Pipelines free-grant re-enablement — Microsoft docs note the free grant restriction is "temporarily disabled" (as of 2026-05-07). If re-enabled, the ADO Pipelines free-tier constraint disappears. Monitor; the GitHub Actions decision stands on cost and co-location merits regardless.

References &ZeroWidthSpace;

Heritage Community Hub — Internal. Access restricted via Cloudflare Access + Entra ID.