Observability stack — epic
Single pane of glass (metrics, logs, traces, profiles, cost, cloud resources) across all environments. Closes CNCF capability gap #7 (today only Hubble + ArgoCD). Delivered as the full stack in small, independently-verifiable phases — one Terragrunt unit + gated plan→apply + a runtime check each, never batched.
Full design: docs/plans/102-observability-stack.md
Progress: 2 / 14 phases live (P1, P2). Each remaining phase is now its own tracked sub-issue (links below).
Topology — hub & spoke
- Hub = platform cluster: central Grafana + SSO + multi-tenant stores Mimir (metrics) / Loki (logs) / Tempo (traces). One UI, one set of stores.
- Spokes = each workload cluster: lightweight collectors (Alloy / OTel) remote-write/push to the hub over Tailscale/TGW.
- Tenancy: tenant = team =
teams.hcl key, stamped as X-Scope-OrgID from the namespace label on the write path, enforced server-side (auth_enabled: true), pinned per-team on the read path. Grafana is Tailscale-only.
Locked decisions
- Terragrunt units; hub on platform; isolation-ready from day one.
- Absolute latest stable (GA) chart + provider pins, re-resolved per phase.
- HA is a per-unit
high_availability toggle (mirrors the ArgoCD module): off on reference clusters, on for prod/capacity-rich.
- Cost-conscious: attack data volume (retention, trace tail-sampling, cardinality limits, S3 lifecycle) + compute (Graviton/arm64, spot for stateless tiers), not replica counts. OpenCost (P11) is the evidence.
- OSS-default, commercial opt-in: every capability ships OSS as default; commercial (Grafana Enterprise/Cloud, AMP, SLO/Synthetics/OnCall) is a per-unit flag, never a fork.
Security invariants (load-bearing)
X-Scope-OrgID is a trust header, not auth → cross-cluster ingest is authenticated + the hub overwrites tenant from the authenticated source identity + the collector derives tenant from the verified pod namespace. Raw store endpoints are network-isolated from team-* pods. Per-tenant limits are a security control. Grafana datasource-proxy locked (SSRF). Secrets via External Secrets.
Phases
Track A — Core stores & UI
Track B — Make it actionable
Track C — Cloud-resource observability (AWS)
Track D — Developer experience / APM
Track E — Reliability
Track F — Multi-cluster reach & economics
Track G — Tenancy & self-service
Ordering
Hard ordering: A → (B,C,D,E depend on the P2/P3 stores) → P10 spoke → P11–P14. D/E can slip after P10 if capacity is tight. Next up: P3 (#582).
Observability stack — epic
Single pane of glass (metrics, logs, traces, profiles, cost, cloud resources) across all environments. Closes CNCF capability gap #7 (today only Hubble + ArgoCD). Delivered as the full stack in small, independently-verifiable phases — one Terragrunt unit + gated
plan→apply+ a runtime check each, never batched.Full design:
docs/plans/102-observability-stack.mdProgress: 2 / 14 phases live (P1, P2). Each remaining phase is now its own tracked sub-issue (links below).
Topology — hub & spoke
teams.hclkey, stamped asX-Scope-OrgIDfrom the namespace label on the write path, enforced server-side (auth_enabled: true), pinned per-team on the read path. Grafana is Tailscale-only.Locked decisions
high_availabilitytoggle (mirrors the ArgoCD module): off on reference clusters, on for prod/capacity-rich.Security invariants (load-bearing)
X-Scope-OrgIDis a trust header, not auth → cross-cluster ingest is authenticated + the hub overwrites tenant from the authenticated source identity + the collector derives tenant from the verified pod namespace. Raw store endpoints are network-isolated fromteam-*pods. Per-tenant limits are a security control. Grafana datasource-proxy locked (SSRF). Secrets via External Secrets.Phases
Track A — Core stores & UI
observabilityns (+default-deny) + Kyverno exclude; dashboards-as-code + Grafana hardening; Tailscale-only; minimal critical SNS route + Watchdog. DONE / live. (SSO is a fast-follow — see below.)auth_enabled+ per-tenant limits + store isolation; hub Prometheusremote_write→ Mimir. DONE / live (PR feat(observability): Prometheus remote_write → Mimir + durable PVCs (#102 P2) #147).auth_enabled+ limits + collector-side redaction; Alloy + OTel write platform telemetry; trace→logs. (Splittable P3a/P3b.) ← next up.Track B — Make it actionable
PrometheusRules + severity routing + inhibition + runbooks; Alertmanager → SNS/Slack/PagerDuty; K8s events→Loki; deploy annotations.Track C — Cloud-resource observability (AWS)
Track D — Developer experience / APM
Track E — Reliability
Track F — Multi-cluster reach & economics
X-Scope-OrgID=<team>+cluster=preprod; instrument app-alpha.Track G — Tenancy & self-service
X-Scope-OrgID; IC group-GUID gating;teams.hclobservabilityblock.teams.hcl; documented app conventions; Backstage tie-in (Developer portal / service catalog (Backstage) #103/Golden-path scaffolding (create-new-app/tenant templates) #104/BACK stack P6: Backstage plugins (ArgoCD, Crossplane, Kyverno, Grafana) #177).Ordering
Hard ordering: A → (B,C,D,E depend on the P2/P3 stores) → P10 spoke → P11–P14. D/E can slip after P10 if capacity is tight. Next up: P3 (#582).