Pipelines
All services use Azure DevOps pipelines defined in azure-pipelines.yml files in their respective directories. Pipelines share common templates for Docker builds and Cloudflare deployments.
Pipeline patterns
Section titled “Pipeline patterns”Backend pipeline (Cloud Backend / Management Backend)
Section titled “Backend pipeline (Cloud Backend / Management Backend)”flowchart LR
A[Push to master] --> B[Checkout]
B --> C[Security scanning - govulncheck / trivy / gitleaks / SBOM]
C --> D[Build Docker image]
D --> E[Push to ACR]
E --> F[Deploy to Container App]
F --> G[Run Flyway migrations]
G --> H[Health check]
Triggered by pushes to master with path filters (e.g. only when files under Backend/ change).
Ingestor pipeline
Section titled “Ingestor pipeline”Same Docker → ACR → Container Apps template as other Go backends, but no Flyway step — the ingestor has no db/migration/ directory; schema is owned by the Cloud Backend migrations. Pipeline uses deployMode: app only.
flowchart LR
A[Push to master] --> B[Checkout]
B --> C[Security scanning]
C --> D[Build Docker image]
D --> E[Push to ACR]
E --> F[Deploy to Container App]
F --> G[Health check]
Frontend pipeline (Cloud SPA / Management SPA / Website / Docs)
Section titled “Frontend pipeline (Cloud SPA / Management SPA / Website / Docs)”flowchart LR
A[Push to master] --> B[Checkout]
B --> C[npm install + npm run build]
C --> D[Security scanning - npm audit / license-checker]
D --> E[Deploy to Cloudflare Pages]
Variable groups
Section titled “Variable groups”| Group | Used by | Contains |
|---|---|---|
cloudflare-cloud | All Cloudflare deployments | CLOUDFLARE_API_TOKEN, CLOUDFLARE_ACCOUNT_ID, project names |
cloud-backend-build | Cloud Backend pipeline | imageRepository (cloud-backend) |
cloud-backend-dev | Cloud Backend dev pipeline | Web App name/RG, SQL, ACR, service connections |
cloud-backend-prd | Cloud Backend prod pipeline | Same, production values |
cloud-ingestor-build | Ingestor pipeline | imageRepository (cloud-ingestor) |
cloud-ingestor-dev | Ingestor dev pipeline | Ingestor Web App name/RG, ACR, service connections |
cloud-ingestor-prd | Ingestor prod pipeline | Same, production values |
manage-backend-build | Management Backend pipeline | imageRepository |
manage-backend-dev | Management Backend dev | App settings |
manage-backend-prd | Management Backend prod | App settings |
Security scanning
Section titled “Security scanning”Backend pipelines run:
govulncheck— Go vulnerability scanner (known CVEs in dependencies)trivy image— Container image scanning (OS packages + Go deps)gitleaks— Secret detection in source code- SBOM generation — Software Bill of Materials (CRA compliance)
Frontend pipelines run:
npm audit— Node.js dependency vulnerability checklicense-checker— License compliance verification
Flyway migration step
Section titled “Flyway migration step”After each Cloud Backend or Management Backend deploy (deployMode: both or migrate), the pipeline runs Flyway migrations against that service’s database. The migration connection string uses the service’s Managed Identity and is scoped to the deployment environment.
The Ingestor pipeline uses deployMode: app only — it shares the Cloud database but does not run migrations.
Migrations are forward-only. Rolling back requires a new migration file — never delete or edit existing migration files.
Secrets management in pipelines
Section titled “Secrets management in pipelines”Pipeline steps do not have access to raw secrets. Instead:
- Build-time: VITE_* variables come from Azure DevOps variable groups (marked as secret)
- Runtime: Container Apps read secrets from Key Vault via secret references
- Cloudflare deploy: Cloudflare API token is in the
cloudflare-cloudvariable group
No secrets are ever written to Docker images or build artifacts.
Trigger path filters (example)
Section titled “Trigger path filters (example)”The Cloud Backend pipeline only triggers when files under Backend/ change:
trigger: branches: include: - master paths: include: - Backend/*This prevents unnecessary builds when only the frontend or documentation changes.
Infrastructure pipeline
Section titled “Infrastructure pipeline”Infrastructure/pipelines/infrastructure.yml deploys shared Azure resources (Bicep) per environment. After Container Apps DNS, it runs:
scripts/setup_cloudflare_dns.py— CNAME + asuid TXT forcloud/manage/ingesthostnamesscripts/setup_acs_email_dns.py— Cloudflare records for ACS Email domain verification, bounded poll, link domain to Communication Service
See Transactional Email and Azure Infrastructure.