- Create SOPS-encrypted cloudflared-secrets.enc.yaml with tunnel token - Add Cloudflare vars to .env.example (CLOUDFLARE_CONNECTOR_TOKEN, ACCOUNT_ID, TUNNEL_ID, API_TOKEN) - Document Phase 0 cloudflared-token Secret creation in BOOTSTRAP.md (manual step until CMP plugin wires it) - Note: Cloudflare-side TCP routing (cp1.homelab -> 192.168.1.213:6443, etc.) must be configured manually in Zero Trust dashboard Tunnel already deployed as ArgoCD Application in k8s/argocd/apps/60-applications.yaml (wave 8); this closes the missing Secret gap and documents the bootstrap path.
4.2 KiB
4.2 KiB
CLAUDE.md — Homelab Integration Guide
Homelab: A bare-metal three-node Kubernetes cluster running Talos Linux with a full observability stack, SSO via Authentik, secret management via Vault, and CI/CD infrastructure (Forgejo + Argo CD, deployed).
Cluster Topology (3 control-plane HA, since 2026-07-20)
| Node | IP | Zone | Scheduling | Storage |
|---|---|---|---|---|
talos-cp-1 |
.213 | az-a | schedulable (all workloads) | sole Longhorn node |
talos-cp-2 |
.163 | az-b | dedicated (NoSchedule) |
none |
talos-cp-3 |
.166 | az-c | dedicated (NoSchedule) |
none |
3 voting etcd members peering on the LAN. Only talos-cp-1 runs workloads and
holds storage → stateful services are single-instance (e.g. CNPG ddb-cluster
= 1 instance). API endpoint is single-homed to .213 (no VIP yet).
Service Integration Routes
New service? Pick your stack below:
| Need | Doc | Example |
|---|---|---|
| Authentication | project-usage/authentik-oidc.md |
OAuth2 login, RBAC groups, JWT tokens |
| Async messaging | project-usage/sqs-messaging.md |
Kafka topic consumers, fire-and-forget, DLQ |
| Object storage | project-usage/minio-s3.md |
File uploads, backups, log backend |
| CI/CD pipeline | project-usage/cicd-workflow.md |
GitHub Actions syntax, image push, Argo CD sync |
| Workflows | project-usage/temporal-workflows.md |
Long-running jobs, retries, state machines |
| Database | project-usage/database-postgres.md |
CloudNativePG setup, schema migrations, replicas |
| Monitoring | project-usage/monitoring-metrics.md |
Prometheus scrape, Grafana dashboard, alerts |
| Secrets | project-usage/vault-secrets.md |
Store credentials, rotate tokens, seal/unseal |
| Networking | project-usage/networking-ingress.md |
Public HTTPS, hostname routing, TLS |
Cluster Essentials
22 namespaces, 18 releases:
Core: cert-manager, ingress-nginx, kube-system, cilium
Storage: longhorn-system, storage (MinIO)
Data: ddb (PostgreSQL), iam (Authentik + Vault)
Observability: logging (Loki + Grafana), monitoring (Prometheus)
Apps: cicd (Forgejo + Argo CD), sqs (Kafka + kmsvc), temporal, story-crater-backend
Architecture principles:
- Immutable OS (Talos — no SSH, declarative config)
- Secrets in Vault + SOPS-encrypted (
*.enc.yaml, age); never commit.env - ArgoCD app-of-apps = CD source of truth (
k8s/argocd/root→k8s/argocd/apps/*); helmfile is deprecated. Two-phase bootstrap ink8s/argocd/bootstrap/BOOTSTRAP.md - Pull-based GitOps (Argo CD, no kubeconfig in CI); iterate =
git pushto Forgejo → auto-sync - Federated OIDC (Authentik provider for all services)
Deployment Checklist
- Service has Prometheus
/metricsendpoint or ServiceMonitor - All credentials in Vault (never in pod env, ConfigMap, or code)
- Ingress rule in
k8s/ingress/with TLS cert - Grafana dashboard in
k8s/monitoring/dashboards/svc-<name>.yaml - Alert rules in
k8s/monitoring/alerts/svc-<name>-rules.yaml(if needed) - Helm release in
helmfile.yaml.gotmplwith correctneeds:dependencies
Hard Rules
- No kubeconfig in CI — Argo CD bridges gap (pull-based, never push secrets to runner)
- Field name = variable name — In Vault:
talos put cluster/KAFKA_BOOTSTRAP KAFKA_BOOTSTRAP="..." - Secrets via volumes — Never
--envflag in pod specs (exposes inkubectl describe) - External services via Ingress — All public endpoints via TLS (homelab-ca)
- Never commit
.env— Only.env.examplein git; real secrets in Vault - Never rename or wipe
talos-cp-1(.213) — sole Longhorn storage node; renaming orphans its node CR and faults every volume (permanent data loss). Rename/reprovision only the dedicated CPs. - Control-plane etcd advertises on the LAN — keep
cluster.etcd.advertisedSubnets: ["192.168.1.0/24"], else Talos advertises on WireGuard and new members hang as etcd learners.
Git & Release
Multi-remote push:
git push origin main
Incremental commits (service-layer grouped):
- Foundation & Docs
- Helmfile & Core Infra
- Storage Layer
- Observability Stack
- IAM & Secrets
- CI/CD & GitOps
- Messaging Infrastructure
- Applications & Utilities