From 54bfb5ade62d6b3e70391190872d102f08f5f0b5 Mon Sep 17 00:00:00 2001 From: Story Crater Bot <19826264+Riotpiaole@users.noreply.github.com> Date: Sun, 19 Jul 2026 09:29:17 -0700 Subject: [PATCH] =?UTF-8?q?feat(gitops):=20migrate=20domain=20to=20riotpia?= =?UTF-8?q?o.com,=20add=20CNPG=20+=20Forgejo=20HA=20on=20Redis/Postgres,?= =?UTF-8?q?=20wire=20ArgoCD=20apps=20=E2=80=94=20enables=20cluster=20rebui?= =?UTF-8?q?ld=20after=20etcd=20wipe=20and=20unblocks=20the=20git-source=20?= =?UTF-8?q?chicken-egg=20via=20standalone=20Helm-source=20Applications?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.example | 4 +- .forgejo/CI-CD.md | 10 +- GITOPS_ARCHITECTURE.md | 4 +- GITOPS_MIGRATION_PLAN.md | 4 +- README.md | 34 ++-- Recover-Plan.md | 81 +++++++++ USAGE.md | 10 +- .../patches/forgejo-registry-ca.yaml | 4 +- k8s/applications/cloudflared/deployment.yaml | 37 +++++ .../cloudflared/kustomization.yaml | 5 + k8s/applications/dev-tools/README.md | 8 +- k8s/applications/dev-tools/build.sh | 2 +- k8s/applications/dev-tools/values.yaml | 4 +- k8s/applications/duckdns/kustomization.yaml | 5 +- k8s/applications/forge/runner.yaml | 8 +- k8s/applications/kustomization.yaml | 1 + .../sqs/argocd/apps/01-kafka-cluster.yaml | 2 +- .../sqs/argocd/apps/03-queue-crd.yaml | 4 +- .../argocd/apps/04-management-service.yaml | 8 +- k8s/applications/sqs/argocd/project.yaml | 2 +- k8s/applications/sqs/argocd/root.yaml | 2 +- .../sqs/charts/management-service/values.yaml | 4 +- .../sqs/environments/homelab.yaml | 4 +- k8s/applications/temporal/PHASE_2_TESTING.md | 2 +- .../temporal/TEMPORAL_OAUTH2_SETUP.md | 12 +- k8s/argocd/apps/0-minio.yaml | 6 +- k8s/argocd/apps/00-homelab-root.yaml | 2 +- k8s/argocd/apps/1-wave-1.yaml | 57 +++---- k8s/argocd/apps/2-wave-2.yaml | 55 +++--- k8s/argocd/apps/3-wave-3.yaml | 4 +- k8s/argocd/apps/cnpg-operator.yaml | 22 +++ k8s/argocd/apps/forgejo.yaml | 146 ++++++++++++++++ k8s/argocd/apps/layer-1-infrastructure.yaml | 2 +- k8s/argocd/apps/layer-2-bootstrap.yaml | 2 +- k8s/argocd/apps/layer-3-platform.yaml | 2 +- k8s/argocd/apps/layer-4-security.yaml | 2 +- k8s/argocd/apps/layer-5-applications.yaml | 2 +- k8s/argocd/apps/layer-6-data.yaml | 2 +- k8s/argocd/apps/phase0-minio.yaml | 4 +- k8s/argocd/apps/phase1-hookless-0.yaml | 10 +- .../apps/phase2-storage-observability-0.yaml | 4 +- .../apps/phase2-storage-observability-1.yaml | 4 +- k8s/argocd/apps/phase3-iam-0.yaml | 2 +- k8s/argocd/projects/homelab-project.yaml | 25 +++ .../cert-manager/letsencrypt-issuer.yaml | 45 +++++ k8s/bootstrap/coredns/coredns-configmap.yaml | 28 ++-- k8s/bootstrap/ingress/ingress.yaml | 30 ++-- k8s/bootstrap/ingress/nginx-values.yaml | 12 +- k8s/bootstrap/ingress/riotpiao-com-cert.yaml | 25 +++ k8s/bootstrap/ingress/wildcard-cert.yaml | 22 --- k8s/data/forgejo-database.yaml | 10 ++ k8s/data/kustomization.yaml | 1 + k8s/infrastructure/minio/minio-tenant.yaml | 4 +- k8s/infrastructure/minio/minio-values.yaml | 4 +- k8s/platform/logging/grafana-values.yaml | 10 +- .../monitoring/blackbox-exporter-values.yaml | 22 +-- k8s/security/ci-cd/argocd-values.yaml | 8 +- .../ci-cd/charts/forgejo-runner/values.yaml | 2 +- .../ci-cd/deploy-scaffold/api/deployment.yaml | 2 +- .../ci-cd/deploy-scaffold/apps/api.yaml | 2 +- .../ci-cd/deploy-scaffold/apps/argocd.yaml | 2 +- .../ci-cd/deploy-scaffold/apps/forge.yaml | 2 +- k8s/security/ci-cd/example-workflows/ci.yml | 6 +- k8s/security/ci-cd/forgejo-redis.yaml | 39 +++++ k8s/security/ci-cd/forgejo-values.yaml | 53 ++++-- k8s/security/ci-cd/kustomization.yaml | 8 +- k8s/security/ci-cd/talos-cli.sh | 4 +- k8s/security/iam/OAUTH_APP_SETUP.md | 12 +- k8s/security/iam/README.md | 6 +- k8s/security/iam/authentik-values.yaml | 6 +- .../iam/example_register_dashboard.py | 8 +- k8s/security/iam/register_oauth_app.py | 10 +- k8s/security/iam/setup_vault.sh | 14 +- k8s/security/iam/vault-values.yaml | 6 +- project-usage/authentik-oidc.md | 30 ++-- project-usage/cicd-workflow.md | 26 +-- project-usage/infra-practice.md | 4 +- project-usage/infra-troubleshooting.md | 2 +- project-usage/minio-s3.md | 10 +- project-usage/monitoring-metrics.md | 4 +- project-usage/networking-ingress.md | 26 +-- project-usage/sqs-messaging.md | 12 +- project-usage/vault-secrets.md | 4 +- terraform/main.tf | 156 +++++++++--------- terraform/templates/controlplane.tftpl | 2 +- terraform/variables.tf | 42 ++--- 86 files changed, 889 insertions(+), 446 deletions(-) create mode 100644 Recover-Plan.md create mode 100644 k8s/applications/cloudflared/deployment.yaml create mode 100644 k8s/applications/cloudflared/kustomization.yaml create mode 100644 k8s/argocd/apps/cnpg-operator.yaml create mode 100644 k8s/argocd/apps/forgejo.yaml create mode 100644 k8s/argocd/projects/homelab-project.yaml create mode 100644 k8s/bootstrap/cert-manager/letsencrypt-issuer.yaml create mode 100644 k8s/bootstrap/ingress/riotpiao-com-cert.yaml delete mode 100644 k8s/bootstrap/ingress/wildcard-cert.yaml create mode 100644 k8s/data/forgejo-database.yaml create mode 100644 k8s/security/ci-cd/forgejo-redis.yaml diff --git a/.env.example b/.env.example index 20918ec..0c6bca8 100644 --- a/.env.example +++ b/.env.example @@ -4,8 +4,8 @@ # ── Cluster Configuration ────────────────────────────────────────────────────── # Base domain for external services (Authentik, MinIO, Forgejo, etc.) -# Example: riotpiao.homelab.com -CLUSTER_DOMAIN=riotpiao.homelab.com +# Example: riotpiao.com +CLUSTER_DOMAIN=riotpiao.com # Internal Kubernetes DNS names (svc.cluster.local) # Only change these if your cluster domain differs diff --git a/.forgejo/CI-CD.md b/.forgejo/CI-CD.md index 6522a25..fdc434a 100644 --- a/.forgejo/CI-CD.md +++ b/.forgejo/CI-CD.md @@ -83,7 +83,7 @@ Resources: 23 ``` **Requires secrets:** -- `ARGOCD_SERVER`: ArgoCD server URL (https://argocd.riotpiao.homelab.com) +- `ARGOCD_SERVER`: ArgoCD server URL (https://argocd.riotpiao.com) - `ARGOCD_AUTH_TOKEN`: ArgoCD API token (generate via ArgoCD UI) ### 3. security-scan.yaml (Optional) @@ -131,7 +131,7 @@ Resources: 23 ```bash # On runner machine (inside cluster or external) forgejo-runner register \ - --instance https://forgejo.riotpiao.homelab.com \ + --instance https://forgejo.riotpiao.com \ --token \ --name homelab-runner \ --labels docker @@ -145,7 +145,7 @@ forgejo-runner daemon # Go to: Forgejo → Settings → Secrets # Add: -ARGOCD_SERVER = https://argocd.riotpiao.homelab.com +ARGOCD_SERVER = https://argocd.riotpiao.com ARGOCD_AUTH_TOKEN = # Generate: argocd account generate-token ``` @@ -240,7 +240,7 @@ kubeval k8s/platform/minio/config.yaml ```bash # Check ArgoCD UI -# https://argocd.riotpiao.homelab.com → homelab-root +# https://argocd.riotpiao.com → homelab-root # Or CLI argocd app get homelab-root @@ -286,7 +286,7 @@ Repository → Actions ### ArgoCD UI ``` -https://argocd.riotpiao.homelab.com +https://argocd.riotpiao.com ├─ homelab-root │ ├─ Status: Synced ✓ │ ├─ Health: Healthy ✓ diff --git a/GITOPS_ARCHITECTURE.md b/GITOPS_ARCHITECTURE.md index 1a05a5b..d5bdc18 100644 --- a/GITOPS_ARCHITECTURE.md +++ b/GITOPS_ARCHITECTURE.md @@ -163,7 +163,7 @@ metadata: spec: project: homelab source: - repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git + repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git targetRevision: main path: k8s/infrastructure # Start with Layer 0 destination: @@ -184,7 +184,7 @@ metadata: spec: project: homelab source: - repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git + repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git targetRevision: main path: k8s/bootstrap destination: diff --git a/GITOPS_MIGRATION_PLAN.md b/GITOPS_MIGRATION_PLAN.md index a2761fc..e2625c6 100644 --- a/GITOPS_MIGRATION_PLAN.md +++ b/GITOPS_MIGRATION_PLAN.md @@ -359,7 +359,7 @@ metadata: spec: project: homelab source: - repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git + repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git targetRevision: main path: k8s/infrastructure destination: @@ -382,7 +382,7 @@ metadata: spec: project: homelab source: - repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git + repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git targetRevision: main path: k8s/bootstrap destination: diff --git a/README.md b/README.md index 50f88b5..655d74c 100644 --- a/README.md +++ b/README.md @@ -60,7 +60,7 @@ Edit `.env` and fill in cluster configuration. See `.env.example` for all option ```bash # Cluster configuration -CLUSTER_DOMAIN=riotpiao.homelab.com # Your cluster domain +CLUSTER_DOMAIN=riotpiao.com # Your cluster domain POSTGRES_HOST=ddb-cluster-rw.ddb.svc.cluster.local MINIO_ENDPOINT=minio.storage.svc.cluster.local:9000 KAFKA_BOOTSTRAP=kmsvc-kafka-bootstrap.sqs.svc.cluster.local:9092 @@ -285,15 +285,15 @@ Add to `/etc/hosts` on every client machine (Mac/Linux): ``` # WireGuard access (remote — via talos-cp-1) -10.6.0.1 grafana.riotpiao.homelab.com authentik.riotpiao.homelab.com vault.riotpiao.homelab.com minio.riotpiao.homelab.com prometheus.riotpiao.homelab.com portainer.riotpiao.homelab.com longhorn.riotpiao.homelab.com loki.riotpiao.homelab.com forgejo.riotpiao.homelab.com temporal.riotpiao.homelab.com temporal-grpc.riotpiao.homelab.com kmsvc.riotpiao.homelab.com +10.6.0.1 grafana.riotpiao.com authentik.riotpiao.com vault.riotpiao.com minio.riotpiao.com prometheus.riotpiao.com portainer.riotpiao.com longhorn.riotpiao.com loki.riotpiao.com forgejo.riotpiao.com temporal.riotpiao.com temporal-grpc.riotpiao.com kmsvc.riotpiao.com # LAN access (on the home network — use actual LoadBalancer IP from above) -192.168.1.160 grafana.riotpiao.homelab.com authentik.riotpiao.homelab.com vault.riotpiao.homelab.com minio.riotpiao.homelab.com prometheus.riotpiao.homelab.com portainer.riotpiao.homelab.com longhorn.riotpiao.homelab.com loki.riotpiao.homelab.com forgejo.riotpiao.homelab.com temporal.riotpiao.homelab.com temporal-grpc.riotpiao.homelab.com kmsvc.riotpiao.homelab.com +192.168.1.160 grafana.riotpiao.com authentik.riotpiao.com vault.riotpiao.com minio.riotpiao.com prometheus.riotpiao.com portainer.riotpiao.com longhorn.riotpiao.com loki.riotpiao.com forgejo.riotpiao.com temporal.riotpiao.com temporal-grpc.riotpiao.com kmsvc.riotpiao.com ``` **Note:** `192.168.1.160` is an example Cilium LB-IPAM assignment. Verify with `kubectl get svc -n ingress-nginx ingress-nginx`. -**There is no real DNS wildcard for `*.riotpiao.homelab.com`** — every hostname must be added to `/etc/hosts` explicitly (as above) before it resolves. Adding a new Ingress host doesn't make it reachable by itself; add the line too. +**There is no real DNS wildcard for `*.riotpiao.com`** — every hostname must be added to `/etc/hosts` explicitly (as above) before it resolves. Adding a new Ingress host doesn't make it reachable by itself; add the line too. ### kubectl Context @@ -310,14 +310,14 @@ Then access services at: | Service | URL | Credentials | |---------|-----|-------------| -| Grafana | http://grafana.riotpiao.homelab.com | admin / `GRAFANA_ADMIN_PASSWORD` or Authentik SSO | -| Authentik | http://authentik.riotpiao.homelab.com | akadmin / see `.env` | -| Vault | http://vault.riotpiao.homelab.com | root token / see `setup_vault.sh` output | -| MinIO console | http://minio.riotpiao.homelab.com | `MINIO_ROOT_USER` / `MINIO_ROOT_PASSWORD` | -| Prometheus | http://prometheus.riotpiao.homelab.com | no auth | -| Portainer | http://portainer.riotpiao.homelab.com | set on first visit | -| Longhorn | http://longhorn.riotpiao.homelab.com | no auth | -| Forgejo *(planned)* | https://forgejo.forge.riotpiao.homelab.com | `rock` / `FORGEJO_ADMIN_PASSWORD`, or Authentik SSO | +| Grafana | http://grafana.riotpiao.com | admin / `GRAFANA_ADMIN_PASSWORD` or Authentik SSO | +| Authentik | http://authentik.riotpiao.com | akadmin / see `.env` | +| Vault | http://vault.riotpiao.com | root token / see `setup_vault.sh` output | +| MinIO console | http://minio.riotpiao.com | `MINIO_ROOT_USER` / `MINIO_ROOT_PASSWORD` | +| Prometheus | http://prometheus.riotpiao.com | no auth | +| Portainer | http://portainer.riotpiao.com | set on first visit | +| Longhorn | http://longhorn.riotpiao.com | no auth | +| Forgejo *(planned)* | https://forgejo.forge.riotpiao.com | `rock` / `FORGEJO_ADMIN_PASSWORD`, or Authentik SSO | | Argo CD *(planned)* | `kubectl port-forward -n argocd svc/argocd-server 8080:443` | Authentik SSO (admins only) | Grafana → "Homelab" folder has the operator dashboards (sidecar-loaded from `k8s/monitoring/dashboards/`, no restart needed on change): @@ -379,7 +379,7 @@ Authentik is the central OIDC identity provider. Vault stores secrets and delega │ │ OAuth2 / OIDC ▼ - Authentik (authentik.riotpiao.homelab.com) + Authentik (authentik.riotpiao.com) ├── grafana app → Grafana OIDC login (group → Admin/Viewer role) ├── minio app → MinIO OIDC login (group → readwrite/readonly policy) ├── vault-browser → Vault UI OIDC login / `vault login -method=oidc` @@ -387,7 +387,7 @@ Authentik is the central OIDC identity provider. Vault stores secrets and delega │ │ JWKS endpoint for JWT validation ▼ - HashiCorp Vault (vault.riotpiao.homelab.com) + HashiCorp Vault (vault.riotpiao.com) ├── auth/jwt — core-cli authenticates with device code JWT ├── auth/oidc — browser/UI login via Authentik └── secret/ — KV v2: mcp/*, cluster/*, cloud/* @@ -402,8 +402,8 @@ core put cluster/DUCKDNS_TOKEN DUCKDNS_TOKEN="abc" # field name = var **One-time IAM setup (after `helmfile apply`):** ```bash # 1. Provision OIDC apps and groups in Authentik -GRAFANA_URL=http://grafana.riotpiao.homelab.com \ -MINIO_URL=http://minio.riotpiao.homelab.com \ +GRAFANA_URL=http://grafana.riotpiao.com \ +MINIO_URL=http://minio.riotpiao.com \ python3 k8s/talos-iam/provision_oidc.py # 2. Init Vault, wire JWT + OIDC auth, seed secrets @@ -487,7 +487,7 @@ Pods / Talos journal (both nodes) │ Grafana (logging ns) queries Loki + Prometheus via dashboards │ - Nginx Ingress → grafana.riotpiao.homelab.com browser access + Nginx Ingress → grafana.riotpiao.com browser access ``` ## Example Applications & Workloads diff --git a/Recover-Plan.md b/Recover-Plan.md new file mode 100644 index 0000000..3028265 --- /dev/null +++ b/Recover-Plan.md @@ -0,0 +1,81 @@ +# Cluster Recovery Plan + +**Context:** Control-plane node (`talos-cp-1`, 192.168.1.213) had a corrupted machine CA in `terraform.tfvars`, causing a "broken key size" TLS error. During troubleshooting, an `apply-config` run with `install.wipe: true` (before the fix) wiped the OS/etcd disk (`sda`). Longhorn storage disks (`sdb`/`sdc`/`sdd`, ~1.26TB) were NOT touched and still hold data. etcd has since been re-bootstrapped fresh and empty; kube-apiserver/controller-manager/scheduler are running; node is `NotReady` (no CNI yet). + +## Phase 1 — Get CNI up (blocks everything else) + +Cluster config has `cni: name: none` (Cilium installs via Helm, not Talos-managed). Install via Helm, using KubePrism (already enabled, port 7445) as the API endpoint: + +```bash +helm repo add cilium https://helm.cilium.io/ +helm repo update +helm install cilium cilium/cilium --namespace kube-system \ + --set ipam.mode=kubernetes \ + --set kubeProxyReplacement=true \ + --set securityContext.capabilities.ciliumAgent="{CHOWN,KILL,NET_ADMIN,NET_RAW,IPC_LOCK,SYS_ADMIN,SYS_RESOURCE,DAC_OVERRIDE,FOWNER,SETGID,SETUID}" \ + --set securityContext.capabilities.cleanCiliumState="{NET_ADMIN,SYS_ADMIN,SYS_RESOURCE}" \ + --set cgroup.autoMount.enabled=false \ + --set cgroup.hostRoot=/sys/fs/cgroup \ + --set k8sServiceHost=localhost \ + --set k8sServicePort=7445 +``` + +Verify: node flips to `Ready`, `cilium status` reports OK. + +## Phase 2 — Bootstrap ArgoCD (app-of-apps) + +If ArgoCD's own manifests + root Application live in git (`k8s/argocd/`), recovery is a 3-step process: + +```bash +kubectl create namespace argocd +kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml +# wait for argocd-server to be Ready +kubectl apply -f k8s/argocd/root-app.yaml # app-of-apps entrypoint +``` + +Everything downstream (Longhorn CRDs, ingress, cert-manager, workloads) reconciles automatically from git once the root app syncs. + +## Phase 3 — Longhorn volume salvage (manual, per-volume, do after Longhorn CRDs reinstall) + +Replica data survived on disk; CRDs (PVC↔PV↔Volume mappings) did not. Official supported recovery path: "Export a Volume from a Single Replica." + +1. Confirm disk path via `longhorn-disk.cfg` (already confirmed: `/var/lib/longhorn-disk{1,2,3}`) +2. Locate `replicas//` directories, read `volume.meta` for size +3. Launch a temporary `longhornio/longhorn-engine` container against the replica directory to expose it as a block device +4. Mount and copy data out manually, per volume + +Not automatic — budget real time, one volume at a time. + +## Phase 4 — WireGuard / router path + +DuckDNS (`riotpiao.duckdns.org`) resolves correctly to current public IP (`24.114.42.68`, confirmed via Google + Cloudflare DNS). Tunnel fails to connect from **off-LAN** — needs router-side verification: +- Confirm port-forward rule is **UDP 51820 → 192.168.1.213:51820** exactly +- If double-NAT, forward must be on the outermost internet-facing router +- Confirm with ISP whether you're behind CGNAT (silently blocks all inbound forwarding) + +**Separately — LAN-side symptom:** tunnel also fails to connect **from the same LAN** as the server, via the public DDNS hostname. Root cause: **NAT hairpin/loopback not supported by the router** — traffic leaves the LAN, tries to loop back in via the public IP, and gets dropped. This is a router limitation, not a WireGuard/Shadowrocket bug. + +Fixes, in order of robustness: +1. Enable NAT hairpinning/loopback in router settings, if supported +2. Split-DNS: resolve the DDNS hostname to the LAN IP (`192.168.1.213`) for LAN clients only, via a local resolver (Pi-hole/dnsmasq/router DNS) +3. Quick workaround: manually point the Shadowrocket WireGuard peer endpoint at `192.168.1.213:51820` while on LAN; switch back to the DDNS hostname when away + +## Phase 5 — Redeploy DuckDNS updater + +The cluster wipe likely took out any in-cluster DuckDNS-refresh CronJob. Redeploy via GitOps once ArgoCD is back — standard pattern: a `CronJob` running `curl "https://www.duckdns.org/update?domains=riotpiao&token=...&ip="` every few minutes. + +--- + +**Recommended order:** Phase 1 (Cilium) → Phase 2 (ArgoCD) → Phase 4 (router/WireGuard, parallel) → Phase 5 (DuckDNS cron) → Phase 3 (Longhorn salvage, lowest urgency). + +## Sources + +- [How to Install Cilium on Talos Linux Step by Step](https://oneuptime.com/blog/post/2026-03-03-install-cilium-on-talos-linux-step-by-step/view) +- [Deploy Cilium CNI - Sidero Documentation](https://docs.siderolabs.com/kubernetes-guides/cni/deploying-cilium) +- [Cluster Bootstrapping - Argo CD](https://argo-cd.readthedocs.io/en/latest/operator-manual/cluster-bootstrapping/) +- [How to Bootstrap an Entire Cluster with ArgoCD App-of-Apps](https://oneuptime.com/blog/post/2026-02-26-argocd-bootstrap-cluster-app-of-apps/view) +- [Restoring Data from an Orphaned Replica Directory - Longhorn KB](https://longhorn.io/kb/restoring-data-from-an-orphaned-replica-directory/) +- [Port Forwarding for WireGuard](https://portforward.com/wireguard/) +- [Guide Wireguard-portforwarding - SNBForums](https://www.snbforums.com/threads/guide-wireguard-portforwarding.89737/) +- [Help with hairpin NAT for wireguard on ubuntu server - Ubiquiti Community](https://community.ui.com/questions/Help-with-hairpin-NAT-for-wireguard-on-ubuntu-server/12d4cbe7-f1f5-448d-9d77-ea8226c18f16) +- [Wireguard VPN on Pi4 - cannot connect client - Raspberry Pi Forums](https://forums.raspberrypi.com/viewtopic.php?t=339692) diff --git a/USAGE.md b/USAGE.md index a1744a6..115be1a 100644 --- a/USAGE.md +++ b/USAGE.md @@ -209,7 +209,7 @@ core iam list-apps #### Create New Application ```bash -core iam create-app "my-service" --slug my-service --redirect-uri "https://my-service.riotpiao.homelab.com/callback" +core iam create-app "my-service" --slug my-service --redirect-uri "https://my-service.riotpiao.com/callback" ``` Returns client ID and secret (save immediately). @@ -331,13 +331,13 @@ core get cluster/iam/roles/admin --key roles export REGISTRY_TOKEN=$(core get cluster/iam/agents/ci-bot --key token) # 2. Authenticate docker/podman to Forgejo registry -docker login forgejo.riotpiao.homelab.com \ +docker login forgejo.riotpiao.com \ --username ci-bot \ --password "$REGISTRY_TOKEN" # 3. Tag and push image -docker tag myapp:latest forgejo.riotpiao.homelab.com/rock/myapp:latest -docker push forgejo.riotpiao.homelab.com/rock/myapp:latest +docker tag myapp:latest forgejo.riotpiao.com/rock/myapp:latest +docker push forgejo.riotpiao.com/rock/myapp:latest ``` **Pull images in runner (automatic):** @@ -345,7 +345,7 @@ docker push forgejo.riotpiao.homelab.com/rock/myapp:latest ```bash # Inside .forgejo/workflows/*.yml, runner pulls via K8s ServiceAccount # No explicit login needed — imagePullSecrets injected by runner pod -image: forgejo.riotpiao.homelab.com/rock/myapp:latest +image: forgejo.riotpiao.com/rock/myapp:latest ``` **Runner pod setup:** diff --git a/cluster-config/patches/forgejo-registry-ca.yaml b/cluster-config/patches/forgejo-registry-ca.yaml index c4c7710..e51fbe9 100644 --- a/cluster-config/patches/forgejo-registry-ca.yaml +++ b/cluster-config/patches/forgejo-registry-ca.yaml @@ -1,10 +1,10 @@ # Trust the homelab-ca CA for pulling from the Forgejo container registry. # Without this, containerd fails: x509 certificate signed by unknown authority -# (nginx terminates forgejo.riotpiao.homelab.com TLS with a homelab-ca cert). +# (nginx terminates forgejo.riotpiao.com TLS with a homelab-ca cert). # Apply: talosctl -n patch mc --patch @cluster-config/patches/forgejo-registry-ca.yaml machine: registries: config: - forgejo.riotpiao.homelab.com: + forgejo.riotpiao.com: tls: ca: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJiVENDQVJTZ0F3SUJBZ0lVYTBVaGs3Rm81d3BiWjZsRzVEWWJUVkFic1k4d0NnWUlLb1pJemowRUF3SXcKRlRFVE1CRUdBMVVFQXhNS2FHOXRaV3hoWWkxallUQWVGdzB5TmpBM01UQXdORFF3TXpaYUZ3MHpOakEzTURjdwpORFF3TXpaYU1CVXhFekFSQmdOVkJBTVRDbWh2YldWc1lXSXRZMkV3V1RBVEJnY3Foa2pPUFFJQkJnZ3Foa2pPClBRTUJCd05DQUFTc1pNU2piUWI0YzNiUk00MjMxVEVrRXVLTnFLUUhaaW5uYnUzbWZGbStRc0wweTF3cjg1Uk0KUWJ6ZEZ2N01JZmN4REpMbHFqQTY1bEJ6TE9pdHRZZHRvMEl3UURBT0JnTlZIUThCQWY4RUJBTUNBcVF3RHdZRApWUjBUQVFIL0JBVXdBd0VCL3pBZEJnTlZIUTRFRmdRVUVmcGJQL3FnYWsxaXUvQzdaQi9uZk5zc0hpd3dDZ1lJCktvWkl6ajBFQXdJRFJ3QXdSQUlnR2ltdnJiWU1xZjhGYThCeTBBM0M1ak1VL0d3dGU0NHgzOU4rRDRyaTJ1a0MKSUNkOEtIQXhhV0s2ZkVJcEFYZGdUQ1FxQmFiZjVZUDdhQzNDVzkzYkNsTjIKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo= diff --git a/k8s/applications/cloudflared/deployment.yaml b/k8s/applications/cloudflared/deployment.yaml new file mode 100644 index 0000000..7404e72 --- /dev/null +++ b/k8s/applications/cloudflared/deployment.yaml @@ -0,0 +1,37 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: cloudflared + namespace: cloudflared +spec: + replicas: 2 + selector: + matchLabels: + app: cloudflared + template: + metadata: + labels: + app: cloudflared + spec: + containers: + - name: cloudflared + image: cloudflare/cloudflared:latest + args: + - tunnel + - --no-autoupdate + - run + - --token + - $(TUNNEL_TOKEN) + env: + - name: TUNNEL_TOKEN + valueFrom: + secretKeyRef: + name: cloudflared-token + key: token + resources: + requests: + cpu: 10m + memory: 32Mi + limits: + cpu: 100m + memory: 128Mi diff --git a/k8s/applications/cloudflared/kustomization.yaml b/k8s/applications/cloudflared/kustomization.yaml new file mode 100644 index 0000000..3e60949 --- /dev/null +++ b/k8s/applications/cloudflared/kustomization.yaml @@ -0,0 +1,5 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +namespace: cloudflared +resources: + - deployment.yaml diff --git a/k8s/applications/dev-tools/README.md b/k8s/applications/dev-tools/README.md index 2017360..e239bfc 100644 --- a/k8s/applications/dev-tools/README.md +++ b/k8s/applications/dev-tools/README.md @@ -9,17 +9,17 @@ Build for `linux/amd64`: ```bash cd homelab docker buildx build --platform linux/amd64 \ - -t forgejo.riotpiao.homelab.com/rock/claude-terminal:latest \ + -t forgejo.riotpiao.com/rock/claude-terminal:latest \ -f k8s/dev-tools/Dockerfile \ k8s/dev-tools # Log in to Forgejo registry -docker login forgejo.riotpiao.homelab.com \ +docker login forgejo.riotpiao.com \ --username ci-bot \ --password "$(talos get cluster/iam/agents/ci-bot --key token)" # Push -docker push forgejo.riotpiao.homelab.com/rock/claude-terminal:latest +docker push forgejo.riotpiao.com/rock/claude-terminal:latest ``` Or use the provided build script: @@ -36,7 +36,7 @@ Update `values.yaml` if needed, then deploy via helmfile: helmfile apply -l name=claude-terminal ``` -Access the terminal at: **https://claude.riotpiao.homelab.com** +Access the terminal at: **https://claude.riotpiao.com** ## Persistent Storage diff --git a/k8s/applications/dev-tools/build.sh b/k8s/applications/dev-tools/build.sh index 62e258c..2658d66 100755 --- a/k8s/applications/dev-tools/build.sh +++ b/k8s/applications/dev-tools/build.sh @@ -1,7 +1,7 @@ #!/bin/bash set -euo pipefail -REGISTRY="forgejo.riotpiao.homelab.com" +REGISTRY="forgejo.riotpiao.com" IMAGE_NAME="rock/claude-terminal" TAG="latest" FULL_IMAGE="${REGISTRY}/${IMAGE_NAME}:${TAG}" diff --git a/k8s/applications/dev-tools/values.yaml b/k8s/applications/dev-tools/values.yaml index ddca0de..a8a468b 100644 --- a/k8s/applications/dev-tools/values.yaml +++ b/k8s/applications/dev-tools/values.yaml @@ -15,14 +15,14 @@ ingress: annotations: cert-manager.io/cluster-issuer: homelab-ca hosts: - - host: claude.riotpiao.homelab.com + - host: claude.riotpiao.com paths: - path: / pathType: Prefix tls: - secretName: claude-terminal-tls hosts: - - claude.riotpiao.homelab.com + - claude.riotpiao.com persistence: enabled: true diff --git a/k8s/applications/duckdns/kustomization.yaml b/k8s/applications/duckdns/kustomization.yaml index f81a4ff..33dbae4 100644 --- a/k8s/applications/duckdns/kustomization.yaml +++ b/k8s/applications/duckdns/kustomization.yaml @@ -1,5 +1,4 @@ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization -namespace: duckdns -resources: [] -# DuckDNS deployed via Helm chart or CronJob +resources: + - duckdns-corn.yaml diff --git a/k8s/applications/forge/runner.yaml b/k8s/applications/forge/runner.yaml index 763e249..ef406a5 100644 --- a/k8s/applications/forge/runner.yaml +++ b/k8s/applications/forge/runner.yaml @@ -21,7 +21,7 @@ # The homelab-ca secret above only reaches the runner/register/dind containers. # It does NOT reach the per-job containers DinD spawns (e.g. golangci-lint, # node:22-bookworm) — those are fresh sibling containers with their own trust -# store. Without this, any git/curl/apk call to forgejo.riotpiao.homelab.com +# store. Without this, any git/curl/apk call to forgejo.riotpiao.com # from inside a job fails with "SSL certificate problem: unable to get local # issuer certificate". Build a merged bundle (public roots + homelab CA) and # bind-mount it over /etc/ssl/certs/ca-certificates.crt in every job @@ -30,7 +30,7 @@ # IMPORTANT: source the CA from the live cluster secret, NOT from # k8s/forge/pki/ca.crt — that repo file is a stale CA from before the # "unified certificate" migration (different key, fails verification -# against the cert actually served by forgejo.riotpiao.homelab.com). The +# against the cert actually served by forgejo.riotpiao.com). The # org-wide CA that signs the live ingress cert lives in # cert-manager/homelab-ca-secret, and cicd/homelab-ca above is already # synced from it. @@ -220,7 +220,7 @@ spec: - | test -f /data/.runner && echo "already registered, skipping" && exit 0 forgejo-runner register --no-interactive \ - --instance https://forgejo.riotpiao.homelab.com \ + --instance https://forgejo.riotpiao.com \ --token "$RUNNER_TOKEN" \ --name talos-runner \ --labels "docker:docker://node:22-bookworm" @@ -407,7 +407,7 @@ spec: - to: - podSelector: {} # ingress-nginx (the runner talks to Forgejo via its public hostname, - # https://forgejo.riotpiao.homelab.com, which resolves to the ingress + # https://forgejo.riotpiao.com, which resolves to the ingress # controller's ClusterIP — a different namespace on the pod network) - to: - namespaceSelector: diff --git a/k8s/applications/kustomization.yaml b/k8s/applications/kustomization.yaml index 976ceb8..4f4af3b 100644 --- a/k8s/applications/kustomization.yaml +++ b/k8s/applications/kustomization.yaml @@ -16,3 +16,4 @@ resources: - shadowsocks/ - dev-tools/ - duckdns/ + - cloudflared/ diff --git a/k8s/applications/sqs/argocd/apps/01-kafka-cluster.yaml b/k8s/applications/sqs/argocd/apps/01-kafka-cluster.yaml index a27d542..ef90331 100644 --- a/k8s/applications/sqs/argocd/apps/01-kafka-cluster.yaml +++ b/k8s/applications/sqs/argocd/apps/01-kafka-cluster.yaml @@ -8,7 +8,7 @@ metadata: spec: project: kmsvc source: - repoURL: https://forgejo.riotpiao.homelab.com/rock/kafaka-management-service.git + repoURL: https://forgejo.riotpiao.com/rock/kafaka-management-service.git targetRevision: main path: k8s/charts/kafka-cluster helm: diff --git a/k8s/applications/sqs/argocd/apps/03-queue-crd.yaml b/k8s/applications/sqs/argocd/apps/03-queue-crd.yaml index 495d309..874ced0 100644 --- a/k8s/applications/sqs/argocd/apps/03-queue-crd.yaml +++ b/k8s/applications/sqs/argocd/apps/03-queue-crd.yaml @@ -8,7 +8,7 @@ metadata: spec: project: kmsvc source: - repoURL: https://forgejo.riotpiao.homelab.com/rock/kafaka-management-service.git + repoURL: https://forgejo.riotpiao.com/rock/kafaka-management-service.git targetRevision: main path: k8s/charts/queue-crd helm: @@ -17,7 +17,7 @@ spec: kafkaBrokers: "kmsvc-kafka-bootstrap.sqs.svc.cluster.local:9092" redisAddr: "kmsvc-redis-master.sqs.svc.cluster.local:6379" image: - repository: forgejo.riotpiao.homelab.com/rock/kafka-management-service-queue-operator + repository: forgejo.riotpiao.com/rock/kafka-management-service-queue-operator # CI (.forgejo/workflows/release.yaml) writes the released git tag # here and pushes the commit -- ArgoCD picks it up on its next sync. tag: latest diff --git a/k8s/applications/sqs/argocd/apps/04-management-service.yaml b/k8s/applications/sqs/argocd/apps/04-management-service.yaml index 459c8ee..9e56a39 100644 --- a/k8s/applications/sqs/argocd/apps/04-management-service.yaml +++ b/k8s/applications/sqs/argocd/apps/04-management-service.yaml @@ -8,25 +8,25 @@ metadata: spec: project: kmsvc source: - repoURL: https://forgejo.riotpiao.homelab.com/rock/kafaka-management-service.git + repoURL: https://forgejo.riotpiao.com/rock/kafaka-management-service.git targetRevision: main path: k8s/charts/management-service helm: values: | namespace: sqs image: - repository: forgejo.riotpiao.homelab.com/rock/kafka-management-service + repository: forgejo.riotpiao.com/rock/kafka-management-service # CI (.forgejo/workflows/release.yaml) writes the released git tag # here and pushes the commit -- ArgoCD picks it up on its next sync. tag: latest env: kafkaBrokers: "kmsvc-kafka-bootstrap.sqs.svc.cluster.local:9092" redisAddr: "kmsvc-redis-master.sqs.svc.cluster.local:6379" - authentikIssuerURL: "https://authentik.riotpiao.homelab.com/application/o/kafaka/" + authentikIssuerURL: "https://authentik.riotpiao.com/application/o/kafaka/" authentikAudience: "QI0gPtR99ar8VvhK8Tqox4SDkTKzbNU7lbgwBNSc" ingress: enabled: true - host: kmsvc.riotpiao.homelab.com + host: kmsvc.riotpiao.com clusterIssuer: homelab-ca destination: server: https://kubernetes.default.svc diff --git a/k8s/applications/sqs/argocd/project.yaml b/k8s/applications/sqs/argocd/project.yaml index 062b2d6..73c8bb3 100644 --- a/k8s/applications/sqs/argocd/project.yaml +++ b/k8s/applications/sqs/argocd/project.yaml @@ -6,7 +6,7 @@ metadata: spec: description: Kafka Management Service (design.md) -- Strimzi/Kafka, Redis, queue-operator, message-plane server sourceRepos: - - https://forgejo.riotpiao.homelab.com/rock/kafaka-management-service.git + - https://forgejo.riotpiao.com/rock/kafaka-management-service.git - https://strimzi.io/charts/ - https://charts.bitnami.com/bitnami destinations: diff --git a/k8s/applications/sqs/argocd/root.yaml b/k8s/applications/sqs/argocd/root.yaml index 240b1b0..1a7d14e 100644 --- a/k8s/applications/sqs/argocd/root.yaml +++ b/k8s/applications/sqs/argocd/root.yaml @@ -6,7 +6,7 @@ metadata: spec: project: kmsvc source: - repoURL: https://forgejo.riotpiao.homelab.com/rock/kafaka-management-service.git + repoURL: https://forgejo.riotpiao.com/rock/kafaka-management-service.git targetRevision: main path: k8s/argocd/apps directory: diff --git a/k8s/applications/sqs/charts/management-service/values.yaml b/k8s/applications/sqs/charts/management-service/values.yaml index 215d6a7..ede1e6c 100644 --- a/k8s/applications/sqs/charts/management-service/values.yaml +++ b/k8s/applications/sqs/charts/management-service/values.yaml @@ -40,10 +40,10 @@ ingress: enabled: true className: nginx clusterIssuer: homelab-ca - host: kmsvc.riotpiao.homelab.com + host: kmsvc.riotpiao.com tlsSecretName: kmsvc-tls # kmsvc-cli connects via gRPC directly to --server/KMSVC_SERVER (default - # kmsvc.riotpiao.homelab.com:443, see kmsvc-cli's README), so raw gRPC needs an + # kmsvc.riotpiao.com:443, see kmsvc-cli's README), so raw gRPC needs an # external path too — scoped to the gRPC service's own path prefix on the # same host/port, rather than opening the whole host to gRPC passthrough. grpcEnabled: true diff --git a/k8s/applications/sqs/environments/homelab.yaml b/k8s/applications/sqs/environments/homelab.yaml index 774f724..44aa6ee 100644 --- a/k8s/applications/sqs/environments/homelab.yaml +++ b/k8s/applications/sqs/environments/homelab.yaml @@ -23,7 +23,7 @@ redis: managementService: ingress: - host: kmsvc.riotpiao.homelab.com + host: kmsvc.riotpiao.com clusterIssuer: homelab-ca - authentikIssuerURL: "https://authentik.riotpiao.homelab.com/application/o/kafaka/" + authentikIssuerURL: "https://authentik.riotpiao.com/application/o/kafaka/" authentikAudience: "QI0gPtR99ar8VvhK8Tqox4SDkTKzbNU7lbgwBNSc" diff --git a/k8s/applications/temporal/PHASE_2_TESTING.md b/k8s/applications/temporal/PHASE_2_TESTING.md index 5c5a0eb..2531c66 100644 --- a/k8s/applications/temporal/PHASE_2_TESTING.md +++ b/k8s/applications/temporal/PHASE_2_TESTING.md @@ -119,7 +119,7 @@ worker-production-5f8b4c... 1/1 Running 0 10s ### Step 5: Verify Worker Connected to Temporal Namespace Check Temporal UI for namespace "production": ```bash -open https://temporal.riotpiao.homelab.com/namespaces/production/task-queues +open https://temporal.riotpiao.com/namespaces/production/task-queues ``` Look for all task queues with worker count > 0: diff --git a/k8s/applications/temporal/TEMPORAL_OAUTH2_SETUP.md b/k8s/applications/temporal/TEMPORAL_OAUTH2_SETUP.md index df335cb..e292132 100644 --- a/k8s/applications/temporal/TEMPORAL_OAUTH2_SETUP.md +++ b/k8s/applications/temporal/TEMPORAL_OAUTH2_SETUP.md @@ -19,7 +19,7 @@ Browser → Ingress (TLS) → oauth2-proxy (OIDC check) → temporal-web (intern ✅ Authentik OIDC provider `temporal` already exists with: - Client ID: `temporal` - Client Secret: stored in Kubernetes secret `temporal-oidc` (key: `clientSecret`) -- Redirect URI: `https://temporal.riotpiao.homelab.com/oauth2/callback` +- Redirect URI: `https://temporal.riotpiao.com/oauth2/callback` ## Secrets @@ -85,14 +85,14 @@ kubectl get ingress -n temporal Expected: ``` NAME CLASS HOSTS ADDRESS PORTS AGE -temporal nginx temporal.riotpiao.homelab.com ... 80, 443 10s +temporal nginx temporal.riotpiao.com ... 80, 443 10s ``` ### Step 3: Test Access 1. **Open Temporal UI (unauthenticated):** ```bash - open https://temporal.riotpiao.homelab.com + open https://temporal.riotpiao.com ``` Expected: Redirects to Authentik login page @@ -100,12 +100,12 @@ temporal nginx temporal.riotpiao.homelab.com ... 80, 443 10s 2. **Login with Authentik credentials** - Username/email - Password - - Should redirect back to `temporal.riotpiao.homelab.com` and display UI + - Should redirect back to `temporal.riotpiao.com` and display UI 3. **Verify auth:** ```bash # Check for oauth2_proxy cookie - curl -v https://temporal.riotpiao.homelab.com 2>&1 | grep -i cookie + curl -v https://temporal.riotpiao.com 2>&1 | grep -i cookie ``` 4. **Check oauth2-proxy logs:** @@ -127,7 +127,7 @@ redirect_uri_mismatch: The redirect_uri does not match the one registered in Aut ``` Fix: -- Verify Authentik application (Applications → temporal) has redirect URI: `https://temporal.riotpiao.homelab.com/oauth2/callback` +- Verify Authentik application (Applications → temporal) has redirect URI: `https://temporal.riotpiao.com/oauth2/callback` - Ensure HTTPS (not HTTP) ### Missing secret diff --git a/k8s/argocd/apps/0-minio.yaml b/k8s/argocd/apps/0-minio.yaml index 3bd650c..3aec051 100644 --- a/k8s/argocd/apps/0-minio.yaml +++ b/k8s/argocd/apps/0-minio.yaml @@ -10,7 +10,7 @@ metadata: spec: project: homelab source: - repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git + repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git targetRevision: main path: k8s/sqs directory: @@ -35,7 +35,7 @@ metadata: spec: project: homelab source: - repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git + repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git targetRevision: main path: k8s/sqs directory: @@ -60,7 +60,7 @@ metadata: spec: project: homelab source: - repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git + repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git targetRevision: main path: k8s/monitoring directory: diff --git a/k8s/argocd/apps/00-homelab-root.yaml b/k8s/argocd/apps/00-homelab-root.yaml index 5690153..a4113c6 100644 --- a/k8s/argocd/apps/00-homelab-root.yaml +++ b/k8s/argocd/apps/00-homelab-root.yaml @@ -8,7 +8,7 @@ metadata: spec: project: homelab source: - repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git + repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git targetRevision: main path: k8s/argocd/root destination: diff --git a/k8s/argocd/apps/1-wave-1.yaml b/k8s/argocd/apps/1-wave-1.yaml index ae56f88..4b0e197 100644 --- a/k8s/argocd/apps/1-wave-1.yaml +++ b/k8s/argocd/apps/1-wave-1.yaml @@ -10,7 +10,7 @@ metadata: spec: project: homelab source: - repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git + repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git targetRevision: main path: k8s/talos-iam directory: @@ -33,7 +33,7 @@ metadata: spec: project: homelab source: - repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git + repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git targetRevision: main path: k8s/logging directory: @@ -45,29 +45,30 @@ spec: automated: prune: true selfHeal: true ---- -apiVersion: argoproj.io/v1alpha1 -kind: Application -metadata: - name: cloudnative-pg - namespace: argocd - annotations: - argocd.argoproj.io/sync-wave: "1" -spec: - project: homelab - source: - repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git - targetRevision: main - path: k8s/ddb - directory: - recurse: false - destination: - server: https://kubernetes.default.svc - namespace: ddb - syncPolicy: - automated: - prune: true - selfHeal: true +# cloudnative-pg: managed separately via k8s/argocd/apps/cnpg-operator.yaml +# (Helm-source Application, avoids the git chicken-egg for the operator itself) +# apiVersion: argoproj.io/v1alpha1 +# kind: Application +# metadata: +# name: cloudnative-pg +# namespace: argocd +# annotations: +# argocd.argoproj.io/sync-wave: "1" +# spec: +# project: homelab +# source: +# repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git +# targetRevision: main +# path: k8s/ddb +# directory: +# recurse: false +# destination: +# server: https://kubernetes.default.svc +# namespace: ddb +# syncPolicy: +# automated: +# prune: true +# selfHeal: true --- apiVersion: argoproj.io/v1alpha1 kind: Application @@ -79,7 +80,7 @@ metadata: spec: project: homelab source: - repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git + repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git targetRevision: main path: k8s/talos-iam directory: @@ -101,7 +102,7 @@ metadata: spec: project: homelab source: - repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git + repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git targetRevision: main path: k8s/temporal directory: @@ -124,7 +125,7 @@ metadata: spec: project: homelab source: - repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git + repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git targetRevision: main path: k8s/sqs directory: diff --git a/k8s/argocd/apps/2-wave-2.yaml b/k8s/argocd/apps/2-wave-2.yaml index 4fcd0b4..7ce49bf 100644 --- a/k8s/argocd/apps/2-wave-2.yaml +++ b/k8s/argocd/apps/2-wave-2.yaml @@ -8,7 +8,7 @@ metadata: spec: project: homelab source: - repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git + repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git targetRevision: main path: k8s/sqs directory: @@ -31,7 +31,7 @@ metadata: spec: project: homelab source: - repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git + repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git targetRevision: main path: k8s/sqs directory: @@ -54,7 +54,7 @@ metadata: spec: project: homelab source: - repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git + repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git targetRevision: main path: k8s/logging directory: @@ -77,7 +77,7 @@ metadata: spec: project: homelab source: - repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git + repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git targetRevision: main path: k8s/logging directory: @@ -89,26 +89,27 @@ spec: automated: prune: true selfHeal: true ---- -apiVersion: argoproj.io/v1alpha1 -kind: Application -metadata: - name: forgejo - namespace: argocd - annotations: - argocd.argoproj.io/sync-wave: "2" -spec: - project: homelab - source: - repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git - targetRevision: main - path: k8s/talos-ci-cd - directory: - recurse: false - destination: - server: https://kubernetes.default.svc - namespace: cicd - syncPolicy: - automated: - prune: true - selfHeal: true +# forgejo: managed separately via k8s/argocd/apps/forgejo.yaml +# (Helm-source Application with inlined values, avoids the git chicken-egg) +# apiVersion: argoproj.io/v1alpha1 +# kind: Application +# metadata: +# name: forgejo +# namespace: argocd +# annotations: +# argocd.argoproj.io/sync-wave: "2" +# spec: +# project: homelab +# source: +# repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git +# targetRevision: main +# path: k8s/talos-ci-cd +# directory: +# recurse: false +# destination: +# server: https://kubernetes.default.svc +# namespace: cicd +# syncPolicy: +# automated: +# prune: true +# selfHeal: true diff --git a/k8s/argocd/apps/3-wave-3.yaml b/k8s/argocd/apps/3-wave-3.yaml index 5e8b417..98246e5 100644 --- a/k8s/argocd/apps/3-wave-3.yaml +++ b/k8s/argocd/apps/3-wave-3.yaml @@ -8,7 +8,7 @@ metadata: spec: project: homelab source: - repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git + repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git targetRevision: main path: k8s/talos-ci-cd directory: @@ -31,7 +31,7 @@ metadata: spec: project: homelab source: - repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git + repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git targetRevision: main path: k8s/portainer directory: diff --git a/k8s/argocd/apps/cnpg-operator.yaml b/k8s/argocd/apps/cnpg-operator.yaml new file mode 100644 index 0000000..ce70bcf --- /dev/null +++ b/k8s/argocd/apps/cnpg-operator.yaml @@ -0,0 +1,22 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: cnpg-operator + namespace: argocd + annotations: + argocd.argoproj.io/sync-wave: "0" +spec: + project: homelab + source: + repoURL: https://cloudnative-pg.github.io/charts + chart: cloudnative-pg + targetRevision: "*" + destination: + server: https://kubernetes.default.svc + namespace: ddb + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true diff --git a/k8s/argocd/apps/forgejo.yaml b/k8s/argocd/apps/forgejo.yaml new file mode 100644 index 0000000..28987cc --- /dev/null +++ b/k8s/argocd/apps/forgejo.yaml @@ -0,0 +1,146 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: forgejo + namespace: argocd + annotations: + argocd.argoproj.io/sync-wave: "7" + # Must sync after cnpg-operator (wave 0) and the ddb-cluster/forgejo-database + # (wave 6, k8s/data) — Forgejo's DB connection depends on both existing first. +spec: + project: homelab + source: + repoURL: https://dl.gitea.com/charts/ + chart: gitea + targetRevision: "~10" + helm: + # Mirrors k8s/security/ci-cd/forgejo-values.yaml inline — avoids the + # git-repo chicken-egg (Forgejo can't source its own values from a repo + # it hosts). Keep both files in sync when editing either one. + valuesObject: + image: + repository: codeberg.org/forgejo/forgejo + tag: "13" + pullPolicy: IfNotPresent + gitea: + admin: + username: rock + email: locartrock@gmail.com + config: + server: + PROTOCOL: http + DOMAIN: forgejo.riotpiao.com + ROOT_URL: https://forgejo.riotpiao.com/ + HTTP_PORT: 3000 + START_SSH_SERVER: true + SSH_DOMAIN: forgejo.riotpiao.com + SSH_PORT: 2222 + SSH_LISTEN_PORT: 2222 + database: + DB_TYPE: postgres + HOST: ddb-cluster-rw.ddb.svc:5432 + NAME: forgejo + USER: app + repository: + ROOT: /data/git + actions: + ENABLED: true + packages: + ENABLED: true + metrics: + ENABLED: true + service: + DISABLE_REGISTRATION: true + oauth2: + ENABLED: true + PROVIDER: openidconnect + OPENID_CONNECT_DISCOVERY_URL: https://authentik.riotpiao.com/application/o/forgejo/.well-known/openid-configuration + CLIENT_ID: forgejo + AUTO_DISCOVER_URL: https://authentik.riotpiao.com/application/o/forgejo/.well-known/openid-configuration + cache: + ADAPTER: redis + HOST: "redis://forgejo-redis.cicd.svc:6379/0" + session: + PROVIDER: redis + PROVIDER_CONFIG: "redis://forgejo-redis.cicd.svc:6379/1" + queue: + TYPE: redis + CONN_STR: "redis://forgejo-redis.cicd.svc:6379/2" + metrics: + enabled: true + serviceMonitor: + enabled: false + persistence: + enabled: true + storageClass: longhorn + size: 20Gi + accessModes: + - ReadWriteMany + replicaCount: 2 + deployment: + strategy: + type: RollingUpdate + env: + - name: SSL_CERT_DIR + value: /homelab-ca + - name: GITEA__database__PASSWD + valueFrom: + secretKeyRef: + name: ddb-cluster-app + key: password + podAnnotations: + configmap.reloader.stakater.com/reload: "homelab-ca" + service: + http: + type: LoadBalancer + port: 3000 + targetPort: 3000 + annotations: + io.cilium/lb-ipam-ips: "192.168.1.165" + io.cilium/lb-ipam-sharing-key: "forgejo" + ssh: + type: LoadBalancer + port: 2222 + targetPort: 2222 + annotations: + io.cilium/lb-ipam-ips: "192.168.1.165" + io.cilium/lb-ipam-sharing-key: "forgejo" + resources: + requests: + cpu: 250m + memory: 512Mi + limits: + cpu: "1" + memory: 1Gi + tolerations: + - key: node-role.kubernetes.io/control-plane + operator: Exists + effect: NoSchedule + extraVolumes: + - name: homelab-ca + configMap: + name: homelab-ca + extraVolumeMounts: + - name: homelab-ca + mountPath: /homelab-ca + readOnly: true + ingress: + enabled: false + postgresql: + enabled: false + postgresql-ha: + enabled: false + mysql: + enabled: false + redis-cluster: + enabled: false + act_runner: + enabled: false + destination: + server: https://kubernetes.default.svc + namespace: cicd + syncPolicy: + syncOptions: + - CreateNamespace=true + # NO automated sync — Forgejo is what CI uses to push commits; auto-sync + # would let a bad CI commit break the system CI depends on. Manual only. diff --git a/k8s/argocd/apps/layer-1-infrastructure.yaml b/k8s/argocd/apps/layer-1-infrastructure.yaml index 61be883..c387b3c 100644 --- a/k8s/argocd/apps/layer-1-infrastructure.yaml +++ b/k8s/argocd/apps/layer-1-infrastructure.yaml @@ -8,7 +8,7 @@ metadata: spec: project: homelab source: - repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git + repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git targetRevision: main path: k8s/infrastructure destination: diff --git a/k8s/argocd/apps/layer-2-bootstrap.yaml b/k8s/argocd/apps/layer-2-bootstrap.yaml index a960332..a64779e 100644 --- a/k8s/argocd/apps/layer-2-bootstrap.yaml +++ b/k8s/argocd/apps/layer-2-bootstrap.yaml @@ -8,7 +8,7 @@ metadata: spec: project: homelab source: - repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git + repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git targetRevision: main path: k8s/bootstrap destination: diff --git a/k8s/argocd/apps/layer-3-platform.yaml b/k8s/argocd/apps/layer-3-platform.yaml index 28b02ee..8e6d5a8 100644 --- a/k8s/argocd/apps/layer-3-platform.yaml +++ b/k8s/argocd/apps/layer-3-platform.yaml @@ -8,7 +8,7 @@ metadata: spec: project: homelab source: - repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git + repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git targetRevision: main path: k8s/platform destination: diff --git a/k8s/argocd/apps/layer-4-security.yaml b/k8s/argocd/apps/layer-4-security.yaml index ffe4fb8..d24487c 100644 --- a/k8s/argocd/apps/layer-4-security.yaml +++ b/k8s/argocd/apps/layer-4-security.yaml @@ -8,7 +8,7 @@ metadata: spec: project: homelab source: - repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git + repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git targetRevision: main path: k8s/security destination: diff --git a/k8s/argocd/apps/layer-5-applications.yaml b/k8s/argocd/apps/layer-5-applications.yaml index 746a1d3..4c2503c 100644 --- a/k8s/argocd/apps/layer-5-applications.yaml +++ b/k8s/argocd/apps/layer-5-applications.yaml @@ -8,7 +8,7 @@ metadata: spec: project: homelab source: - repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git + repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git targetRevision: main path: k8s/applications destination: diff --git a/k8s/argocd/apps/layer-6-data.yaml b/k8s/argocd/apps/layer-6-data.yaml index aa02ddd..07d278a 100644 --- a/k8s/argocd/apps/layer-6-data.yaml +++ b/k8s/argocd/apps/layer-6-data.yaml @@ -8,7 +8,7 @@ metadata: spec: project: homelab source: - repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git + repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git targetRevision: main path: k8s/data destination: diff --git a/k8s/argocd/apps/phase0-minio.yaml b/k8s/argocd/apps/phase0-minio.yaml index 6871dbd..78d069b 100644 --- a/k8s/argocd/apps/phase0-minio.yaml +++ b/k8s/argocd/apps/phase0-minio.yaml @@ -67,12 +67,12 @@ spec: purge: false environment: - MINIO_IDENTITY_OPENID_CONFIG_URL: https://authentik.riotpiao.homelab.com/application/o/minio/.well-known/openid-configuration + MINIO_IDENTITY_OPENID_CONFIG_URL: https://authentik.riotpiao.com/application/o/minio/.well-known/openid-configuration MINIO_IDENTITY_OPENID_CLIENT_ID: minio MINIO_IDENTITY_OPENID_CLIENT_SECRET: 9d2867fe08c3bf7fedd7e32bbaf4456fce3b0aaf788966d7559e1955947b0219 MINIO_IDENTITY_OPENID_CLAIM_NAME: policy MINIO_IDENTITY_OPENID_SCOPES: openid,profile,email,minio - MINIO_IDENTITY_OPENID_REDIRECT_URI: https://minio.riotpiao.homelab.com/oauth_callback + MINIO_IDENTITY_OPENID_REDIRECT_URI: https://minio.riotpiao.com/oauth_callback MINIO_IDENTITY_OPENID_DISPLAY_NAME: Authentik destination: diff --git a/k8s/argocd/apps/phase1-hookless-0.yaml b/k8s/argocd/apps/phase1-hookless-0.yaml index 2a14b3c..70bb80e 100644 --- a/k8s/argocd/apps/phase1-hookless-0.yaml +++ b/k8s/argocd/apps/phase1-hookless-0.yaml @@ -82,7 +82,7 @@ metadata: spec: project: homelab source: - repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git + repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git targetRevision: main path: k8s/sqs/charts/kafka-cluster helm: @@ -117,7 +117,7 @@ metadata: spec: project: homelab source: - repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git + repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git targetRevision: main path: k8s/sqs/charts/queue-crd helm: @@ -146,7 +146,7 @@ metadata: spec: project: homelab source: - repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git + repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git targetRevision: main path: k8s/sqs/charts/management-service helm: @@ -155,11 +155,11 @@ spec: env: kafkaBrokers: "kmsvc-kafka-bootstrap.sqs.svc.cluster.local:9092" redisAddr: "kmsvc-redis-master.sqs.svc.cluster.local:6379" - authentikIssuerURL: "https://authentik.riotpiao.homelab.com/application/o/kafaka/" + authentikIssuerURL: "https://authentik.riotpiao.com/application/o/kafaka/" authentikAudience: "QI0gPtR99ar8VvhK8Tqox4SDkTKzbNU7lbgwBNSc" ingress: enabled: true - host: kmsvc.riotpiao.homelab.com + host: kmsvc.riotpiao.com clusterIssuer: homelab-ca destination: server: https://kubernetes.default.svc diff --git a/k8s/argocd/apps/phase2-storage-observability-0.yaml b/k8s/argocd/apps/phase2-storage-observability-0.yaml index ffbcd90..8b0b889 100644 --- a/k8s/argocd/apps/phase2-storage-observability-0.yaml +++ b/k8s/argocd/apps/phase2-storage-observability-0.yaml @@ -17,7 +17,7 @@ spec: helm: valueFiles: - k8s/monitoring/prometheus-values.yaml - - repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git + - repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git targetRevision: main path: k8s/hooks/phase2 destination: @@ -47,7 +47,7 @@ spec: helm: valueFiles: - k8s/ddb/cnpg-values.yaml - - repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git + - repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git targetRevision: main path: k8s/hooks/phase2 destination: diff --git a/k8s/argocd/apps/phase2-storage-observability-1.yaml b/k8s/argocd/apps/phase2-storage-observability-1.yaml index a32c260..8253b91 100644 --- a/k8s/argocd/apps/phase2-storage-observability-1.yaml +++ b/k8s/argocd/apps/phase2-storage-observability-1.yaml @@ -95,13 +95,13 @@ metadata: spec: project: homelab sources: - - repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git + - repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git targetRevision: main path: k8s/talos-ci-cd/charts/forgejo-runner helm: valueFiles: - values.yaml - - repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git + - repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git targetRevision: main path: k8s/hooks/phase2 destination: diff --git a/k8s/argocd/apps/phase3-iam-0.yaml b/k8s/argocd/apps/phase3-iam-0.yaml index 59ac356..93fcba8 100644 --- a/k8s/argocd/apps/phase3-iam-0.yaml +++ b/k8s/argocd/apps/phase3-iam-0.yaml @@ -18,7 +18,7 @@ spec: valueFiles: - k8s/talos-iam/authentik-values.yaml - k8s/talos-iam/authentik-secrets.enc.yaml - - repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git + - repoURL: https://forgejo.riotpiao.com/riotpiao.com/homelab.git targetRevision: main path: k8s/hooks/phase3 destination: diff --git a/k8s/argocd/projects/homelab-project.yaml b/k8s/argocd/projects/homelab-project.yaml new file mode 100644 index 0000000..77cc44f --- /dev/null +++ b/k8s/argocd/projects/homelab-project.yaml @@ -0,0 +1,25 @@ +# k8s/argocd/projects/homelab-project.yaml +# AppProject referenced by every Application manifest under k8s/argocd/apps/ +# (project: homelab) — was never committed, so 00-homelab-root.yaml and all +# layer/wave/phase apps fail admission with "application references project +# 'homelab' which does not exist" until this exists. +apiVersion: argoproj.io/v1alpha1 +kind: AppProject +metadata: + name: homelab + namespace: argocd +spec: + description: Homelab GitOps — single-repo, in-cluster destinations only + sourceRepos: + - https://forgejo.riotpiao.com/riotpiao.com/homelab.git + - https://cloudnative-pg.github.io/charts + - https://dl.gitea.com/charts/ + destinations: + - server: https://kubernetes.default.svc + namespace: "*" + clusterResourceWhitelist: + - group: "*" + kind: "*" + namespaceResourceWhitelist: + - group: "*" + kind: "*" diff --git a/k8s/bootstrap/cert-manager/letsencrypt-issuer.yaml b/k8s/bootstrap/cert-manager/letsencrypt-issuer.yaml new file mode 100644 index 0000000..549b233 --- /dev/null +++ b/k8s/bootstrap/cert-manager/letsencrypt-issuer.yaml @@ -0,0 +1,45 @@ +# k8s/bootstrap/cert-manager/letsencrypt-issuer.yaml +# Let's Encrypt ClusterIssuers for *.riotpiao.com, DNS-01 via Cloudflare +# (wildcard certs require DNS-01 — HTTP-01 can't prove ownership of a wildcard name). +# +# Prereq (apply manually, not in git — token is a secret): +# kubectl create secret generic cloudflare-api-token-secret \ +# --namespace cert-manager \ +# --from-literal=api-token= +# Token scope: Zone:DNS:Edit for the riotpiao.com zone. +# +# Start with letsencrypt-staging to validate the solver, then point +# Certificate.issuerRef at letsencrypt-prod once staging issues cleanly. +apiVersion: cert-manager.io/v1 +kind: ClusterIssuer +metadata: + name: letsencrypt-staging +spec: + acme: + server: https://acme-staging-v02.api.letsencrypt.org/directory + email: locartrock@gmail.com + privateKeySecretRef: + name: letsencrypt-staging-account-key + solvers: + - dns01: + cloudflare: + apiTokenSecretRef: + name: cloudflare-api-token-secret + key: api-token +--- +apiVersion: cert-manager.io/v1 +kind: ClusterIssuer +metadata: + name: letsencrypt-prod +spec: + acme: + server: https://acme-v02.api.letsencrypt.org/directory + email: locartrock@gmail.com + privateKeySecretRef: + name: letsencrypt-prod-account-key + solvers: + - dns01: + cloudflare: + apiTokenSecretRef: + name: cloudflare-api-token-secret + key: api-token diff --git a/k8s/bootstrap/coredns/coredns-configmap.yaml b/k8s/bootstrap/coredns/coredns-configmap.yaml index 4d8911a..abeb08c 100644 --- a/k8s/bootstrap/coredns/coredns-configmap.yaml +++ b/k8s/bootstrap/coredns/coredns-configmap.yaml @@ -4,7 +4,7 @@ # Why this is needed: # Grafana v10+ does OIDC auto-discovery by fetching # /.well-known/openid-configuration from Authentik. When Grafana reaches -# Authentik via the external hostname (authentik.riotpiao.homelab.com), the +# Authentik via the external hostname (authentik.riotpiao.com), the # HTTP Host header is preserved and Authentik returns external URLs in the # discovery response. Without this rewrite, the hostname doesn't resolve # inside the cluster and Grafana falls back to the internal service DNS, @@ -30,29 +30,33 @@ data: } prometheus :9153 + # VPN Access: Map api-server.cluster.local to cluster API IP + # Allows secure cluster access via WireGuard tunnel (Shadowrocket/Talos) + rewrite name api-server.cluster.local kubernetes.default.svc.cluster.local + # Forgejo: route through nginx ingress like every other host below. nginx # terminates TLS (wildcard-tls) on :443 and routes both /v2/ (container # registry) and web/git to forgejo-gitea-http:3000. # Do NOT point this at forgejo-gitea-http directly: that service only serves # port 3000, so containerd image pulls (which use https/:443) get # `dial tcp :443: i/o timeout`. SSH stays on its own LB service. - rewrite name forgejo.riotpiao.homelab.com ingress-nginx-controller.ingress-nginx.svc.cluster.local + rewrite name forgejo.riotpiao.com ingress-nginx-controller.ingress-nginx.svc.cluster.local # Rewrite homelab hostnames to the nginx ingress controller so in-cluster pods # hit nginx TLS termination (cert-manager cert) and preserve the Host header. # Routing through nginx — not directly to the backend service — is critical: # direct rewrites to the backend bypass nginx TLS and expose each app's own # self-signed cert, which nothing in the cluster trusts. - rewrite name authentik.riotpiao.homelab.com ingress-nginx-controller.ingress-nginx.svc.cluster.local - rewrite name grafana.riotpiao.homelab.com ingress-nginx-controller.ingress-nginx.svc.cluster.local - rewrite name minio.riotpiao.homelab.com ingress-nginx-controller.ingress-nginx.svc.cluster.local - rewrite name minio-api.riotpiao.homelab.com ingress-nginx-controller.ingress-nginx.svc.cluster.local - rewrite name argocd.riotpiao.homelab.com ingress-nginx-controller.ingress-nginx.svc.cluster.local - rewrite name vault.riotpiao.homelab.com ingress-nginx-controller.ingress-nginx.svc.cluster.local - rewrite name loki.riotpiao.homelab.com ingress-nginx-controller.ingress-nginx.svc.cluster.local - rewrite name prometheus.riotpiao.homelab.com ingress-nginx-controller.ingress-nginx.svc.cluster.local - rewrite name portainer.riotpiao.homelab.com ingress-nginx-controller.ingress-nginx.svc.cluster.local - rewrite name longhorn.riotpiao.homelab.com ingress-nginx-controller.ingress-nginx.svc.cluster.local + rewrite name authentik.riotpiao.com ingress-nginx-controller.ingress-nginx.svc.cluster.local + rewrite name grafana.riotpiao.com ingress-nginx-controller.ingress-nginx.svc.cluster.local + rewrite name minio.riotpiao.com ingress-nginx-controller.ingress-nginx.svc.cluster.local + rewrite name minio-api.riotpiao.com ingress-nginx-controller.ingress-nginx.svc.cluster.local + rewrite name argocd.riotpiao.com ingress-nginx-controller.ingress-nginx.svc.cluster.local + rewrite name vault.riotpiao.com ingress-nginx-controller.ingress-nginx.svc.cluster.local + rewrite name loki.riotpiao.com ingress-nginx-controller.ingress-nginx.svc.cluster.local + rewrite name prometheus.riotpiao.com ingress-nginx-controller.ingress-nginx.svc.cluster.local + rewrite name portainer.riotpiao.com ingress-nginx-controller.ingress-nginx.svc.cluster.local + rewrite name longhorn.riotpiao.com ingress-nginx-controller.ingress-nginx.svc.cluster.local kubernetes cluster.local in-addr.arpa ip6.arpa { pods insecure diff --git a/k8s/bootstrap/ingress/ingress.yaml b/k8s/bootstrap/ingress/ingress.yaml index c081306..fd6a285 100644 --- a/k8s/bootstrap/ingress/ingress.yaml +++ b/k8s/bootstrap/ingress/ingress.yaml @@ -1,10 +1,10 @@ # k8s/ingress/ingress.yaml # Ingress rules for all homelab services. -# TLS is handled centrally: nginx serves the wildcard-tls cert (*.riotpiao.homelab.com) +# TLS is handled centrally: nginx serves the wildcard-tls cert (*.riotpiao.com) # as its default-ssl-certificate. No per-rule tls: blocks or cert-manager annotations # are needed — cert-manager manages one cert, nginx uses it for all hosts. # -# DNS: *.riotpiao.homelab.com must resolve to 10.6.0.1 (WireGuard) or 192.168.1.160 (LAN). +# DNS: *.riotpiao.com must resolve to 10.6.0.1 (WireGuard) or 192.168.1.160 (LAN). # ── Grafana ─────────────────────────────────────────────────────────────────── apiVersion: networking.k8s.io/v1 @@ -17,7 +17,7 @@ metadata: spec: ingressClassName: nginx rules: - - host: grafana.riotpiao.homelab.com + - host: grafana.riotpiao.com http: paths: - path: / @@ -38,7 +38,7 @@ metadata: spec: ingressClassName: nginx rules: - - host: loki.riotpiao.homelab.com + - host: loki.riotpiao.com http: paths: - path: / @@ -62,7 +62,7 @@ metadata: spec: ingressClassName: nginx rules: - - host: authentik.riotpiao.homelab.com + - host: authentik.riotpiao.com http: paths: - path: / @@ -85,7 +85,7 @@ metadata: spec: ingressClassName: nginx rules: - - host: vault.riotpiao.homelab.com + - host: vault.riotpiao.com http: paths: - path: / @@ -113,7 +113,7 @@ metadata: spec: ingressClassName: nginx rules: - - host: minio.riotpiao.homelab.com + - host: minio.riotpiao.com http: paths: - path: / @@ -138,7 +138,7 @@ metadata: spec: ingressClassName: nginx rules: - - host: minio-api.riotpiao.homelab.com + - host: minio-api.riotpiao.com http: paths: - path: / @@ -159,7 +159,7 @@ metadata: spec: ingressClassName: nginx rules: - - host: prometheus.riotpiao.homelab.com + - host: prometheus.riotpiao.com http: paths: - path: / @@ -183,7 +183,7 @@ metadata: spec: ingressClassName: nginx rules: - - host: portainer.riotpiao.homelab.com + - host: portainer.riotpiao.com http: paths: - path: / @@ -210,7 +210,7 @@ metadata: spec: ingressClassName: nginx rules: - - host: forgejo.riotpiao.homelab.com + - host: forgejo.riotpiao.com http: paths: - path: / @@ -238,7 +238,7 @@ metadata: spec: ingressClassName: nginx rules: - - host: argocd.riotpiao.homelab.com + - host: argocd.riotpiao.com http: paths: - path: / @@ -259,7 +259,7 @@ metadata: spec: ingressClassName: nginx rules: - - host: longhorn.riotpiao.homelab.com + - host: longhorn.riotpiao.com http: paths: - path: / @@ -285,7 +285,7 @@ metadata: spec: ingressClassName: nginx rules: - - host: temporal.riotpiao.homelab.com + - host: temporal.riotpiao.com http: paths: - path: / @@ -307,7 +307,7 @@ metadata: spec: ingressClassName: nginx rules: - - host: kmsvc.riotpiao.homelab.com + - host: kmsvc.riotpiao.com http: paths: - path: / diff --git a/k8s/bootstrap/ingress/nginx-values.yaml b/k8s/bootstrap/ingress/nginx-values.yaml index 93cd868..7901322 100644 --- a/k8s/bootstrap/ingress/nginx-values.yaml +++ b/k8s/bootstrap/ingress/nginx-values.yaml @@ -1,16 +1,16 @@ # k8s/ingress/nginx-values.yaml # Nginx Ingress Controller — bare-metal homelab config. # LoadBalancer service with Cilium LB-IPAM assigns fixed IP (192.168.1.160). -# Access services at https://grafana.riotpiao.homelab.com (80/443 via LoadBalancer). +# Access services at https://grafana.riotpiao.com (80/443 via LoadBalancer). controller: kind: DaemonSet - # Single wildcard cert served for every *.riotpiao.homelab.com host. - # Applied by the ingress-nginx presync hook (wildcard-cert.yaml) before nginx starts. - # nginx hot-reloads when cert-manager renews homelab-tls — no restart needed. + # Single wildcard cert served for every *.riotpiao.com host (Let's Encrypt, + # see ../ingress/riotpiao-com-cert.yaml + ../cert-manager/letsencrypt-issuer.yaml). + # nginx hot-reloads when cert-manager renews riotpiao-com-tls — no restart needed. extraArgs: - default-ssl-certificate: "ingress-nginx/homelab-tls" + default-ssl-certificate: "ingress-nginx/riotpiao-com-tls" hostPort: enabled: true @@ -19,7 +19,7 @@ controller: https: 443 # TCP proxy: forward port 2222 on every node → Forgejo SSH service. - # This lets `git clone git@forgejo.riotpiao.homelab.com:repo` work via the + # This lets `git clone git@forgejo.riotpiao.com:repo` work via the # same hostname as HTTPS without a separate LoadBalancer IP for SSH. tcp: 2222: "cicd/forgejo-gitea-ssh:2222" diff --git a/k8s/bootstrap/ingress/riotpiao-com-cert.yaml b/k8s/bootstrap/ingress/riotpiao-com-cert.yaml new file mode 100644 index 0000000..66eb48e --- /dev/null +++ b/k8s/bootstrap/ingress/riotpiao-com-cert.yaml @@ -0,0 +1,25 @@ +# k8s/bootstrap/ingress/riotpiao-com-cert.yaml +# Public wildcard cert for *.riotpiao.com, signed by Let's Encrypt (DNS-01 via +# Cloudflare, see ../cert-manager/letsencrypt-issuer.yaml). Distinct from +# homelab-tls (self-signed homelab-ca, internal *.riotpiao.com) — +# reference riotpiao-com-tls explicitly on ingresses that expose riotpiao.com +# hosts to the internet; it is not nginx's default-ssl-certificate. +# +# issuerRef starts on letsencrypt-staging. Switch to letsencrypt-prod once the +# staging cert issues cleanly, then delete this Certificate's Secret to force +# a re-issue against prod (staging certs aren't browser-trusted). +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: riotpiao-com-tls + namespace: ingress-nginx +spec: + secretName: riotpiao-com-tls + dnsNames: + - "*.riotpiao.com" + - "riotpiao.com" + issuerRef: + name: letsencrypt-staging + kind: ClusterIssuer + duration: 2160h # 90 days (LE max) + renewBefore: 720h # renew 30 days before expiry diff --git a/k8s/bootstrap/ingress/wildcard-cert.yaml b/k8s/bootstrap/ingress/wildcard-cert.yaml deleted file mode 100644 index b68ca74..0000000 --- a/k8s/bootstrap/ingress/wildcard-cert.yaml +++ /dev/null @@ -1,22 +0,0 @@ -# k8s/ingress/wildcard-cert.yaml -# Single wildcard TLS certificate for all *.riotpiao.homelab.com services. -# Lives in the ingress-nginx namespace and is set as nginx's default-ssl-certificate, -# so every ingress host gets it automatically — no per-service TLS blocks needed. -# -# Renewal: cert-manager auto-renews 30 days before expiry (renewBefore: 720h). -# nginx detects the secret update via its K8s watch and hot-reloads — no pod restart. -apiVersion: cert-manager.io/v1 -kind: Certificate -metadata: - name: homelab-tls - namespace: ingress-nginx -spec: - secretName: homelab-tls - dnsNames: - - "*.riotpiao.homelab.com" - - "riotpiao.homelab.com" - issuerRef: - name: homelab-ca - kind: ClusterIssuer - duration: 8760h # 1 year - renewBefore: 720h # renew 30 days before expiry diff --git a/k8s/data/forgejo-database.yaml b/k8s/data/forgejo-database.yaml new file mode 100644 index 0000000..1814887 --- /dev/null +++ b/k8s/data/forgejo-database.yaml @@ -0,0 +1,10 @@ +apiVersion: postgresql.cnpg.io/v1 +kind: Database +metadata: + name: forgejo + namespace: ddb +spec: + name: forgejo + owner: app + cluster: + name: ddb-cluster diff --git a/k8s/data/kustomization.yaml b/k8s/data/kustomization.yaml index 397026f..4defab2 100644 --- a/k8s/data/kustomization.yaml +++ b/k8s/data/kustomization.yaml @@ -13,3 +13,4 @@ resources: - ddb-cluster.yaml - schemas.yaml - db-init-job.yaml + - forgejo-database.yaml diff --git a/k8s/infrastructure/minio/minio-tenant.yaml b/k8s/infrastructure/minio/minio-tenant.yaml index bf74ef8..2b28784 100644 --- a/k8s/infrastructure/minio/minio-tenant.yaml +++ b/k8s/infrastructure/minio/minio-tenant.yaml @@ -111,7 +111,7 @@ spec: # Environment variables — OIDC config env: - name: MINIO_IDENTITY_OPENID_CONFIG_URL - value: "https://authentik.riotpiao.homelab.com/application/o/minio/.well-known/openid-configuration" + value: "https://authentik.riotpiao.com/application/o/minio/.well-known/openid-configuration" - name: MINIO_IDENTITY_OPENID_CLIENT_ID value: "minio" - name: MINIO_IDENTITY_OPENID_CLIENT_SECRET @@ -124,7 +124,7 @@ spec: - name: MINIO_IDENTITY_OPENID_SCOPES value: "openid,profile,email,minio" - name: MINIO_IDENTITY_OPENID_REDIRECT_URI - value: "https://minio.riotpiao.homelab.com/oauth_callback" + value: "https://minio.riotpiao.com/oauth_callback" - name: MINIO_IDENTITY_OPENID_DISPLAY_NAME value: "Authentik" diff --git a/k8s/infrastructure/minio/minio-values.yaml b/k8s/infrastructure/minio/minio-values.yaml index 3730fed..b61f34d 100644 --- a/k8s/infrastructure/minio/minio-values.yaml +++ b/k8s/infrastructure/minio/minio-values.yaml @@ -42,11 +42,11 @@ envFrom: name: minio-oidc environment: - MINIO_IDENTITY_OPENID_CONFIG_URL: "https://authentik.riotpiao.homelab.com/application/o/minio/.well-known/openid-configuration" + MINIO_IDENTITY_OPENID_CONFIG_URL: "https://authentik.riotpiao.com/application/o/minio/.well-known/openid-configuration" MINIO_IDENTITY_OPENID_CLIENT_ID: "minio" MINIO_IDENTITY_OPENID_CLAIM_NAME: "policy" MINIO_IDENTITY_OPENID_SCOPES: "openid,profile,email,minio" - MINIO_IDENTITY_OPENID_REDIRECT_URI: "https://minio.riotpiao.homelab.com/oauth_callback" + MINIO_IDENTITY_OPENID_REDIRECT_URI: "https://minio.riotpiao.com/oauth_callback" MINIO_IDENTITY_OPENID_DISPLAY_NAME: "Authentik" podAnnotations: diff --git a/k8s/platform/logging/grafana-values.yaml b/k8s/platform/logging/grafana-values.yaml index 919d61c..68a494b 100644 --- a/k8s/platform/logging/grafana-values.yaml +++ b/k8s/platform/logging/grafana-values.yaml @@ -39,7 +39,7 @@ persistence: # ── Grafana config ──────────────────────────────────────────────────────────── grafana.ini: server: - root_url: https://grafana.riotpiao.homelab.com + root_url: https://grafana.riotpiao.com # No anonymous read access — every user must log in via Authentik SSO. auth.anonymous: @@ -70,9 +70,9 @@ grafana.ini: allow_sign_up: true client_id: grafana scopes: openid email profile - auth_url: https://authentik.riotpiao.homelab.com/application/o/authorize/ - token_url: https://authentik.riotpiao.homelab.com/application/o/token/ - api_url: https://authentik.riotpiao.homelab.com/application/o/userinfo/ + auth_url: https://authentik.riotpiao.com/application/o/authorize/ + token_url: https://authentik.riotpiao.com/application/o/token/ + api_url: https://authentik.riotpiao.com/application/o/userinfo/ role_attribute_path: "contains(groups[*], 'grafana-admins') && 'Admin' || 'Viewer'" use_pkce: false use_refresh_token: false @@ -154,7 +154,7 @@ tolerations: operator: Exists effect: NoSchedule -# ClusterIP only — access via ingress (grafana.riotpiao.homelab.com) or port-forward. +# ClusterIP only — access via ingress (grafana.riotpiao.com) or port-forward. service: type: ClusterIP port: 80 diff --git a/k8s/platform/monitoring/blackbox-exporter-values.yaml b/k8s/platform/monitoring/blackbox-exporter-values.yaml index 0f7ae29..c8a52a5 100644 --- a/k8s/platform/monitoring/blackbox-exporter-values.yaml +++ b/k8s/platform/monitoring/blackbox-exporter-values.yaml @@ -40,27 +40,27 @@ serviceMonitor: module: http_2xx targets: - name: grafana - url: https://grafana.riotpiao.homelab.com/ + url: https://grafana.riotpiao.com/ - name: loki - url: https://loki.riotpiao.homelab.com/ready + url: https://loki.riotpiao.com/ready - name: authentik - url: https://authentik.riotpiao.homelab.com/-/health/ready/ + url: https://authentik.riotpiao.com/-/health/ready/ - name: vault - url: https://vault.riotpiao.homelab.com/v1/sys/health + url: https://vault.riotpiao.com/v1/sys/health - name: minio-console - url: https://minio.riotpiao.homelab.com/ + url: https://minio.riotpiao.com/ - name: minio-api - url: https://minio-api.riotpiao.homelab.com/minio/health/live + url: https://minio-api.riotpiao.com/minio/health/live - name: prometheus - url: https://prometheus.riotpiao.homelab.com/-/healthy + url: https://prometheus.riotpiao.com/-/healthy - name: portainer - url: https://portainer.riotpiao.homelab.com/ + url: https://portainer.riotpiao.com/ - name: forgejo - url: https://forgejo.riotpiao.homelab.com/api/healthz + url: https://forgejo.riotpiao.com/api/healthz - name: argocd - url: https://argocd.riotpiao.homelab.com/healthz + url: https://argocd.riotpiao.com/healthz - name: longhorn - url: https://longhorn.riotpiao.homelab.com/ + url: https://longhorn.riotpiao.com/ prometheusRule: enabled: true diff --git a/k8s/security/ci-cd/argocd-values.yaml b/k8s/security/ci-cd/argocd-values.yaml index b0782e4..95f5046 100644 --- a/k8s/security/ci-cd/argocd-values.yaml +++ b/k8s/security/ci-cd/argocd-values.yaml @@ -3,7 +3,7 @@ # Deployed via helmfile (name=argocd) so it sits alongside Authentik, MinIO, etc. # # UI is exposed via the cluster Ingress (k8s/ingress/ingress.yaml, -# argocd.riotpiao.homelab.com) over the WireGuard/LAN-only nginx ingress — +# argocd.riotpiao.com) over the WireGuard/LAN-only nginx ingress — # never as a LoadBalancer, since argocd-server holds cluster-admin # credentials and that Ingress isn't reachable from the WAN. # @@ -12,7 +12,7 @@ # CA trust for Forgejo repo clones injected into argocd-tls-certs-cm by postsync hook. global: - domain: argocd.riotpiao.homelab.com + domain: argocd.riotpiao.com configs: params: @@ -23,10 +23,10 @@ configs: # Authentik (provision_oidc.py argocd_url) exactly — ArgoCD builds its # OIDC redirect_uri as "{url}/auth/callback", so any mismatch here is # what Authentik's "Invalid redirect URL" error means. - url: "https://argocd.riotpiao.homelab.com" + url: "https://argocd.riotpiao.com" oidc.config: | name: Authentik - issuer: https://authentik.riotpiao.homelab.com/application/o/argocd/ + issuer: https://authentik.riotpiao.com/application/o/argocd/ clientID: $oidc-secret:client-id clientSecret: $oidc-secret:client-secret requestedScopes: [openid, profile, email, groups] diff --git a/k8s/security/ci-cd/charts/forgejo-runner/values.yaml b/k8s/security/ci-cd/charts/forgejo-runner/values.yaml index 964a074..ad57e2f 100644 --- a/k8s/security/ci-cd/charts/forgejo-runner/values.yaml +++ b/k8s/security/ci-cd/charts/forgejo-runner/values.yaml @@ -4,7 +4,7 @@ runner: tag: "6" # pin exact release before apply name: talos-runner labels: "docker:docker://node:22-bookworm" - forgejoUrl: https://forgejo.riotpiao.homelab.com + forgejoUrl: https://forgejo.riotpiao.com # tokenSecret: name of the K8s Secret that holds the runner registration token # created automatically by the helmfile presync hook (see helmfile.yaml.gotmpl) tokenSecret: runner-token diff --git a/k8s/security/ci-cd/deploy-scaffold/api/deployment.yaml b/k8s/security/ci-cd/deploy-scaffold/api/deployment.yaml index a9ac753..158b8e5 100644 --- a/k8s/security/ci-cd/deploy-scaffold/api/deployment.yaml +++ b/k8s/security/ci-cd/deploy-scaffold/api/deployment.yaml @@ -16,7 +16,7 @@ spec: containers: - name: api # CI bumps this tag on every push to main (ci.yml step "bump deploy repo") - image: forgejo.riotpiao.homelab.com/rock/api:latest + image: forgejo.riotpiao.com/rock/api:latest ports: - containerPort: 8080 resources: diff --git a/k8s/security/ci-cd/deploy-scaffold/apps/api.yaml b/k8s/security/ci-cd/deploy-scaffold/apps/api.yaml index a9066cc..5a5534e 100644 --- a/k8s/security/ci-cd/deploy-scaffold/apps/api.yaml +++ b/k8s/security/ci-cd/deploy-scaffold/apps/api.yaml @@ -8,7 +8,7 @@ metadata: spec: project: default source: - repoURL: https://forgejo.forge.riotpiao.homelab.com/rock/deploy.git + repoURL: https://forgejo.forge.riotpiao.com/rock/deploy.git targetRevision: main path: api destination: diff --git a/k8s/security/ci-cd/deploy-scaffold/apps/argocd.yaml b/k8s/security/ci-cd/deploy-scaffold/apps/argocd.yaml index f53013d..e376d90 100644 --- a/k8s/security/ci-cd/deploy-scaffold/apps/argocd.yaml +++ b/k8s/security/ci-cd/deploy-scaffold/apps/argocd.yaml @@ -8,7 +8,7 @@ metadata: spec: project: default source: - repoURL: https://forgejo.forge.riotpiao.homelab.com/rock/deploy.git + repoURL: https://forgejo.forge.riotpiao.com/rock/deploy.git targetRevision: main path: argocd destination: diff --git a/k8s/security/ci-cd/deploy-scaffold/apps/forge.yaml b/k8s/security/ci-cd/deploy-scaffold/apps/forge.yaml index e6641c7..be10f48 100644 --- a/k8s/security/ci-cd/deploy-scaffold/apps/forge.yaml +++ b/k8s/security/ci-cd/deploy-scaffold/apps/forge.yaml @@ -8,7 +8,7 @@ metadata: spec: project: default source: - repoURL: https://forgejo.forge.riotpiao.homelab.com/rock/deploy.git + repoURL: https://forgejo.forge.riotpiao.com/rock/deploy.git targetRevision: main path: forge destination: diff --git a/k8s/security/ci-cd/example-workflows/ci.yml b/k8s/security/ci-cd/example-workflows/ci.yml index 60de495..b40feeb 100644 --- a/k8s/security/ci-cd/example-workflows/ci.yml +++ b/k8s/security/ci-cd/example-workflows/ci.yml @@ -37,7 +37,7 @@ jobs: # ── 2. Build + push OCI image ─────────────────────────────────────────── - name: build and push image env: - REGISTRY: forgejo.forge.riotpiao.homelab.com + REGISTRY: forgejo.forge.riotpiao.com OWNER: rock run: | REPO_NAME=${{ github.event.repository.name }} @@ -60,7 +60,7 @@ jobs: # Argo CD notices the commit and rolls out the new image. - name: bump deploy repo env: - REGISTRY: forgejo.forge.riotpiao.homelab.com + REGISTRY: forgejo.forge.riotpiao.com OWNER: rock run: | git clone \ @@ -75,7 +75,7 @@ jobs: git -C /tmp/deploy \ -c user.name="ci-bot" \ - -c user.email="ci-bot@forgejo.forge.riotpiao.homelab.com" \ + -c user.email="ci-bot@forgejo.forge.riotpiao.com" \ commit -am "${REPO_NAME}: deploy ${TAG}" git -C /tmp/deploy push diff --git a/k8s/security/ci-cd/forgejo-redis.yaml b/k8s/security/ci-cd/forgejo-redis.yaml new file mode 100644 index 0000000..8ca2342 --- /dev/null +++ b/k8s/security/ci-cd/forgejo-redis.yaml @@ -0,0 +1,39 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: forgejo-redis + namespace: cicd +spec: + replicas: 1 + selector: + matchLabels: + app: forgejo-redis + template: + metadata: + labels: + app: forgejo-redis + spec: + containers: + - name: redis + image: redis:7-alpine + ports: + - containerPort: 6379 + resources: + requests: + cpu: 10m + memory: 32Mi + limits: + cpu: 100m + memory: 128Mi +--- +apiVersion: v1 +kind: Service +metadata: + name: forgejo-redis + namespace: cicd +spec: + selector: + app: forgejo-redis + ports: + - port: 6379 + targetPort: 6379 diff --git a/k8s/security/ci-cd/forgejo-values.yaml b/k8s/security/ci-cd/forgejo-values.yaml index b3ca058..97f59a8 100644 --- a/k8s/security/ci-cd/forgejo-values.yaml +++ b/k8s/security/ci-cd/forgejo-values.yaml @@ -1,7 +1,10 @@ -# k8s/talos-ci-cd/forgejo-values.yaml -# Forgejo deployed via the gitea-charts/gitea Helm chart with image override. -# Admin password injected via helmfile --set (FORGEJO_ADMIN_PASSWORD in .env). -# Runner is managed by a separate helmfile release (charts/forgejo-runner/). +# k8s/security/ci-cd/forgejo-values.yaml +# Forgejo deployed via the gitea-charts/gitea Helm chart with image override, +# as an ArgoCD Application with an inline Helm source (k8s/argocd/apps/forgejo.yaml). +# Admin password set via --set at install time (FORGEJO_ADMIN_PASSWORD in .env). +# DB: CNPG (k8s/data/ddb-cluster.yaml + forgejo-database.yaml), not SQLite. +# Cache/session/queue: dedicated Redis (forgejo-redis.yaml), not in-memory — +# required once replicaCount > 1, since in-memory state isn't shared across pods. # # Chart docs: https://gitea.com/gitea/helm-chart @@ -21,16 +24,18 @@ gitea: config: server: PROTOCOL: http # nginx ingress handles TLS; pod serves plain HTTP - DOMAIN: forgejo.riotpiao.homelab.com - ROOT_URL: https://forgejo.riotpiao.homelab.com/ + DOMAIN: forgejo.riotpiao.com + ROOT_URL: https://forgejo.riotpiao.com/ HTTP_PORT: 3000 START_SSH_SERVER: true - SSH_DOMAIN: forgejo.riotpiao.homelab.com + SSH_DOMAIN: forgejo.riotpiao.com SSH_PORT: 2222 SSH_LISTEN_PORT: 2222 database: - DB_TYPE: sqlite3 - PATH: /data/forgejo.db + DB_TYPE: postgres + HOST: ddb-cluster-rw.ddb.svc:5432 + NAME: forgejo + USER: app repository: ROOT: /data/git actions: @@ -44,37 +49,49 @@ gitea: oauth2: ENABLED: true PROVIDER: openidconnect - OPENID_CONNECT_DISCOVERY_URL: https://authentik.riotpiao.homelab.com/application/o/forgejo/.well-known/openid-configuration + OPENID_CONNECT_DISCOVERY_URL: https://authentik.riotpiao.com/application/o/forgejo/.well-known/openid-configuration CLIENT_ID: forgejo - AUTO_DISCOVER_URL: https://authentik.riotpiao.homelab.com/application/o/forgejo/.well-known/openid-configuration + AUTO_DISCOVER_URL: https://authentik.riotpiao.com/application/o/forgejo/.well-known/openid-configuration cache: - ADAPTER: memory # no Redis — single-replica SQLite setup + ADAPTER: redis + HOST: redis://forgejo-redis.cicd.svc:6379/0 session: - PROVIDER: memory + PROVIDER: redis + PROVIDER_CONFIG: redis://forgejo-redis.cicd.svc:6379/1 queue: - TYPE: channel # in-memory queue; no file lock, no LevelDB contention on rollout + TYPE: redis + CONN_STR: redis://forgejo-redis.cicd.svc:6379/2 metrics: enabled: true serviceMonitor: enabled: true # kube-prometheus-stack discovers ServiceMonitors cluster-wide -# ── Persistence (Longhorn RWO — SQLite lives here) ──────────────────────────── +# ── Persistence (Longhorn RWX — git repo data shared across replicas) ──────── persistence: enabled: true storageClass: longhorn size: 20Gi accessModes: - - ReadWriteOnce + - ReadWriteMany + +# ── Replicas ────────────────────────────────────────────────────────────────── +# Postgres (CNPG) + Redis (session/cache/queue) + RWX storage means replicas +# no longer need to serialize on a single pod like the old SQLite setup did. +replicaCount: 2 # ── Deployment strategy ──────────────────────────────────────────────────────── -# RWO PVC + SQLite: old pod must terminate before new one mounts the volume. deployment: strategy: - type: Recreate + type: RollingUpdate env: - name: SSL_CERT_DIR value: /homelab-ca + - name: GITEA__database__PASSWD + valueFrom: + secretKeyRef: + name: ddb-cluster-app + key: password # ── Cert / CA auto-reload ───────────────────────────────────────────────────── # nginx serves the wildcard-tls cert — Forgejo itself never reads a TLS secret. diff --git a/k8s/security/ci-cd/kustomization.yaml b/k8s/security/ci-cd/kustomization.yaml index f853f3d..e8ed7b0 100644 --- a/k8s/security/ci-cd/kustomization.yaml +++ b/k8s/security/ci-cd/kustomization.yaml @@ -1,5 +1,9 @@ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization namespace: ci-cd -resources: [] -# Helm charts (forgejo-runner) deployed via ArgoCD Helm source +resources: + - forgejo-redis.yaml +# Helm charts (forgejo, forgejo-runner) deployed via standalone ArgoCD +# Applications with Helm sources (k8s/argocd/apps/forgejo.yaml) — not through +# this kustomization, since layer-4-security syncs from Forgejo's own repo +# (chicken-egg: Forgejo can't be the source of truth for deploying itself). diff --git a/k8s/security/ci-cd/talos-cli.sh b/k8s/security/ci-cd/talos-cli.sh index 0bff8d7..351973b 100755 --- a/k8s/security/ci-cd/talos-cli.sh +++ b/k8s/security/ci-cd/talos-cli.sh @@ -1,7 +1,7 @@ # 0. Source your env (Authentik bootstrap token + Vault addr) set -a && source ~/.authentik/.env && set +a -VAULT_ADDR="http://vault.riotpiao.homelab.com" -AUTHENTIK_URL="http://authentik.riotpiao.homelab.com" +VAULT_ADDR="http://vault.riotpiao.com" +AUTHENTIK_URL="http://authentik.riotpiao.com" # 1. Fetch the real client_id + client_secret from Authentik PROVIDER_PK=$(curl -s \ diff --git a/k8s/security/iam/OAUTH_APP_SETUP.md b/k8s/security/iam/OAUTH_APP_SETUP.md index edabc92..d86700c 100644 --- a/k8s/security/iam/OAUTH_APP_SETUP.md +++ b/k8s/security/iam/OAUTH_APP_SETUP.md @@ -78,7 +78,7 @@ cd /Users/rockliang/workplace/homelab python3 k8s/talos-iam/register_oauth_app.py \ --service-name my-app \ --namespace my-namespace \ - --redirect-uri "https://my-app.riotpiao.homelab.com/oauth2/callback" \ + --redirect-uri "https://my-app.riotpiao.com/oauth2/callback" \ --service-name-in-vault "MY_SERVICE" \ --vault-jwt-policy "shell-secrets" ``` @@ -127,7 +127,7 @@ kubectl port-forward -n iam svc/authentik-server 7000:80 & - **Name:** `yourservice` - **Client ID:** `yourservice` (or custom) - **Client Secret:** (paste from `$CLIENT_SECRET` above) - - **Redirect URIs:** `https://your-app.riotpiao.homelab.com/oauth2/callback` (or your app's callback URL) + - **Redirect URIs:** `https://your-app.riotpiao.com/oauth2/callback` (or your app's callback URL) - **Sub Mode:** `Hashed User ID` - **Include claims in ID Token:** ✓ Enabled - **Grant Types:** `Authorization Code`, `Refresh Token` @@ -143,7 +143,7 @@ kubectl port-forward -n iam svc/authentik-server 7000:80 & - **Name:** `Your App Display Name` - **Slug:** `yourservice` (must match provider slug) - **Provider:** (select the provider created above) - - **Meta Launch URL:** `https://your-app.riotpiao.homelab.com` (optional, for app launcher) + - **Meta Launch URL:** `https://your-app.riotpiao.com` (optional, for app launcher) 3. **Save** @@ -160,7 +160,7 @@ OIDC_CLIENT_ID=yourservice OIDC_CLIENT_SECRET=$CLIENT_SECRET # Redirect URI (must match what you configured in step 2) -OIDC_REDIRECT_URI=https://your-app.riotpiao.homelab.com/oauth2/callback +OIDC_REDIRECT_URI=https://your-app.riotpiao.com/oauth2/callback # Optionally, token validation endpoint OIDC_TOKEN_URL=http://authentik-server.iam.svc.cluster.local/application/o/yourservice/token/ @@ -179,7 +179,7 @@ talos put cluster/YOURSERVICE_OIDC_CLIENT_SECRET YOURSERVICE_OIDC_CLIENT_SECRET= talos put cluster/yourservice-oidc \ client_id=yourservice \ issuer_url="http://authentik-server.iam.svc.cluster.local/application/o/yourservice/" \ - callback_uri="https://your-app.riotpiao.homelab.com/oauth2/callback" + callback_uri="https://your-app.riotpiao.com/oauth2/callback" ``` ### Step 5: Mount Credentials in Your Service @@ -378,7 +378,7 @@ kubectl get secret yourservice-oidc -n your-namespace -o jsonpath='{.data}' | ba vault read auth/jwt/role/yourservice # 5. Test OAuth login (requires port-forward to your app) -# Open http://your-app.riotpiao.homelab.com/login +# Open http://your-app.riotpiao.com/login # Should redirect to Authentik, then back to your app # 6. Test JWT auth to Vault (if applicable) diff --git a/k8s/security/iam/README.md b/k8s/security/iam/README.md index 8e9b8b3..09c76e2 100644 --- a/k8s/security/iam/README.md +++ b/k8s/security/iam/README.md @@ -227,7 +227,7 @@ The homelab provides **automated OAuth registration** for new services via `regi python3 k8s/talos-iam/register_oauth_app.py \ --service-name my-service \ --namespace my-ns \ - --redirect-uri "https://my-service.riotpiao.homelab.com/oauth2/callback" \ + --redirect-uri "https://my-service.riotpiao.com/oauth2/callback" \ --service-name-in-vault MY_SERVICE \ --vault-jwt-policy shell-secrets \ --add-group my-service-admins @@ -254,7 +254,7 @@ export DASHBOARD_OIDC_CLIENT_SECRET python3 k8s/talos-iam/register_oauth_app.py \ --service-name dashboard-service \ --namespace apps \ - --redirect-uri "https://dashboard.riotpiao.homelab.com/oauth2/callback" \ + --redirect-uri "https://dashboard.riotpiao.com/oauth2/callback" \ --service-name-in-vault DASHBOARD \ --vault-jwt-policy shell-secrets \ --add-group dashboard-admins \ @@ -282,7 +282,7 @@ kubectl get secret my-service-oidc -n my-ns -o yaml vault read auth/jwt/role/my-service # Test OAuth login -# Browser: https://my-service.riotpiao.homelab.com/login +# Browser: https://my-service.riotpiao.com/login # Should redirect to Authentik → back to service with session ``` diff --git a/k8s/security/iam/authentik-values.yaml b/k8s/security/iam/authentik-values.yaml index 6f06f5e..d70a30b 100644 --- a/k8s/security/iam/authentik-values.yaml +++ b/k8s/security/iam/authentik-values.yaml @@ -17,7 +17,7 @@ authentik: # Must match what the browser sees — if it returns an internal svc URL, # the browser's redirect after login will fail (can't reach svc DNS externally). # HTTP (not HTTPS) because the Authentik ingress has no TLS cert configured. - host: "https://authentik.riotpiao.homelab.com" + host: "https://authentik.riotpiao.com" error_reporting: enabled: false # do not phone home to Sentry @@ -103,7 +103,7 @@ _caEnv: &caEnv # ── Authentik server (UI + API) ─────────────────────────────────────────────── # Handles all browser traffic: login flows, admin UI, OAuth2 authorize/token endpoints. # NodePort 32172 is a fallback for direct node access during troubleshooting; -# normal access is via nginx ingress (authentik.riotpiao.homelab.com → svc:80). +# normal access is via nginx ingress (authentik.riotpiao.com → svc:80). # Recreate: single replica + RWO-adjacent state — avoids split-brain on redeploy. server: replicas: 1 @@ -221,5 +221,5 @@ redis: operator: Exists architecture: standalone -# Ingress disabled — rule lives in k8s/ingress/ingress.yaml (authentik.riotpiao.homelab.com). +# Ingress disabled — rule lives in k8s/ingress/ingress.yaml (authentik.riotpiao.com). # For direct access during bootstrap: kubectl -n iam port-forward svc/authentik-server 7000:80 diff --git a/k8s/security/iam/example_register_dashboard.py b/k8s/security/iam/example_register_dashboard.py index ca27899..54c13e5 100755 --- a/k8s/security/iam/example_register_dashboard.py +++ b/k8s/security/iam/example_register_dashboard.py @@ -23,7 +23,7 @@ To use this example: python3 register_oauth_app.py \\ --service-name dashboard-service \\ --namespace apps \\ - --redirect-uri "https://dashboard.riotpiao.homelab.com/oauth2/callback" \\ + --redirect-uri "https://dashboard.riotpiao.com/oauth2/callback" \\ --service-name-in-vault DASHBOARD \\ --vault-jwt-policy shell-secrets \\ --add-group dashboard-admins \\ @@ -34,7 +34,7 @@ To use this example: http://localhost:7000/api/v3/core/applications/?slug=dashboard-service | jq . # 5. Test OAuth callback (requires app running) - # Browser: http://dashboard.riotpiao.homelab.com/login + # Browser: http://dashboard.riotpiao.com/login # Should redirect to Authentik → back to dashboard with session """ @@ -68,7 +68,7 @@ def example_dashboard_service(): "register_oauth_app.py", "--service-name", "dashboard-service", "--namespace", "apps", - "--redirect-uri", "https://dashboard.riotpiao.homelab.com/oauth2/callback", + "--redirect-uri", "https://dashboard.riotpiao.com/oauth2/callback", "--service-name-in-vault", "DASHBOARD", "--vault-jwt-policy", "shell-secrets", "--add-group", "dashboard-admins", @@ -122,7 +122,7 @@ def verify_example(): print() print("✅ Test OAuth redirect (requires app running):") - print(" curl -L https://dashboard.riotpiao.homelab.com/login") + print(" curl -L https://dashboard.riotpiao.com/login") print(" # Should redirect to Authentik, then back to dashboard") print() diff --git a/k8s/security/iam/register_oauth_app.py b/k8s/security/iam/register_oauth_app.py index 8fde782..affd9ff 100755 --- a/k8s/security/iam/register_oauth_app.py +++ b/k8s/security/iam/register_oauth_app.py @@ -10,7 +10,7 @@ Usage: python3 register_oauth_app.py \\ --service-name my-service \\ --namespace my-ns \\ - --redirect-uri "https://my-service.riotpiao.homelab.com/oauth2/callback" \\ + --redirect-uri "https://my-service.riotpiao.com/oauth2/callback" \\ [--service-name-in-vault MY_SERVICE] \\ [--vault-jwt-policy shell-secrets] @@ -28,13 +28,13 @@ Examples: python3 register_oauth_app.py \\ --service-name myapp \\ --namespace apps \\ - --redirect-uri "https://myapp.riotpiao.homelab.com/callback" + --redirect-uri "https://myapp.riotpiao.com/callback" # Advanced: full service with Vault JWT auth python3 register_oauth_app.py \\ --service-name myservice \\ --namespace my-namespace \\ - --redirect-uri "https://myservice.riotpiao.homelab.com/oauth2/callback" \\ + --redirect-uri "https://myservice.riotpiao.com/oauth2/callback" \\ --service-name-in-vault MYSERVICE \\ --vault-jwt-policy shell-secrets \\ --add-group myservice-admins \\ @@ -328,7 +328,7 @@ def main() -> None: parser.add_argument( "--redirect-uri", required=True, - help="OAuth2 redirect URI (e.g., https://myapp.riotpiao.homelab.com/callback)" + help="OAuth2 redirect URI (e.g., https://myapp.riotpiao.com/callback)" ) parser.add_argument( "--service-name-in-vault", @@ -420,7 +420,7 @@ def main() -> None: display_name=service_name.replace("-", " ").title(), slug=service_name, provider_pk=provider_pk, - launch_url=f"https://{service_name}.riotpiao.homelab.com" + launch_url=f"https://{service_name}.riotpiao.com" ) print() diff --git a/k8s/security/iam/setup_vault.sh b/k8s/security/iam/setup_vault.sh index e3a318b..acd8a7b 100755 --- a/k8s/security/iam/setup_vault.sh +++ b/k8s/security/iam/setup_vault.sh @@ -238,7 +238,7 @@ _vault_browser_payload=$(jq -n \ invalidation_flow: $inval_flow, signing_key: $signing_key, redirect_uris: [ - {"matching_mode": "strict", "url": "http://vault.riotpiao.homelab.com/ui/vault/auth/oidc/oidc/callback"}, + {"matching_mode": "strict", "url": "http://vault.riotpiao.com/ui/vault/auth/oidc/oidc/callback"}, {"matching_mode": "strict", "url": "http://localhost:8250/oidc/callback"} ] }') @@ -465,7 +465,7 @@ step oidc_enable "Enabling OIDC auth method for browser login..." vault auth enable oidc 2>/dev/null || echo "OIDC auth already enabled." vault write auth/oidc/config \ - oidc_discovery_url="http://authentik.riotpiao.homelab.com/application/o/vault-browser/" \ + oidc_discovery_url="http://authentik.riotpiao.com/application/o/vault-browser/" \ oidc_client_id="vault-browser" \ oidc_client_secret="${VAULT_BROWSER_CLIENT_SECRET}" \ default_role="homelab" @@ -475,7 +475,7 @@ vault write auth/oidc/config \ vault write auth/oidc/role/homelab \ role_type=oidc \ bound_audiences="vault-browser" \ - allowed_redirect_uris="http://vault.riotpiao.homelab.com/ui/vault/auth/oidc/oidc/callback,http://localhost:8250/oidc/callback" \ + allowed_redirect_uris="http://vault.riotpiao.com/ui/vault/auth/oidc/oidc/callback,http://localhost:8250/oidc/callback" \ user_claim="sub" \ oidc_scopes="openid,profile,email" \ token_policies="shell-secrets,cluster-admin" \ @@ -483,8 +483,8 @@ vault write auth/oidc/role/homelab \ token_max_ttl=12h echo "OIDC auth configured." -echo " Browser login: http://vault.riotpiao.homelab.com → sign in with Authentik" -echo " CLI login: VAULT_ADDR=http://vault.riotpiao.homelab.com vault login -method=oidc" +echo " Browser login: http://vault.riotpiao.com → sign in with Authentik" +echo " CLI login: VAULT_ADDR=http://vault.riotpiao.com vault login -method=oidc" # ── 14. Seed initial secrets ────────────────────────────────────────────────── step seed_secrets "Seeding initial secrets from environment (accessible after OIDC login)..." @@ -519,8 +519,8 @@ echo "==> Vault bootstrap complete." echo "" echo "Next steps:" echo " 1. Move ${UNSEAL_KEYS_FILE} OFFLINE (USB / password manager)." -echo " 2. Browser login: open http://vault.riotpiao.homelab.com → choose OIDC → sign in with Authentik" -echo " 3. CLI login: export VAULT_ADDR=http://vault.riotpiao.homelab.com" +echo " 2. Browser login: open http://vault.riotpiao.com → choose OIDC → sign in with Authentik" +echo " 3. CLI login: export VAULT_ADDR=http://vault.riotpiao.com" echo " vault login -method=oidc" echo " 4. Read MinIO credentials from Vault after login:" echo " vault kv get secret/cluster/minio" diff --git a/k8s/security/iam/vault-values.yaml b/k8s/security/iam/vault-values.yaml index ba6e2b1..dae8013 100644 --- a/k8s/security/iam/vault-values.yaml +++ b/k8s/security/iam/vault-values.yaml @@ -9,7 +9,7 @@ # once after first install to initialize and store the keys). # ── Global ──────────────────────────────────────────────────────────────────── -# tlsDisable: true — TLS terminated at the nginx ingress (vault.riotpiao.homelab.com) +# tlsDisable: true — TLS terminated at the nginx ingress (vault.riotpiao.com) # or at port-forward. In-cluster traffic to Vault is plain HTTP; this is acceptable # because all clients are on the pod network (not crossing node boundaries). global: @@ -137,7 +137,7 @@ server: # ── Service ───────────────────────────────────────────────────────────────── # NodePort 32171 — fallback for direct node access during bootstrap before - # the ingress is up. Normal access is via nginx ingress (vault.riotpiao.homelab.com). + # the ingress is up. Normal access is via nginx ingress (vault.riotpiao.com). service: type: NodePort port: 8200 @@ -155,7 +155,7 @@ server: # ── UI ──────────────────────────────────────────────────────────────────────── # Vault's web UI is used for the OIDC browser login flow (Vault as an OIDC # provider, if configured) and for manual operator inspection. -# Accessible at http://vault.riotpiao.homelab.com or via port-forward. +# Accessible at http://vault.riotpiao.com or via port-forward. ui: enabled: true diff --git a/project-usage/authentik-oidc.md b/project-usage/authentik-oidc.md index cd95710..98a5578 100644 --- a/project-usage/authentik-oidc.md +++ b/project-usage/authentik-oidc.md @@ -1,7 +1,7 @@ # Authentik Federated OIDC & SSO -**Provider:** `https://authentik.riotpiao.homelab.com` -**OIDC Issuer:** `https://authentik.riotpiao.homelab.com/application/o/talos-federation/` +**Provider:** `https://authentik.riotpiao.com` +**OIDC Issuer:** `https://authentik.riotpiao.com/application/o/talos-federation/` **Namespace:** `iam` ## When to Use @@ -15,7 +15,7 @@ **1. Login to Authentik console:** ```bash -# Browser: https://authentik.riotpiao.homelab.com +# Browser: https://authentik.riotpiao.com # Default user: akadmin # Password: AUTHENTIK_BOOTSTRAP_PASSWORD (from .env) @@ -33,7 +33,7 @@ Authentik console → Users → Create **3. User logs into Grafana:** ``` -https://grafana.riotpiao.homelab.com +https://grafana.riotpiao.com → Sign in with Authentik (auto-redirects to OIDC provider) → Approve access → Logged in as alice (group determines role: Admin or Viewer) @@ -44,8 +44,8 @@ https://grafana.riotpiao.homelab.com | Key | Value | |-----|-------| | OIDC provider | `talos-federation` (federated) | -| OIDC issuer | `https://authentik.riotpiao.homelab.com/application/o/talos-federation/` | -| JWKS endpoint | `https://authentik.riotpiao.homelab.com/application/o/talos-federation/.well-known/openid-configuration` | +| OIDC issuer | `https://authentik.riotpiao.com/application/o/talos-federation/` | +| JWKS endpoint | `https://authentik.riotpiao.com/application/o/talos-federation/.well-known/openid-configuration` | | Database | PostgreSQL (ddb namespace, authentik user) | | Backups | WAL archived to MinIO | @@ -60,9 +60,9 @@ grafana: name: Authentik client_id: grafana client_secret: $GRAFANA_OIDC_CLIENT_SECRET # from Vault - auth_url: https://authentik.riotpiao.homelab.com/application/o/authorize/ - token_url: https://authentik.riotpiao.homelab.com/application/o/token/ - api_url: https://authentik.riotpiao.homelab.com/application/o/userinfo/ + auth_url: https://authentik.riotpiao.com/application/o/authorize/ + token_url: https://authentik.riotpiao.com/application/o/token/ + api_url: https://authentik.riotpiao.com/application/o/userinfo/ scopes: openid profile email groups use_pkce: true ``` @@ -75,8 +75,8 @@ minio: provider: authentik client_id: minio client_secret: $MINIO_OIDC_CLIENT_SECRET - redirect_uri: https://minio.riotpiao.homelab.com/oauth_callback - config_url: https://authentik.riotpiao.homelab.com/application/o/talos-federation/.well-known/openid-configuration + redirect_uri: https://minio.riotpiao.com/oauth_callback + config_url: https://authentik.riotpiao.com/application/o/talos-federation/.well-known/openid-configuration policy_mappings: - group: homelab-admins → consoleAdmin - group: homelab-devops → readwrite @@ -99,7 +99,7 @@ core get cluster/ANTHROPIC_API_KEY --key ANTHROPIC_API_KEY ```go import "github.com/coreos/go-oidc/v3/oidc" -provider, _ := oidc.NewProvider(ctx, "https://authentik.riotpiao.homelab.com/application/o/talos-federation/") +provider, _ := oidc.NewProvider(ctx, "https://authentik.riotpiao.com/application/o/talos-federation/") verifier := provider.Verifier(&oidc.Config{ClientID: "my-app"}) @@ -137,7 +137,7 @@ Authentik console → Users → alice → Edit ## Monitoring -**Authentik dashboard:** https://authentik.riotpiao.homelab.com/api/v3/admin/dashboards +**Authentik dashboard:** https://authentik.riotpiao.com/api/v3/admin/dashboards **Key metrics:** - Login attempts (success/failure) @@ -151,7 +151,7 @@ Authentik console → Users → alice → Edit ```bash # Check redirect URI matches # Authentik console → Applications → grafana → Edit -# Verify Redirect URI = https://grafana.riotpiao.homelab.com/login/generic_oauth +# Verify Redirect URI = https://grafana.riotpiao.com/login/generic_oauth # Check OIDC provider is running k get pods -n iam -l app=authentik @@ -174,7 +174,7 @@ core secrets login **Vault can't validate JWT:** ```bash # Verify JWKS endpoint is accessible -curl https://authentik.riotpiao.homelab.com/application/o/talos-federation/.well-known/openid-configuration +curl https://authentik.riotpiao.com/application/o/talos-federation/.well-known/openid-configuration # Restart Vault to refresh JWKS cache k rollout restart -n iam deployment/vault diff --git a/project-usage/cicd-workflow.md b/project-usage/cicd-workflow.md index 033c3c4..3b13781 100644 --- a/project-usage/cicd-workflow.md +++ b/project-usage/cicd-workflow.md @@ -1,7 +1,7 @@ # CI/CD Pipeline (Forgejo + Argo CD) -**Git Forge:** `https://forgejo.riotpiao.homelab.com` -**Deployments:** `https://argocd.riotpiao.homelab.com` (or `kubectl port-forward`) +**Git Forge:** `https://forgejo.riotpiao.com` +**Deployments:** `https://argocd.riotpiao.com` (or `kubectl port-forward`) **Namespaces:** `cicd`, `forge` ## When to Use @@ -15,7 +15,7 @@ **1. Clone a repo from Forgejo:** ```bash -git clone https://forgejo.riotpiao.homelab.com/rock/source.git +git clone https://forgejo.riotpiao.com/rock/source.git cd source ``` @@ -33,10 +33,10 @@ jobs: - run: npm test - run: docker build -t myapp:latest . - run: | - docker login forgejo.riotpiao.homelab.com \ + docker login forgejo.riotpiao.com \ -u ci-bot \ -p ${{ secrets.CI_BOT_TOKEN }} - docker push forgejo.riotpiao.homelab.com/rock/myapp:latest + docker push forgejo.riotpiao.com/rock/myapp:latest EOF git add .forgejo/workflows/ci.yml @@ -47,11 +47,11 @@ git push **3. Trigger deployment:** ```bash # Update deployment repo (rock/deploy) -git clone https://forgejo.riotpiao.homelab.com/rock/deploy.git +git clone https://forgejo.riotpiao.com/rock/deploy.git cd deploy # Update image tag -sed -i 's|forgejo.riotpiao.homelab.com/rock/myapp:.*|forgejo.riotpiao.homelab.com/rock/myapp:abc123|' k8s/deployment.yaml +sed -i 's|forgejo.riotpiao.com/rock/myapp:.*|forgejo.riotpiao.com/rock/myapp:abc123|' k8s/deployment.yaml git add k8s/deployment.yaml git commit -m "deploy: bump myapp to abc123" @@ -92,7 +92,7 @@ jobs: steps: - uses: actions/checkout@v3 - run: docker build -t myapp:${{ github.sha }} . - - run: docker push forgejo.riotpiao.homelab.com/rock/myapp:${{ github.sha }} + - run: docker push forgejo.riotpiao.com/rock/myapp:${{ github.sha }} ``` **Available variables:** @@ -109,10 +109,10 @@ ${{ secrets.CI_BOT_TOKEN }} # injected from Forgejo ```yaml - run: | echo "${{ secrets.CI_BOT_TOKEN }}" | docker login \ - forgejo.riotpiao.homelab.com \ + forgejo.riotpiao.com \ -u ci-bot \ --password-stdin - docker push forgejo.riotpiao.homelab.com/rock/myapp:latest + docker push forgejo.riotpiao.com/rock/myapp:latest ``` **API token (for pushing commits):** @@ -121,7 +121,7 @@ ${{ secrets.CI_BOT_TOKEN }} # injected from Forgejo git config user.name "ci-bot" git config user.email "ci-bot@homelab" git commit --allow-empty -m "bump: version" - git push https://ci-bot:${{ secrets.CI_BOT_TOKEN }}@forgejo.riotpiao.homelab.com/rock/deploy.git main + git push https://ci-bot:${{ secrets.CI_BOT_TOKEN }}@forgejo.riotpiao.com/rock/deploy.git main ``` **Vault secrets (via talos CLI):** @@ -135,7 +135,7 @@ ${{ secrets.CI_BOT_TOKEN }} # injected from Forgejo **Create app (one-time):** ```bash argocd app create story-crater \ - --repo https://forgejo.riotpiao.homelab.com/rock/deploy.git \ + --repo https://forgejo.riotpiao.com/rock/deploy.git \ --path k8s/ \ --dest-server https://kubernetes.default.svc \ --dest-namespace story-crater-backend \ @@ -148,7 +148,7 @@ argocd app create story-crater \ argocd app get story-crater argocd app logs story-crater -# UI: https://argocd.riotpiao.homelab.com +# UI: https://argocd.riotpiao.com # Login: Authentik SSO (homelab-admins group only) ``` diff --git a/project-usage/infra-practice.md b/project-usage/infra-practice.md index 829bf4f..169f09f 100644 --- a/project-usage/infra-practice.md +++ b/project-usage/infra-practice.md @@ -107,7 +107,7 @@ Standardized procedures for troubleshooting, developing, deploying, and operatin - Verify scrape: `kubectl get servicemonitor -A | grep ` and check Prometheus Targets UI for green status. 9. **If OIDC/IAM-gated (admin UI, restricted API):** - - Create app in Authentik: `core iam create-app "my-service" --slug my-service --redirect-uri "https://my-service.riotpiao.homelab.com/callback"`. + - Create app in Authentik: `core iam create-app "my-service" --slug my-service --redirect-uri "https://my-service.riotpiao.com/callback"`. - Bind app to group: `core iam bind-app my-service ` (e.g., `grafana-admins` for admin-only UI). - Retrieve credentials: `core iam describe-app my-service` (client ID, client secret). - Deploy secret: `kubectl create secret generic -oidc --from-literal=client-id= --from-literal=client-secret= -n `. @@ -117,7 +117,7 @@ Standardized procedures for troubleshooting, developing, deploying, and operatin 10. **Verify service is live.** - Pods: `kubectl get pods -n -o wide` (all Running, 1/1 Ready). - Metrics (if applicable): `kubectl get servicemonitor -A | grep ` and visit Prometheus Targets or Grafana dashboard. - - Endpoint: If publicly routed via Ingress, verify `/etc/hosts` entry (10.6.0.1 for WireGuard, 192.168.1.160 for LAN) and `curl https://my-service.riotpiao.homelab.com/health` (or equivalent health endpoint). + - Endpoint: If publicly routed via Ingress, verify `/etc/hosts` entry (10.6.0.1 for WireGuard, 192.168.1.160 for LAN) and `curl https://my-service.riotpiao.com/health` (or equivalent health endpoint). - Logs: `kubectl logs -n ` (no errors). ### Definition of Done (Per Service) diff --git a/project-usage/infra-troubleshooting.md b/project-usage/infra-troubleshooting.md index 652fe2d..a609107 100644 --- a/project-usage/infra-troubleshooting.md +++ b/project-usage/infra-troubleshooting.md @@ -58,7 +58,7 @@ k exec -n ddb pod/ddb-cluster-0 -- psql -U postgres -c "SELECT * FROM pg_stat_re - **MinIO credentials:** Use Secret volumes, never `--env` flag (exposes in `kubectl describe`) - **Temporal namespace registration:** never manually `temporal operator namespace create` for a namespace a Queue's `temporal.io/namespace` label references — `queue-operator` registers it automatically. See `~/workplace/kmsvc-manage/CLAUDE.md` ("Temporal Namespace Registration") for the full rule and why. - **kubectl hangs / connection refused:** you're probably off-LAN. `kubectl config use-context admin@homelab-cluster-1` (WireGuard path, `10.6.0.1:6443`) — the default context (`admin@homelab-cluster`, `192.168.1.213:6443`) only works on-LAN. See README.md "kubectl Context". -- **No wildcard DNS:** `*.riotpiao.homelab.com` isn't a real DNS zone — every hostname is a manual `/etc/hosts` line (`10.6.0.1` for WireGuard, the Cilium LB-IPAM IP for LAN). Adding an Ingress `host:` rule doesn't make it resolvable; you must also add the `/etc/hosts` line, on every client machine that needs it. +- **No wildcard DNS:** `*.riotpiao.com` isn't a real DNS zone — every hostname is a manual `/etc/hosts` line (`10.6.0.1` for WireGuard, the Cilium LB-IPAM IP for LAN). Adding an Ingress `host:` rule doesn't make it resolvable; you must also add the `/etc/hosts` line, on every client machine that needs it. - **gRPC through nginx ingress:** add `nginx.ingress.kubernetes.io/backend-protocol: "GRPC"` to proxy h2c to a plaintext-gRPC backend (see `temporal-grpc` Ingress in `k8s/ingress/ingress.yaml`). TLS still terminates at nginx via the wildcard cert — clients need `--tls`, not client certs. - **Soft podAntiAffinity doesn't rebalance existing pods.** `preferredDuringSchedulingIgnoredDuringExecution` only applies at scheduling time — pods that landed on the same node before the constraint existed (or before other nodes were `Ready`) stay there forever. Fixing the affinity config in values.yaml/CRD only affects *future* pod creation; existing skew needs `kubectl delete pod ` (one at a time, verify healthy before the next) to force a reschedule under the now-correct constraint. Hit this with Cassandra, the Kafka `KafkaNodePool`, and CNPG's `ddb-cluster` all stacking onto `talos-cp-1`. - **Cassandra/StatefulSet pod deleted+recreated with no PVC (ephemeral storage) can crash-loop on rejoin:** `Other bootstrapping/leaving/moving nodes detected` or `A node required to move the data consistently is down (/)` — the ring still holds a stale gossip entry for the deleted pod's old IP. Fix: `kubectl exec -- nodetool assassinate ` from a healthy node, then let the crash-looping pod's next restart retry. diff --git a/project-usage/minio-s3.md b/project-usage/minio-s3.md index 3770243..9ae989e 100644 --- a/project-usage/minio-s3.md +++ b/project-usage/minio-s3.md @@ -1,6 +1,6 @@ # MinIO S3-Compatible Object Storage -**Endpoint:** `https://minio.riotpiao.homelab.com` (console) +**Endpoint:** `https://minio.riotpiao.com` (console) **API:** `minio.storage.svc.cluster.local:9000` (cluster-internal) **Namespace:** `storage` @@ -15,7 +15,7 @@ **1. Access MinIO console:** ```bash -# Via browser: https://minio.riotpiao.homelab.com +# Via browser: https://minio.riotpiao.com # Credentials: MINIO_ROOT_USER / MINIO_ROOT_PASSWORD (from .env) # Or port-forward @@ -29,7 +29,7 @@ export AWS_ACCESS_KEY_ID=$MINIO_ROOT_USER export AWS_SECRET_ACCESS_KEY=$MINIO_ROOT_PASSWORD aws s3 mb s3://my-bucket \ - --endpoint-url https://minio.riotpiao.homelab.com \ + --endpoint-url https://minio.riotpiao.com \ --region homelab # Or via console UI: Click "Create Bucket" @@ -126,8 +126,8 @@ aws s3 ls --endpoint-url http://$MINIO_ENDPOINT --use-path-style **External access (HTTPS via Ingress):** ```bash -# Console: https://minio.riotpiao.homelab.com (port 9001) -# API: Use AWS CLI with --endpoint-url https://minio.riotpiao.homelab.com:9000 +# Console: https://minio.riotpiao.com (port 9001) +# API: Use AWS CLI with --endpoint-url https://minio.riotpiao.com:9000 ``` ## Troubleshooting diff --git a/project-usage/monitoring-metrics.md b/project-usage/monitoring-metrics.md index 38b4a7f..fdc49b5 100644 --- a/project-usage/monitoring-metrics.md +++ b/project-usage/monitoring-metrics.md @@ -1,7 +1,7 @@ # Monitoring: Prometheus, Grafana & Loki **Prometheus:** `prometheus-kube-prom-prometheus.monitoring.svc.cluster.local:9090` -**Grafana:** `https://grafana.riotpiao.homelab.com` +**Grafana:** `https://grafana.riotpiao.com` **Loki:** `loki.logging.svc.cluster.local:3100` **Namespaces:** `monitoring`, `logging` @@ -16,7 +16,7 @@ **1. Access Grafana:** ```bash -# Browser: https://grafana.riotpiao.homelab.com +# Browser: https://grafana.riotpiao.com # Login: admin / GRAFANA_ADMIN_PASSWORD (from .env) # Or via Authentik SSO diff --git a/project-usage/networking-ingress.md b/project-usage/networking-ingress.md index e481f9e..f203f07 100644 --- a/project-usage/networking-ingress.md +++ b/project-usage/networking-ingress.md @@ -27,10 +27,10 @@ spec: ingressClassName: nginx tls: - hosts: - - myapp.riotpiao.homelab.com + - myapp.riotpiao.com secretName: myapp-tls rules: - - host: myapp.riotpiao.homelab.com + - host: myapp.riotpiao.com http: paths: - path: / @@ -54,10 +54,10 @@ kubectl get certificate -n myapp-ns **3. Test from client:** ```bash # Add to /etc/hosts (or use WireGuard) -192.168.1.160 myapp.riotpiao.homelab.com +192.168.1.160 myapp.riotpiao.com # Access -curl https://myapp.riotpiao.homelab.com +curl https://myapp.riotpiao.com ``` ## Configuration @@ -83,10 +83,10 @@ spec: ingressClassName: nginx tls: - hosts: - - api.riotpiao.homelab.com + - api.riotpiao.com secretName: api-tls rules: - - host: api.riotpiao.homelab.com + - host: api.riotpiao.com http: paths: - path: /users @@ -130,7 +130,7 @@ metadata: spec: ingressClassName: nginx rules: - - host: protected.riotpiao.homelab.com + - host: protected.riotpiao.com http: paths: - path: / @@ -146,8 +146,8 @@ spec: ```yaml # k8s/coredns/coredns-configmap.yaml # Rewrite: -# - grafana.riotpiao.homelab.com → grafana.logging (cluster-internal) -# - prometheus.riotpiao.homelab.com → prometheus-kube-prom-prometheus.monitoring +# - grafana.riotpiao.com → grafana.logging (cluster-internal) +# - prometheus.riotpiao.com → prometheus-kube-prom-prometheus.monitoring # # Allows pods to use external URLs but resolve to internal Services ``` @@ -184,9 +184,9 @@ spec: secretName: myapp-tls duration: 2160h # 90 days renewBefore: 360h # renew 15 days before expiry - commonName: myapp.riotpiao.homelab.com + commonName: myapp.riotpiao.com dnsNames: - - myapp.riotpiao.homelab.com + - myapp.riotpiao.com issuerRef: name: homelab-ca kind: ClusterIssuer @@ -229,7 +229,7 @@ nslookup grafana # if in logging namespace make pf-grafana # localhost:3000 → grafana.logging:3000 # Option 3: Add to /etc/hosts (on home network) -192.168.1.160 grafana.riotpiao.homelab.com +192.168.1.160 grafana.riotpiao.com ``` ## Monitoring @@ -308,7 +308,7 @@ k get secret -n myapp-ns myapp-tls -o jsonpath='{.data.tls\.crt}' | base64 -d | # If cert is self-signed (homelab-ca), add to client's trusted roots # Or bypass cert verification (dev only): -curl -k https://myapp.riotpiao.homelab.com +curl -k https://myapp.riotpiao.com ``` See `/TROUBLESHOOTING.md` for full incident guide. diff --git a/project-usage/sqs-messaging.md b/project-usage/sqs-messaging.md index 9a43afb..007c7ea 100644 --- a/project-usage/sqs-messaging.md +++ b/project-usage/sqs-messaging.md @@ -1,6 +1,6 @@ # SQS-like Message Queue Service (kmsvc) -**Endpoint:** `https://kmsvc.riotpiao.homelab.com` (REST + gRPC-Gateway) +**Endpoint:** `https://kmsvc.riotpiao.com` (REST + gRPC-Gateway) **Internal:** `kmsvc-management-service.sqs.svc.cluster.local:8080` **Namespace:** `sqs` @@ -31,7 +31,7 @@ EOF **2. Send message:** ```bash -curl -X POST https://kmsvc.riotpiao.homelab.com/v1/queues/orders/messages \ +curl -X POST https://kmsvc.riotpiao.com/v1/queues/orders/messages \ -H "Authorization: Bearer $JWT_TOKEN" \ -d '{ "body": "{\"order_id\":123,\"total\":99.99}", @@ -41,7 +41,7 @@ curl -X POST https://kmsvc.riotpiao.homelab.com/v1/queues/orders/messages \ **3. Receive message:** ```bash -curl "https://kmsvc.riotpiao.homelab.com/v1/queues/orders/messages?max_number_of_messages=10&wait_time_seconds=20" \ +curl "https://kmsvc.riotpiao.com/v1/queues/orders/messages?max_number_of_messages=10&wait_time_seconds=20" \ -H "Authorization: Bearer $JWT_TOKEN" # Response: @@ -60,7 +60,7 @@ curl "https://kmsvc.riotpiao.homelab.com/v1/queues/orders/messages?max_number_of **4. Acknowledge (delete) message:** ```bash -curl -X DELETE "https://kmsvc.riotpiao.homelab.com/v1/queues/orders/messages/$receipt_handle" \ +curl -X DELETE "https://kmsvc.riotpiao.com/v1/queues/orders/messages/$receipt_handle" \ -H "Authorization: Bearer $JWT_TOKEN" ``` @@ -79,7 +79,7 @@ curl -X DELETE "https://kmsvc.riotpiao.homelab.com/v1/queues/orders/messages/$re **Batch processing:** ```bash for i in {1..100}; do - curl -X POST https://kmsvc.riotpiao.homelab.com/v1/queues/jobs/messages \ + curl -X POST https://kmsvc.riotpiao.com/v1/queues/jobs/messages \ -H "Authorization: Bearer $JWT_TOKEN" \ -d "{\"body\":\"task-$i\"}" & done @@ -148,7 +148,7 @@ core secrets login # Use token export JWT_TOKEN=$(core get cluster/kmsvc/jwt-token --key jwt-token) -curl -H "Authorization: Bearer $JWT_TOKEN" https://kmsvc.riotpiao.homelab.com/v1/queues +curl -H "Authorization: Bearer $JWT_TOKEN" https://kmsvc.riotpiao.com/v1/queues ``` ## Integration Example diff --git a/project-usage/vault-secrets.md b/project-usage/vault-secrets.md index 3dba7a6..3348066 100644 --- a/project-usage/vault-secrets.md +++ b/project-usage/vault-secrets.md @@ -1,6 +1,6 @@ # Vault: Secret Management & JWT Auth -**Vault:** `https://vault.riotpiao.homelab.com` +**Vault:** `https://vault.riotpiao.com` **Internal:** `vault.iam.svc.cluster.local:8200` **Namespace:** `iam` @@ -15,7 +15,7 @@ **1. Login to Vault:** ```bash -# Browser: https://vault.riotpiao.homelab.com +# Browser: https://vault.riotpiao.com # Auth method: OIDC → "Sign in with Authentik" (federated) # Or: Device code → core secrets login (CLI) diff --git a/terraform/main.tf b/terraform/main.tf index 4ed2465..3188dfb 100644 --- a/terraform/main.tf +++ b/terraform/main.tf @@ -1,15 +1,15 @@ # Generate Talos machine configurations locals { - pod_cidr = var.cluster_config.pod_subnets[0] - service_cidr = var.cluster_config.service_subnets[0] - controlplane_ip = var.cluster_config.controlplane_ip - cluster_dns_ip = "10.96.0.10" - kubelet_image = "ghcr.io/siderolabs/kubelet:${var.kubernetes_version}" - kube_apiserver_img = "registry.k8s.io/kube-apiserver:${var.kubernetes_version}" - controller_mgr_img = "registry.k8s.io/kube-controller-manager:${var.kubernetes_version}" - kube_proxy_img = "registry.k8s.io/kube-proxy:${var.kubernetes_version}" - scheduler_img = "registry.k8s.io/kube-scheduler:${var.kubernetes_version}" + pod_cidr = var.cluster_config.pod_subnets[0] + service_cidr = var.cluster_config.service_subnets[0] + controlplane_ip = var.cluster_config.controlplane_ip + cluster_dns_ip = "10.96.0.10" + kubelet_image = "ghcr.io/siderolabs/kubelet:${var.kubernetes_version}" + kube_apiserver_img = "registry.k8s.io/kube-apiserver:${var.kubernetes_version}" + controller_mgr_img = "registry.k8s.io/kube-controller-manager:${var.kubernetes_version}" + kube_proxy_img = "registry.k8s.io/kube-proxy:${var.kubernetes_version}" + scheduler_img = "registry.k8s.io/kube-scheduler:${var.kubernetes_version}" factory_image = "factory.talos.dev/installer/613e1592b2da41ae5e265e8789429f22e121aab91cb4deb6bc3c0b6262961245:${var.talos_version}" } @@ -19,58 +19,59 @@ resource "local_file" "controlplane_config" { filename = "${path.module}/../cluster-config/controlplane.yaml" content = templatefile("${path.module}/templates/controlplane.tftpl", { - version = "v1alpha1" - hostname = var.controlplane_config.hostname - token = var.machine_token - ca_crt = var.machine_ca_crt - ca_key = var.machine_ca_key - lan_ip = var.controlplane_config.lan_ip - lan_subnet = var.controlplane_config.lan_subnet - lan_gateway = var.controlplane_config.lan_gateway - wg0_ip = var.controlplane_config.wg0_ip - wg0_subnet = var.controlplane_config.wg0_subnet - wg0_port = var.controlplane_config.wg0_port - wg0_private_key = var.controlplane_config.wg0_private_key - wg0_peers = var.controlplane_config.wg0_peers - wg1_ip = var.controlplane_config.wg1_ip - wg1_subnet = var.controlplane_config.wg1_subnet - wg1_port = var.controlplane_config.wg1_port - wg1_private_key = var.controlplane_config.wg1_private_key - wg1_peers = var.controlplane_config.wg1_peers - kubelet_image = local.kubelet_image - cluster_dns_ip = local.cluster_dns_ip - install_disk = var.controlplane_config.install_disk - factory_image = local.factory_image - longhorn_disks = var.controlplane_config.longhorn_disks - dns_servers = var.cluster_config.dns_servers - forgejo_registry_ip = var.forgejo_registry_ip - forgejo_hostname = var.forgejo_hostname + version = "v1alpha1" + hostname = var.controlplane_config.hostname + token = var.machine_token + ca_crt = var.machine_ca_crt + ca_key = var.machine_ca_key + lan_ip = var.controlplane_config.lan_ip + lan_subnet = var.controlplane_config.lan_subnet + lan_gateway = var.controlplane_config.lan_gateway + wg0_ip = var.controlplane_config.wg0_ip + wg0_subnet = var.controlplane_config.wg0_subnet + wg0_port = var.controlplane_config.wg0_port + wg0_private_key = var.controlplane_config.wg0_private_key + wg0_peers = var.controlplane_config.wg0_peers + wg1_ip = var.controlplane_config.wg1_ip + wg1_subnet = var.controlplane_config.wg1_subnet + wg1_port = var.controlplane_config.wg1_port + wg1_private_key = var.controlplane_config.wg1_private_key + wg1_peers = var.controlplane_config.wg1_peers + kubelet_image = local.kubelet_image + cluster_dns_ip = local.cluster_dns_ip + install_disk = var.controlplane_config.install_disk + factory_image = local.factory_image + talos_version = var.talos_version + longhorn_disks = var.controlplane_config.longhorn_disks + dns_servers = var.cluster_config.dns_servers + forgejo_registry_ip = var.forgejo_registry_ip + forgejo_hostname = var.forgejo_hostname # Cluster config - cluster_id = var.cluster_id - cluster_secret = var.cluster_secret - controlplane_ip = local.controlplane_ip - cluster_name = var.cluster_name - pod_subnets = var.cluster_config.pod_subnets - service_subnets = var.cluster_config.service_subnets - dns_domain = var.cluster_config.dns_domain - bootstrap_token = var.bootstrap_token + cluster_id = var.cluster_id + cluster_secret = var.cluster_secret + controlplane_ip = local.controlplane_ip + cluster_name = var.cluster_name + pod_subnets = var.cluster_config.pod_subnets + service_subnets = var.cluster_config.service_subnets + dns_domain = var.cluster_config.dns_domain + bootstrap_token = var.bootstrap_token # Kubernetes certs - kubernetes_ca_crt = var.kubernetes_ca_crt - kubernetes_ca_key = var.kubernetes_ca_key - etcd_ca_crt = var.etcd_ca_crt - etcd_ca_key = var.etcd_ca_key - aggregator_ca_crt = var.aggregator_ca_crt - aggregator_ca_key = var.aggregator_ca_key - service_account_key = var.service_account_key - secretbox_encryption_secret = var.secretbox_encryption_secret + kubernetes_ca_crt = var.kubernetes_ca_crt + kubernetes_ca_key = var.kubernetes_ca_key + etcd_ca_crt = var.etcd_ca_crt + etcd_ca_key = var.etcd_ca_key + aggregator_ca_crt = var.aggregator_ca_crt + aggregator_ca_key = var.aggregator_ca_key + service_account_key = var.service_account_key + secretbox_encryption_secret = var.secretbox_encryption_secret # Component images - kube_apiserver_img = local.kube_apiserver_img - controller_mgr_img = local.controller_mgr_img - kube_proxy_img = local.kube_proxy_img - scheduler_img = local.scheduler_img + kube_apiserver_img = local.kube_apiserver_img + controller_mgr_img = local.controller_mgr_img + kube_proxy_img = local.kube_proxy_img + scheduler_img = local.scheduler_img }) } @@ -81,34 +82,35 @@ resource "local_file" "worker_configs" { filename = "${path.module}/../cluster-config/${each.key}.yaml" content = templatefile("${path.module}/templates/worker.tftpl", { - version = "v1alpha1" - hostname = each.value.hostname - token = var.machine_token - ca_crt = var.machine_ca_crt - lan_ip = each.value.lan_ip - lan_subnet = each.value.lan_subnet - lan_gateway = each.value.lan_gateway - kubelet_image = local.kubelet_image - cluster_dns_ip = local.cluster_dns_ip - install_disk = each.value.install_disk - factory_image = local.factory_image - node_labels = each.value.node_labels + version = "v1alpha1" + hostname = each.value.hostname + token = var.machine_token + ca_crt = var.machine_ca_crt + lan_ip = each.value.lan_ip + lan_subnet = each.value.lan_subnet + lan_gateway = each.value.lan_gateway + kubelet_image = local.kubelet_image + cluster_dns_ip = local.cluster_dns_ip + install_disk = each.value.install_disk + factory_image = local.factory_image + talos_version = var.talos_version + node_labels = each.value.node_labels # Cluster config - cluster_id = var.cluster_id - cluster_secret = var.cluster_secret - controlplane_ip = local.controlplane_ip - cluster_name = var.cluster_name - pod_subnets = var.cluster_config.pod_subnets - service_subnets = var.cluster_config.service_subnets - dns_domain = var.cluster_config.dns_domain - bootstrap_token = var.bootstrap_token + cluster_id = var.cluster_id + cluster_secret = var.cluster_secret + controlplane_ip = local.controlplane_ip + cluster_name = var.cluster_name + pod_subnets = var.cluster_config.pod_subnets + service_subnets = var.cluster_config.service_subnets + dns_domain = var.cluster_config.dns_domain + bootstrap_token = var.bootstrap_token # Kubernetes certs - kubernetes_ca_crt = var.kubernetes_ca_crt + kubernetes_ca_crt = var.kubernetes_ca_crt # Component images - kube_proxy_img = local.kube_proxy_img + kube_proxy_img = local.kube_proxy_img }) } diff --git a/terraform/templates/controlplane.tftpl b/terraform/templates/controlplane.tftpl index 5fb7322..d5b628c 100644 --- a/terraform/templates/controlplane.tftpl +++ b/terraform/templates/controlplane.tftpl @@ -74,7 +74,7 @@ machine: install: disk: ${install_disk} image: factory.talos.dev/installer/613e1592b2da41ae5e265e8789429f22e121aab91cb4deb6bc3c0b6262961245:${talos_version} - wipe: true + wipe: false grubUseUKICmdline: true disks: %{ for disk in longhorn_disks ~} diff --git a/terraform/variables.tf b/terraform/variables.tf index df645de..804e0a8 100644 --- a/terraform/variables.tf +++ b/terraform/variables.tf @@ -102,28 +102,28 @@ variable "secretbox_encryption_secret" { variable "controlplane_config" { type = object({ - hostname = string - lan_ip = string - lan_subnet = string - lan_gateway = string - wg0_ip = string - wg0_subnet = string - wg0_port = number - wg0_peers = list(object({ - public_key = string - allowed_ips = list(string) + hostname = string + lan_ip = string + lan_subnet = string + lan_gateway = string + wg0_ip = string + wg0_subnet = string + wg0_port = number + wg0_peers = list(object({ + public_key = string + allowed_ips = list(string) })) - wg1_ip = string - wg1_subnet = string - wg1_port = number - wg1_peers = list(object({ + wg1_ip = string + wg1_subnet = string + wg1_port = number + wg1_peers = list(object({ public_key = string allowed_ips = list(string) persistent_keepalive_secs = number })) wg0_private_key = string wg1_private_key = string - install_disk = string + install_disk = string longhorn_disks = list(object({ device = string mountpoint = string @@ -134,12 +134,12 @@ variable "controlplane_config" { variable "worker_configs" { type = map(object({ - hostname = string - lan_ip = string - lan_subnet = string - lan_gateway = string + hostname = string + lan_ip = string + lan_subnet = string + lan_gateway = string install_disk = string - node_labels = map(string) + node_labels = map(string) })) description = "Worker machine configurations" } @@ -163,6 +163,6 @@ variable "forgejo_registry_ip" { variable "forgejo_hostname" { type = string - default = "forgejo.riotpiao.homelab.com" + default = "forgejo.riotpiao.com" description = "Forgejo external hostname" }