|
| 1 | +# AutoAudit scaling test runbook (AKS) |
| 2 | + |
| 3 | +End-to-end "deploy this on a fresh AKS cluster" sequence used for the |
| 4 | +scaling demo. Companion to [`scaling-after.md`](./scaling-after.md) (the |
| 5 | +"what changed and why" doc) and the two component READMEs: |
| 6 | + |
| 7 | +- [`infrastructure/monitoring/in-cluster/README.md`](../../infrastructure/monitoring/in-cluster/README.md) — Prometheus / Grafana / KEDA / celery-exporter |
| 8 | +- [`tests/load/in-cluster/README.md`](../../tests/load/in-cluster/README.md) — in-cluster k6 load runner |
| 9 | + |
| 10 | +If you're re-running this after a teardown, skip whatever you've already |
| 11 | +done — every step is idempotent. |
| 12 | + |
| 13 | +## Prerequisites |
| 14 | + |
| 15 | +| What | Why | |
| 16 | +|---|---| |
| 17 | +| `kubectl` configured for the target AKS cluster | Everything that follows | |
| 18 | +| `helm` v3+ | KEDA, Prometheus, Grafana, AutoAudit | |
| 19 | +| `az` logged in to the subscription holding the ACR | Image push (or `az acr login -n autoaudit`) | |
| 20 | +| `docker` | Local builds of the 5 service images | |
| 21 | +| Git Bash (Windows) or any POSIX shell | The launcher scripts in `tests/load/in-cluster/` are bash | |
| 22 | +| AKS metrics-server present | HPA needs it. Default on AKS, no action. | |
| 23 | +| AKS↔ACR pull permission | Either ACR attached to AKS via `az aks update --attach-acr`, or imagePullSecret. | |
| 24 | + |
| 25 | +## 1. Namespace + Secret |
| 26 | + |
| 27 | +```bash |
| 28 | +kubectl create namespace autoaudit |
| 29 | + |
| 30 | +# Generate and create the autoaudit-secrets Secret (4 keys the chart requires). |
| 31 | +# Keep /tmp/autoaudit-creds.env somewhere safe — Secrets cannot be retrieved |
| 32 | +# in cleartext after creation. |
| 33 | +python -c " |
| 34 | +import secrets |
| 35 | +from cryptography.fernet import Fernet |
| 36 | +print(f'PG_PASS={secrets.token_urlsafe(24)}') |
| 37 | +print(f'JWT_SECRET={secrets.token_urlsafe(48)}') |
| 38 | +print(f'FERNET={Fernet.generate_key().decode()}') |
| 39 | +print(f'REDIS_PASS={secrets.token_urlsafe(24)}') |
| 40 | +" > /tmp/autoaudit-creds.env |
| 41 | +source /tmp/autoaudit-creds.env |
| 42 | + |
| 43 | +kubectl create secret generic autoaudit-secrets -n autoaudit \ |
| 44 | + --from-literal=postgresql-password="$PG_PASS" \ |
| 45 | + --from-literal=jwt-secret-key="$JWT_SECRET" \ |
| 46 | + --from-literal=encryption-key="$FERNET" \ |
| 47 | + --from-literal=redis-password="$REDIS_PASS" |
| 48 | +``` |
| 49 | + |
| 50 | +## 2. KEDA + monitoring stack |
| 51 | + |
| 52 | +Follow the install block in |
| 53 | +[`infrastructure/monitoring/in-cluster/README.md`](../../infrastructure/monitoring/in-cluster/README.md#install-order-matters). |
| 54 | +It installs (in order): |
| 55 | + |
| 56 | +1. KEDA (namespace-scoped to `autoaudit`, with `prometheus.operator.enabled=true` so the queue-depth metric is exposed) |
| 57 | +2. Prometheus + kube-state-metrics |
| 58 | +3. celery-exporter |
| 59 | +4. Dashboard ConfigMap |
| 60 | +5. Grafana |
| 61 | + |
| 62 | +## 3. Images in ACR |
| 63 | + |
| 64 | +> **Heads-up for future students / maintainers.** `autoaudit.azurecr.io` |
| 65 | +> was set up as a **temporary registry for testing purposes only**. It |
| 66 | +> does **not** live in a long-lived or university-owned Azure |
| 67 | +> subscription and will be torn down once the scaling proof-of-concept |
| 68 | +> is complete. Do **not** assume it will still resolve, and do **not** |
| 69 | +> depend on the tags that are pushed there. The "move CI/CD to a |
| 70 | +> project-owned ACR" story is captured in |
| 71 | +> [saas-scaling-aks-platform.md §5](./saas-scaling-aks-platform.md#5-image--build-supply-chain); |
| 72 | +> when you re-run this runbook, substitute your own registry (any OCI |
| 73 | +> registry works — ACR, GHCR, Docker Hub) and update |
| 74 | +> `helm/autoaudit/values-scaling.yaml` accordingly. |
| 75 | +
|
| 76 | +The five custom images live in `autoaudit.azurecr.io/autoaudit/{backend-api, |
| 77 | +worker, frontend, opa, powershell-service}`. Existing tags (e.g. |
| 78 | +`20260523-1de7943`) were pushed during the original test and are still |
| 79 | +valid *while the registry exists*; only rebuild when chart-affecting code changes. |
| 80 | + |
| 81 | +Rebuild + push (run from repo root): |
| 82 | + |
| 83 | +```bash |
| 84 | +az acr login -n autoaudit |
| 85 | + |
| 86 | +# Compose-built images. backend-api / worker / powershell-service / frontend |
| 87 | +docker compose --profile all build |
| 88 | +TAG="$(date +%Y%m%d)-$(git rev-parse --short=7 HEAD)" |
| 89 | +for svc in backend-api worker frontend powershell-service; do |
| 90 | + docker tag "autoaudit-${svc}:latest" "autoaudit.azurecr.io/autoaudit/${svc}:latest" |
| 91 | + docker tag "autoaudit-${svc}:latest" "autoaudit.azurecr.io/autoaudit/${svc}:${TAG}" |
| 92 | + docker push "autoaudit.azurecr.io/autoaudit/${svc}:latest" |
| 93 | + docker push "autoaudit.azurecr.io/autoaudit/${svc}:${TAG}" |
| 94 | +done |
| 95 | + |
| 96 | +# Custom OPA image (policies baked in) — build context MUST be repo root. |
| 97 | +docker build -f engine/opa/Dockerfile \ |
| 98 | + -t autoaudit.azurecr.io/autoaudit/opa:latest \ |
| 99 | + -t autoaudit.azurecr.io/autoaudit/opa:${TAG} . |
| 100 | +docker push autoaudit.azurecr.io/autoaudit/opa:latest |
| 101 | +docker push autoaudit.azurecr.io/autoaudit/opa:${TAG} |
| 102 | +``` |
| 103 | + |
| 104 | +Important: the frontend MUST be built from `frontend/Dockerfile.prod` (nginx |
| 105 | +serving the built bundle). Compose uses `frontend/Dockerfile` (vite dev |
| 106 | +server on :3000) which mismatches the chart's Service port 80 — pods crash-loop. |
| 107 | +The compose `--profile all build` uses the dev Dockerfile, so for the chart |
| 108 | +you need: |
| 109 | + |
| 110 | +```bash |
| 111 | +docker build -f frontend/Dockerfile.prod \ |
| 112 | + -t autoaudit.azurecr.io/autoaudit/frontend:latest \ |
| 113 | + -t autoaudit.azurecr.io/autoaudit/frontend:${TAG} ./frontend |
| 114 | +docker push autoaudit.azurecr.io/autoaudit/frontend:latest |
| 115 | +docker push autoaudit.azurecr.io/autoaudit/frontend:${TAG} |
| 116 | +``` |
| 117 | + |
| 118 | +## 4. Install the chart |
| 119 | + |
| 120 | +```bash |
| 121 | +helm upgrade --install autoaudit ./helm/autoaudit \ |
| 122 | + -n autoaudit \ |
| 123 | + -f ./helm/autoaudit/values-scaling.yaml \ |
| 124 | + --wait --timeout 10m |
| 125 | +``` |
| 126 | + |
| 127 | +`values-scaling.yaml` is the demo overlay — HPA + KEDA + PDBs + synthetic |
| 128 | +load levers all enabled, with maxReplicas tuned for a 2–3 node AKS cluster. |
| 129 | +Don't use `values-poc.yaml` for the scaling demo (it disables autoscaling). |
| 130 | + |
| 131 | +## 5. Smoke check |
| 132 | + |
| 133 | +```bash |
| 134 | +kubectl get deploy,hpa,pdb,scaledobject -n autoaudit |
| 135 | +``` |
| 136 | + |
| 137 | +Expected: **9 Deployments** (5 services + 3 worker queues + redis), **1 StatefulSet** (postgresql), |
| 138 | +**4 HPAs** + **3 KEDA-managed HPAs** = 7 HPA objects total, **7 PDBs**, **3 ScaledObjects** |
| 139 | +all `READY=True`, **1 TriggerAuthentication**. |
| 140 | + |
| 141 | +## 6. Fire load tests |
| 142 | + |
| 143 | +Per [`tests/load/in-cluster/README.md`](../../tests/load/in-cluster/README.md#fire-it): |
| 144 | + |
| 145 | +```bash |
| 146 | +# Full demo (api-baseline → 60s cooldown → scan-fanout) |
| 147 | +bash tests/load/in-cluster/demo.sh |
| 148 | + |
| 149 | +# Or one phase at a time |
| 150 | +bash tests/load/in-cluster/run.sh api-baseline.js |
| 151 | +bash tests/load/in-cluster/run.sh scan-fanout.js -e N_GRAPH=150 -e N_POWERSHELL=50 |
| 152 | +``` |
| 153 | + |
| 154 | +## Teardown |
| 155 | + |
| 156 | +```bash |
| 157 | +# 1. The chart (delete PVC so a fresh install gets a fresh database). |
| 158 | +helm -n autoaudit uninstall autoaudit |
| 159 | +kubectl delete pvc -n autoaudit -l app.kubernetes.io/instance=autoaudit |
| 160 | + |
| 161 | +# 2. Monitoring stack (per the in-cluster monitoring README teardown). |
| 162 | +helm -n autoaudit uninstall grafana prometheus |
| 163 | +kubectl -n autoaudit delete -f infrastructure/monitoring/in-cluster/celery-exporter.yaml |
| 164 | +kubectl -n autoaudit delete configmap autoaudit-scaling-dashboard |
| 165 | + |
| 166 | +# 3. KEDA (cluster-wide CRDs). |
| 167 | +helm -n keda uninstall keda |
| 168 | +kubectl delete namespace keda |
| 169 | + |
| 170 | +# 4. autoaudit namespace (drops the Secrets too — re-create per step 1 next time). |
| 171 | +kubectl delete namespace autoaudit |
| 172 | +``` |
| 173 | + |
| 174 | +Then scale the AKS node pool back down via the Azure portal / CLI to stop |
| 175 | +the bill. |
| 176 | + |
| 177 | +## Gotchas hit during the first run |
| 178 | + |
| 179 | +The `Chart bugs found and fixed during AKS testing` section of |
| 180 | +[`scaling-after.md`](./scaling-after.md#chart-bugs-found-and-fixed-during-aks-testing) |
| 181 | +lists each one with the file/line. Skim it before re-running on a new |
| 182 | +cluster — most of the fixes are already merged into the chart, but the |
| 183 | +list explains the why. |
0 commit comments