CatalyzeUp
sondely/deployment

Azure Infrastructure

Overview

Sondely runs on Microsoft Azure, provisioned with Terraform in CatalyzeUp/catalyzeup-devops (azure/main.tf for the Python app, azure/sondely-platform.tf for the new platform) and deployed by GitHub Actions. Two generations run side by side until the cutover:

  • The Python app (CatalyzeUp/sondely): FastAPI and the Vite frontend in one image, on Cosmos DB and Redis. It serves sondely.com today.
  • The new platform (CatalyzeUp/sondely-platform): one Next.js app on Postgres, with the Sona assistant, built on 7 and 8 November 2026. It serves platform-dev.sondely.com and platform.sondely.com until the cutover moves sondely.com to it.

The move between the two, and the full detail of the new platform's Terraform, image and workflows, are on Infrastructure and Deploy and the Cutover Runbook. This page is the summary of what runs.

Resource Group

Property Value
Name rg-catalyzeup
Region Canada Central (Speech and the voice Azure OpenAI account also in Canada Central; openai-catalyzeup in East US)
Subscription Microsoft Azure Sponsorship
Terraform state ideaplacestfstate/tfstate/catalyzeup-azure.tfstate in rg-ideaplaces

Shared resources

Resource Name Use
Container registry acrcatalyzeup Images impactpulse (Python) and sondely-platform (new)
Key Vault kv-catalyzeup, RBAC mode Secrets below
Container Apps environment cae-catalyzeup, logs to law-catalyzeup Every app
Azure OpenAI openai-catalyzeup, deployment gpt-5.4 Survey and interface translation in the Python app; Sona's text model in the new one
Email Azure Communication Services Both apps send through ACS_CONNECTION_STRING
DNS Cloudflare, zone sondely.com Records in Terraform; custom domain bindings made outside Terraform

The Python app

Piece Name Notes
Database cosmos-catalyzeup, Mongo API 4.2, serverless, periodic backup impactpulse (dev), impactpulse_prod (production)
Sessions redis-catalyzeup, Basic C0 DB 0 dev, DB 1 production
Dev app container app impactpulse, branch develop dev.sondely.com, impactpulse.catalyzeupdev.com; ENVIRONMENT=development
Production app container app impactpulse-prod, branch main sondely.com, www.sondely.com, hit.wehappers.org, impactpulse.catalyzeup.ai
Both apps modules/container-app Port 8000, 0.5 CPU, 1 Gi, 1 to 3 replicas, single revision mode, no health probes

Settings: MONGODB_URL, MONGODB_DATABASE, REDIS_URL, SECRET_KEY, GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET, ACS_CONNECTION_STRING, AZURE_OPENAI_ENDPOINT, AZURE_OPENAI_DEPLOYMENT, AZURE_OPENAI_KEY, ENVIRONMENT, DEBUG, USE_INMEMORY_DB, ALGORITHM, ACCESS_TOKEN_EXPIRE_MINUTES, FRONTEND_URL, BACKEND_URL, CORS_ORIGINS.

Deploys: deploy.yml on develop to impactpulse, deploy-prod.yml on main to impactpulse-prod, both on GitHub-hosted runners, polling /health after the update.

The new platform

Piece Name Notes
Postgres psql-catalyzeup-sondely (sondely_prod), psql-catalyzeup-sondely-dev (sondely_dev) Version 16, B_Standard_B2s; the app connects as the constrained sondely_app role, migrations run as the owner
Dev app container app sondely-platform-dev, branch develop platform-dev.sondely.com
Production app container app sondely-platform-prod, branch main platform.sondely.com; one replica until Sona's voice calls have session affinity
Sona's voice speech-catalyzeup-sondely, Speech, Canada Central Azure AI Voice Live
Voice Azure OpenAI openai-catalyzeup-voice, Canada Central A transcription deployment; not used by the app today

Deploys: one workflow after green CI on a push, develop to dev and main to production, only the branch tip, production only from main, proven by the commit on /health.

Key Vault

Secret Use
secret-key-impactpulse Python app JWT signing key
google-client-id-impactpulse, google-client-secret-impactpulse Google sign-in, Python app
acs-connection-string-impactpulse Email through Azure Communication Services, both apps
db-password-sondely-admin, db-password-sondely-admin-dev, db-password-sondely-app, db-password-sondely-app-dev Postgres owner and app role passwords
database-url-sondely-{dev,prod}, admin-database-url-sondely-{dev,prod} Built connection strings
session-secret-sondely, jobs-secret-sondely New platform session signing and the reminder job's shared secret

Health checks

Both apps answer /health. The new platform's runs SELECT 1 through its app role and names the deployed commit. Neither app has container health probes configured yet.

Monitoring

The apps log to law-catalyzeup. The C3 self-healing monitor does not read it yet; wiring it is a condition of the cutover (Testing and Bugs).

Disaster Recovery

  • Cosmos DB: periodic backup; a point-in-time restore is not self-serve, so the migration takes its own mongodump archives.
  • Postgres: Azure Flexible Server backups, per server.
  • Apps: images in acrcatalyzeup tagged by commit, and the source in GitHub, so any commit can be redeployed.