The eSHARS Azure estate is a layered, CAF-aligned landing zone driven entirely by OpenTofu + GitHub Actions. Six numbered workflows (Infra: 1–6, chained by an Infra: 0 orchestrator, fronted by Port) stand a tier up from zero under a two-identity model. App releases deploy onto it from the HISD repo using the ops VM's managed identity, and database refresh/seeding is self-service via Port — with no stored credentials anywhere.
The map
Click a node
Hover to light up a node's connections; click (or press Enter) to see what it creates, which identity runs it, and where the deep-dive docs live.
Tiers & environments
Everything is built once per tier; an environment is just another workload-env on top of a tier that already exists.
| Tier | Environments | State backend | Automation account |
|---|---|---|---|
| nonprod | dev qa regression | sattfnonprodcus in rg-eshars-scaffold-nonprod-cus |
aa-eshars-nonprod-cus |
| prod | uat training prod | sattfprodcus in rg-eshars-scaffold-prod-cus |
aa-eshars-prod-cus |
Every Terraform root has its own state blob in its tier's storage account (Entra-auth only, shared keys disabled) — nonprod CI/CD physically cannot touch prod state. There is no staging environment; prod has a staging deployment slot (the zero-downtime swap target).
The identity model — three identities, three blast radii
| Platform SP | Workload SP | VM managed identities | |
|---|---|---|---|
| Name | github-eshars-platform | github-eshars-deploy | per-VM system-assigned |
| Runs | Infra 1–3 (everything that creates resource groups) | Infra 4–6 + Port/runbook workflows | App CD + Automation runbooks |
| Scope | Subscription Contributor + UAA | RG-scoped grants minted by workload-core (Reader-only on the ops RG — it can never rewrite its own executor) | Narrow data-plane roles |
| GitHub environment | platform | ops | n/a — runner-local az login --identity |
| Runner | GitHub-hosted | Self-hosted ops VM | the ops VM itself |
Drill-in: how an app instance is wired
The chain every environment's app rides — config, secrets, identity, and the database swap trick. (Candidate for its own standalone explorer.)
The web app gets SecureSettingsKeyVault (its per-env vault, kv-eshars-{env}-cus) as an app setting and a token-substituted Web.config — nothing sensitive lives in app settings or config files.
workload-env)The app's system-assigned MI holds Key Vault Secrets User on its env vault (private-endpoint-only). It reads connection strings, vendor keys, and the tier encryption key — no stored credentials anywhere in the chain.
The ESHARS* connection strings target eshars-primary.db.{env}.eshars.internal (and eshars-reporting) — CNAMEs in a per-env private zone. Swapping the database behind an environment is one CNAME update: no deployment, no KV change, no restart.
workload-envdb-eshars-{env} (core) + -log + -audit on sql-eshars-{env}-cus. The server's Entra admin is the tier DBA group; the SQL admin password is Terraform-generated straight into the vault. Prod adds a CanNotDelete lock and prevent_destroy.
workload-env syncs the per-env deploy variables/secrets into the HISD repo's GitHub environment — infrastructure changes propagate to CD configuration automatically; nobody hand-edits environment variables.
masterPassword. It is not a crypto key — any non-empty value is a universal override login into every account. The safe state is absent, and Terraform deliberately does not create it. Details: Configuration & Secrets.What's automated end-to-end today
- Tier from zero → one Infra: 0 dispatch (or six layer dispatches), each self-checking its prerequisite; every credential generated in-root or federated.
- Environment stand-up → one Infra: 6 dispatch, including DB provisioning, secret sync, GitHub environment wiring, and readiness gates.
- App release → push to
developauto-deploys dev; other slots are gated dispatches deploying only what changed, across App Service + four VMs. - DB refresh & seeding → self-service from Port, scrub-safe by default, fully runbook-driven.
- Runbook lifecycle → push-to-deploy with tier routing and pruning; PR review → automated (Otto); certificates → acmebot built, pending go-live gates.
- Layer chain, preflights, runner & identity per layer —
eshars-ops/.github/workflows/{infra-standup,platform-connectivity,foundation,ops,secrets,tier-vms,environment-workload}.yml - Identity split rationale & grant set —
eshars-ops/docs/superpowers/specs/2026-07-21-foundation-workload-identity-split.md,infrastructure/workload-core/ - Tiers, state backends, roots & modules count —
eshars-ops/infrastructure/(18 roots, 24 modules at2d67c92),BACKEND_SETUP.md - App wiring chain —
infrastructure/workload-env/main.tf,modules/key-vault-secrets/main.tf, Configuration & Secrets - Self-service restore/seed —
.github/workflows/port-{restore-db,seed-dev-data}.yml,scripts/azure-runbooks/v2/, Database Restore & Seed v2