Files
yucca/kubernetes/bootstrap
Antoine Lecompte c6985d902c feat(all): introduce partition/region/ceph-cluster model across the stack (#222)
* feat: introduce partition/region/ceph-cluster model across the stack

Formalize partition -> region -> {one k8s cluster, many ceph clusters} and
thread it through every layer plus a new yuctl ops CLI.

- tf: deployment/<partition>/<region>/<stack> layout; terragrunt path-parse +
  state key yucca/<partition>/<region>/<stack>; per-region region.hcl (role,
  site_id, datacenter, provider_code, domain); env->partition / site->region
  renames (NetBird object names byte-identical); standardized per-stack
  `discovery` output contract (secrets as op:// refs).
- k8s: clusters/<partition>/<region>/ (staging/austin, prod/htz-fsn1, dev/local);
  role-based kustomize components (primary/secondary); hybrid cluster-settings
  (TF-rendered identity + human fragment); dev-mirror folded into dev/local;
  charts regrouped into charts/{apps,platform,lib,dev}.
- ci: infra.yml partition/region discovery matrix; partition-keyed path filters;
  <partition>-<region> environment gates; image-versions path moves.
- ansible: inventories under <partition>-<region>/<cluster>.
- yuctl: Go/cobra CLI reading the discovery contract from TF state.
- Retire the sietch-talos libvirt VM cluster (dev@local is the k3d cluster);
  ceph inventory_dirname -> <partition>-<region>/<cluster>.

Verified: mise k8s:validate green (3 clusters); yuctl go build/vet; tofu
validate pre-merge (all 9 stacks). Live-staging state migration NOT run.

* fix typo

* commit
2026-06-29 08:40:29 -04:00
..

Bootstrap (fresh cluster → Flux-managed)

One-time procedure to take an empty cluster to a self-reconciling Flux install of this tree. Everything after step 3 is GitOps — no further kubectl needed.

1. Install Flux

flux check --pre
flux install   # or the flux-operator, once we adopt it

2. Git auth (the repo is private)

kubernetes/apps/dev/local/repos/git-yucca.yaml references secretRef: yucca-repo-auth. Create it before applying anything, using a read-only deploy key (preferred) or a fine-grained PAT:

# deploy key (read-only) — add the printed public key to the GitHub repo
flux create secret git yucca-repo-auth \
  --url=ssh://git@github.com/immich-app/yucca \
  --ssh-key-algorithm=ecdsa --ssh-ecdsa-curve=p521

# …or a fine-grained PAT over https
flux create secret git yucca-repo-auth \
  --url=https://github.com/immich-app/yucca \
  --username=git --password="$GITHUB_TOKEN"

If you use the ssh deploy key, switch spec.url in git-yucca.yaml to the ssh://git@github.com/... form.

3. Seed the sources + entrypoint from the local checkout

The cluster-repos/cluster-apps Kustomizations pull from the yucca GitRepository — which doesn't exist until something applies it. Break the chicken-and-egg from your checkout:

kubectl apply -k kubernetes/apps/dev/local/repos   # GitRepository + HelmRepositories
kubectl apply -k kubernetes/clusters/dev/local     # cluster-repos -> cluster-apps

From here Flux owns the tree: it reconciles kubernetes/apps/dev/local/repos (including any future source changes) and kubernetes/apps/dev/local.

4. Watch it converge

flux get kustomizations --watch
flux get helmreleases -A

Expected order: operators (cnpg-operator, rook-ceph-operator) → rook-ceph-cluster → yucca-database/yucca-object-user → apps → yucca-web.

Before pointing this at a real prod cluster: the app HelmReleases still carry dev-mirror values and TODO(prod) markers (image registries/tags, OIDC endpoints, ingress, persistence, ExternalSecrets). mock-oidc and the Rook dev cluster are dev-only. See kubernetes/README.md.