Skip to content

abossard/always-on-v2

Repository files navigation

AlwaysOn v2 — Mission-Critical Apps on Azure (azd sample)

A lightweight Azure Developer CLI (azd) sample that deploys a globally distributed, mission-critical platform on Azure — AKS stamps, Cosmos DB, Front Door, Orleans apps, and full observability — with a single command.

azd auth login
azd up

That deploys a single stamp in one region. Scaling to two stamps or two regions is one small edit (see Deploy).

  • 📦 What's insideFEATURES.md — every app, tool, and platform feature, with links and sources.
  • 🏭 CI/CD, Flux & production topologyci-cd/.
  • 🧱 Architecture decisionsdocs/adr/.
Layer Technology
Compute AKS (multi-stamp, Karpenter autoscale)
Framework .NET 10, Orleans, Aspire
Database Azure Cosmos DB
Ingress Azure Front Door + Istio Gateway API
AI Azure OpenAI
Observability App Insights + OpenTelemetry + Prometheus
IaC Bicep via azd

Full catalog and sources: FEATURES.md.


Prerequisites

Also required by the azd deploy hooks (the postdeploy step renders K8s manifests locally):

  • kustomize
  • envsubst (ships with gettext; brew install gettext on macOS)
  • jq

Getting started

Run an app locally

# Example: HelloAgents
cd src/HelloAgents
cd HelloAgents.Web && npm ci && cd ..
aspire run --apphost HelloAgents.AppHost

See each app folder (linked from FEATURES.md) for app-specific notes.

Deploy to Azure

azd auth login
azd env new my-dev --location swedencentral --subscription <subscription-id>
azd up

After ~15 minutes every app is live at its Front Door HTTPS endpoint (printed at the end).

⚠️ Don't name the env alwayson — it collides with the production baseName. The preprovision hook blocks it. Use any other name (my-dev, test, demo).


Deploy with Azure Developer CLI (azd)

azd up deploys the entire platform from your machine — no hosted Git repo and no Flux required. It runs:

azd up
├── azd provision      Deploys all Azure infra (AKS, ACR, Front Door, Cosmos DB, AI, ...)
│   └── postprovision  Enables Gateway API, gets cluster credentials, extracts deploy vars
└── azd deploy
    ├── predeploy      Builds images remotely via `az acr build` (no Docker Desktop needed)
    └── postdeploy     `kustomize build | envsubst | kubectl apply`, waits for rollout,
                       verifies health, prints Front Door endpoints

Stamps & regions — start with one

The topology is data in infra/main.parameters.json (the regions array). Stamps and regions are added by editing that array — the hooks and Bicep iterate over whatever you declare, so a single stamp "just works".

Default (shipped): 1 region, 1 stamp. This is what most people want — lowest cost (Serverless Cosmos, Free AKS tier, spot workers), one region.

"regions": {
  "value": [
    {
      "key": "swedencentral",
      "location": "swedencentral",
      "stampDefaults": { "aksNodeVmSize": "Standard_D2s_v5", "aksSystemNodeCount": 1,
        "aksAvailabilityZones": [], "aksTier": "Free", "aksIngressType": "External", "aksUseSpot": true },
      "stamps": [{ "key": "001" }]
    }
  ]
}

Two stamps in the same region — add a second entry to stamps:

"stamps": [{ "key": "001" }, { "key": "002" }]

Two stamps across two regions — add a second region object:

"regions": {
  "value": [
    { "key": "swedencentral", "location": "swedencentral",
      "stampDefaults": { "...": "as above" }, "stamps": [{ "key": "001" }] },
    { "key": "germanywestcentral", "location": "germanywestcentral",
      "stampDefaults": { "...": "as above" }, "stamps": [{ "key": "001" }] }
  ]
}

Run azd up again after editing. For provisioned/multi-write Cosmos, Premium Front Door, and the GitHub Actions/Flux production path, see ci-cd/.

Optional toggles

Set these in infra/main.parameters.json:

Parameter Default Effect
enableFlux false Flux GitOps on AKS. azd deploys via the postdeploy hook when off. See ci-cd/.
enableCustomDomain false Custom-domain routing (DNS zones, CNAMEs). Off uses Front Door default endpoints.
enablePrivateEndpoints true Per-stamp VNet + private endpoints, public access disabled.
cosmosMode Serverless Provisioned enables autoscale + multi-region write.
frontDoorSku Standard_AzureFrontDoor Premium_AzureFrontDoor for WAF + Private Link to internal LB.

How it works (Flux-free, the default)

With enableFlux = false, the postdeploy hook replaces Flux's reconciliation loop with a local equivalent, using the same manifests in clusters/ unchanged:

  1. kustomize build renders clusters/<region>/apps (what Flux would render).
  2. envsubst substitutes ${VAR} patterns from Bicep outputs (same as Flux postBuild.substitute).
  3. kubectl apply --server-side applies to AKS (same as Flux reconciliation).

Tear down

azd down --force --purge

Repository layout

Path What
FEATURES.md Applications, tools, and platform features — with sources
src/ .NET 10 / Orleans apps + shared libraries + az healthmodel CLI
infra/ Bicep IaC (main.bicep entry point) + main.parameters.json
clusters/ Kustomize/Flux manifests (also used by the azd postdeploy hook)
hooks/ azd lifecycle hooks (pre/post provision & deploy)
ci-cd/ GitHub Actions, Flux/GitOps, deploy keys, production profiles
scripts/ Health model + Grafana dashboard generators
docs/adr/ Architecture Decision Records

References

About

AlwaysOn v2 – globally distributed, mission-critical application examples on Azure

Resources

Stars

1 star

Watchers

0 watching

Forks

Packages

 
 
 

Contributors