T-0.1 Flux GitOps layout + dev/prod overlays + platform component skeletons (R-GITOPS-01/03, R-ENV-02, R-PLAT-01)
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
This commit is contained in:
1 parent
bd8de96456
commit
af4f6c07ae
75 files changed
+1638
-4
No files matched your search
+86
-2
@@ -1,3 +1,87 @@
|
||||
# platform
|
||||
# platform/
|
||||
|
||||
_Placeholder — populated in Phase 0. See ../home-network-k3s (read-only spec)._
|
||||
Cluster-wide **platform services**, Flux-managed (**R-PLAT-01**, **R-GITOPS-01/02/03**). Reconciled
|
||||
by the `platform` Flux Kustomization defined in [`clusters/base/platform.yaml`](../clusters/base/platform.yaml),
|
||||
**before** `apps/`.
|
||||
|
||||
Governing spec: [`docs/05-gitops-and-delivery.md`](../../home-network-k3s/docs/05-gitops-and-delivery.md),
|
||||
[`docs/01-architecture-overview.md`](../../home-network-k3s/docs/01-architecture-overview.md).
|
||||
|
||||
> **Phase 0 scaffolding only.** Every component here is a structurally-correct **stub** — a Flux
|
||||
> HelmRelease and/or Kustomization with a values placeholder, a README citing the governing ADR/spec,
|
||||
> and TODOs for the phase that fills it in. **No cluster exists**; nothing reconciles yet. Do not add
|
||||
> working config, secrets, or provisioning under Phase 0 (spec `AGENTS.md` §1/§5/§6, `roadmap/phases.md`).
|
||||
|
||||
## Reconciliation flow (how a change lands)
|
||||
|
||||
```
|
||||
git (source of truth)
|
||||
│ operator PR → CI (lint · schema · Kyverno L0 · Chainsaw) → merge to tracked branch
|
||||
▼
|
||||
Flux GitRepository (clusters/base/flux-system.yaml)
|
||||
▼
|
||||
Flux Kustomization "platform" → ./platform (this dir) ── substituteFrom cluster-vars ──┐
|
||||
│ prune=true (drift correction, R-GITOPS-03) · wait=true │ R-ENV-02
|
||||
▼ │
|
||||
Flux Kustomization "apps" → ./apps (dependsOn platform) ─ substituteFrom cluster-vars ──┘
|
||||
```
|
||||
|
||||
Git is authoritative; the cluster conforms to git and drift is auto-corrected (R-GITOPS-01/03).
|
||||
Manual `kubectl apply` of platform state is prohibited (spec `AGENTS.md` §5).
|
||||
|
||||
## The dev ↔ prod overlay model (R-ENV-02)
|
||||
|
||||
Platform manifests are authored **once**. Every value that legitimately differs between environments
|
||||
is a `${TOKEN}` resolved from the `cluster-vars` ConfigMap via Flux `postBuild.substituteFrom`. The
|
||||
`clusters/dev` and `clusters/prod` overlays differ **only** by the values they patch into
|
||||
`cluster-vars` (issuer, replica counts, storage sizes, retention). See
|
||||
[`clusters/README.md`](../clusters/README.md). Base manifests are **never forked per environment**.
|
||||
|
||||
## Components (one directory each)
|
||||
|
||||
| Dir | Component | Governing ADR / spec | Serves |
|
||||
|---|---|---|---|
|
||||
| `cilium/` | CNI + kube-proxy replacement + Gateway API + Egress Gateway + Hubble | [ADR-0002](../../home-network-k3s/decisions/adr-0002-cni-cilium.md), docs/03 | R-NET-* |
|
||||
| `longhorn/` | Replicated block storage; 3-replica default StorageClass + bulk tier | [ADR-0003](../../home-network-k3s/decisions/adr-0003-storage-longhorn.md), docs/04 | R-STATE-* |
|
||||
| `cert-manager/` | TLS via Let's Encrypt DNS-01 (Cloudflare); staging + prod ClusterIssuers | [ADR-0006](../../home-network-k3s/decisions/adr-0006-tls-cert-manager-letsencrypt.md), docs/08 | R-TLS-* |
|
||||
| `externaldns/` | Automatic DNS records for public services (Cloudflare) | docs/09 | R-DNS-* |
|
||||
| `gateway/` | Gateway API GatewayClass + shared HTTPS Gateway + wildcard cert | [ADR-0002](../../home-network-k3s/decisions/adr-0002-cni-cilium.md)/[ADR-0006](../../home-network-k3s/decisions/adr-0006-tls-cert-manager-letsencrypt.md), docs/09 | R-DNS-01, R-TLS-01 |
|
||||
| `monitoring/` | kube-prometheus-stack + Loki + Grafana Alloy + Alertmanager | docs/10 | R-OBS-* |
|
||||
| `velero/` | Off-cluster backup/DR of volumes + resource state | [ADR-0003](../../home-network-k3s/decisions/adr-0003-storage-longhorn.md), docs/04 | R-STATE-03 |
|
||||
| `kubevirt/` | KubeVirt + CDI (IaaS: application VMs on the same K8s surface) | [ADR-0005](../../home-network-k3s/decisions/adr-0005-vm-workloads-kubevirt.md), docs/06 | R-PLAT-03 |
|
||||
| `image-automation/` | Flux image-update-automation (hands-off image tag advance) | [ADR-0009](../../home-network-k3s/decisions/adr-0009-automated-image-updates.md), docs/11 | R-UPD-02 |
|
||||
| `keycloak/` | Platform IdP (OIDC + SAML), config-as-code, PostgreSQL on Longhorn | [ADR-0014](../../home-network-k3s/decisions/adr-0014-idp-keycloak.md), docs/15 | R-IDP-* |
|
||||
| `oauth2-proxy/` | Forward-auth at the Gateway for non-OIDC apps → Keycloak | [ADR-0014](../../home-network-k3s/decisions/adr-0014-idp-keycloak.md), docs/15 | R-IDP-* |
|
||||
| `kyverno/` | **L0 policy-as-code gate — OWNED BY THE POLICY ENGINEER (WS-TEST).** | [ADR-0011](../../home-network-k3s/decisions/adr-0011-test-tooling-kyverno-chainsaw.md), docs/14 | R-TEST-* |
|
||||
|
||||
## ⚠️ INTEGRATION TODO(PM): wire kyverno into the platform kustomization
|
||||
|
||||
`platform/kyverno/` is authored by a **different agent** (the policy engineer, WS-TEST). This
|
||||
workstream did **not** create any files under `platform/kyverno/` and must not.
|
||||
|
||||
[`platform/kustomization.yaml`](kustomization.yaml) intentionally **omits `- kyverno`**. Once the
|
||||
policy engineer's files land, the **PM** must add `- kyverno` to that list (recommended first, so
|
||||
policies are present before other components reconcile). The line is present as a commented TODO in
|
||||
the kustomization.
|
||||
|
||||
## Secrets
|
||||
|
||||
Every secret referenced below (Cloudflare API token, Velero backup-target creds, Keycloak admin/DB,
|
||||
oauth2-proxy cookie/client secrets) is referenced **by name only** and will be committed
|
||||
**SOPS-encrypted** (WS-SEC, [ADR-0007](../../home-network-k3s/decisions/adr-0007-secrets-sops-age.md)).
|
||||
**No plaintext secret appears anywhere in this tree.**
|
||||
|
||||
## Cross-workstream contracts surfaced by these stubs
|
||||
|
||||
- **cilium (WS-NET ↔ WS-INFRA):** Cilium's *initial* CNI install is done by Ansible at cluster
|
||||
bootstrap (docs/02, Phase 1). The HelmRelease here manages Cilium *config* thereafter; its Helm
|
||||
values MUST match the Ansible bootstrap values (kubeProxyReplacement, k8sServiceHost/Port, API
|
||||
server host) or reconciliation will fight the bootstrap. Contract owner: WS-NET + WS-INFRA.
|
||||
- **gateway + cert-manager + externaldns (WS-NET + WS-SEC):** the shared Gateway listener, the
|
||||
wildcard `*.home.keithjackson.dev` cert, and the ExternalDNS source all reference each other; they
|
||||
form the "Issuer + Gateway TLS" interface in `roadmap/workstreams.md`.
|
||||
- **image-automation (WS-UPDATE):** this dir holds only the *cluster-wide* ImageUpdateAutomation +
|
||||
git write-back. Per-service `ImageRepository`/`ImagePolicy` are rendered from each
|
||||
ServiceDefinition's `update` block (WS-GITOPS/WS-UPDATE), living with `apps/`.
|
||||
- **keycloak/oauth2-proxy (WS-SEC):** the SSO/auth contract (`auth` block → Keycloak client /
|
||||
oauth2-proxy protection) is owned by WS-SEC; these are placeholders pending that contract.
|
||||
Reference in new issue
Block a user