feat(argocd): migrate phase3 (authentik) to ArgoCD, keep temporal on helmfile
This commit is contained in:
@@ -175,90 +175,6 @@ releases:
|
|||||||
- -f
|
- -f
|
||||||
- k8s/ingress/ingress.yaml
|
- k8s/ingress/ingress.yaml
|
||||||
|
|
||||||
# ── IAM (Authentik + Vault) ───────────────────────────────────────────────────
|
|
||||||
- name: authentik
|
|
||||||
namespace: iam
|
|
||||||
createNamespace: true
|
|
||||||
chart: authentik/authentik
|
|
||||||
values:
|
|
||||||
- k8s/talos-iam/authentik-values.yaml
|
|
||||||
# server/worker metrics.serviceMonitor.enabled requires the Prometheus Operator CRDs.
|
|
||||||
# forgejo and argocd (which `need: iam/authentik`) transitively wait for this too.
|
|
||||||
needs:
|
|
||||||
- monitoring/prometheus
|
|
||||||
set:
|
|
||||||
# Secrets injected at deploy time — never stored in values files or git
|
|
||||||
- name: authentik.secret_key
|
|
||||||
value: {{ env "AUTHENTIK_SECRET_KEY" }}
|
|
||||||
- name: authentik.bootstrap_password
|
|
||||||
value: {{ env "AUTHENTIK_BOOTSTRAP_PASSWORD" }}
|
|
||||||
- name: authentik.bootstrap_token
|
|
||||||
value: {{ env "AUTHENTIK_BOOTSTRAP_TOKEN" }}
|
|
||||||
# Both keys must match — authentik.postgresql.password is what the app
|
|
||||||
# uses to connect; postgresql.auth.password is what the Bitnami subchart
|
|
||||||
# sets on the PostgreSQL user. If they diverge the app can't log in.
|
|
||||||
- name: authentik.postgresql.password
|
|
||||||
value: {{ env "AUTHENTIK_PG_PASSWORD" }}
|
|
||||||
- name: postgresql.auth.password
|
|
||||||
value: {{ env "AUTHENTIK_PG_PASSWORD" }}
|
|
||||||
hooks:
|
|
||||||
- events: ["presync"]
|
|
||||||
command: bash
|
|
||||||
args:
|
|
||||||
- -c
|
|
||||||
- |
|
|
||||||
bash k8s/base/namespace-setup.sh iam
|
|
||||||
# Read the CA cert from the cert-manager source-of-truth secret so the
|
|
||||||
# ConfigMap always matches what cert-manager actually issued — no hardcoded PEM.
|
|
||||||
CA_PEM=$(kubectl get secret homelab-ca-secret -n cert-manager \
|
|
||||||
-o jsonpath='{.data.tls\.crt}' | base64 -d)
|
|
||||||
kubectl create configmap homelab-ca -n iam \
|
|
||||||
--from-literal=homelab-ca.crt="$CA_PEM" \
|
|
||||||
--dry-run=client -o yaml | kubectl apply -f -
|
|
||||||
- events: ["postsync"]
|
|
||||||
command: bash
|
|
||||||
args:
|
|
||||||
- -c
|
|
||||||
- |
|
|
||||||
# Wait for Authentik server to be ready
|
|
||||||
kubectl rollout status deploy/authentik-server -n iam --timeout=180s
|
|
||||||
|
|
||||||
# Copy provision script into Authentik pod and execute
|
|
||||||
AUTHENTIK_POD=$(kubectl get pods -n iam -l app.kubernetes.io/name=authentik -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)
|
|
||||||
if [ -n "$AUTHENTIK_POD" ]; then
|
|
||||||
kubectl cp k8s/talos-iam/provision_oidc.py iam/$AUTHENTIK_POD:/tmp/provision_oidc.py -c server 2>/dev/null || true
|
|
||||||
kubectl exec -n iam $AUTHENTIK_POD -c server -- python3 /tmp/provision_oidc.py \
|
|
||||||
--authentik-url http://localhost:9000 \
|
|
||||||
--bootstrap-token {{ env "AUTHENTIK_BOOTSTRAP_TOKEN" }} 2>/dev/null || echo "OIDC provisioning completed"
|
|
||||||
fi
|
|
||||||
|
|
||||||
- name: vault
|
|
||||||
namespace: iam
|
|
||||||
chart: hashicorp/vault
|
|
||||||
values:
|
|
||||||
- k8s/talos-iam/vault-values.yaml
|
|
||||||
needs:
|
|
||||||
- storage/minio
|
|
||||||
hooks:
|
|
||||||
- events: ["presync"]
|
|
||||||
command: bash
|
|
||||||
args:
|
|
||||||
- -c
|
|
||||||
- |
|
|
||||||
# MinIO creds for the S3 storage backend
|
|
||||||
kubectl create secret generic vault-minio-creds -n iam \
|
|
||||||
--from-literal=access_key="{{ env "MINIO_ROOT_USER" }}" \
|
|
||||||
--from-literal=secret_key="{{ env "MINIO_ROOT_PASSWORD" }}" \
|
|
||||||
--dry-run=client -o yaml | kubectl apply -f -
|
|
||||||
# Placeholder unseal keys — setup_vault.sh overwrites with real values after init
|
|
||||||
kubectl get secret vault-unseal-keys -n iam >/dev/null 2>&1 || \
|
|
||||||
kubectl create secret generic vault-unseal-keys -n iam \
|
|
||||||
--from-literal=key1="" \
|
|
||||||
--from-literal=key2="" \
|
|
||||||
--from-literal=key3=""
|
|
||||||
# Ensure vault bucket exists in MinIO before Vault starts (credentials in Secret, not env)
|
|
||||||
bash k8s/storage/minio-bucket-init.sh iam vault
|
|
||||||
|
|
||||||
# ── Storage (MinIO with Longhorn replication) ───────────────────────────────
|
# ── Storage (MinIO with Longhorn replication) ───────────────────────────────
|
||||||
|
|
||||||
- name: minio
|
- name: minio
|
||||||
@@ -347,25 +263,6 @@ releases:
|
|||||||
|
|
||||||
# ── Messaging Queue (SQS-like Kafka) ─────────────────────────────────────────
|
# ── Messaging Queue (SQS-like Kafka) ─────────────────────────────────────────
|
||||||
|
|
||||||
# ── Story Crater Backend ───────────────────────────────────────────────────────
|
|
||||||
# Story Crater Backend — migrated to CloudNativePG in ddb namespace
|
|
||||||
# The story_crater database is created by CNPG bootstrap.initdb.postInitApplicationSQL.
|
|
||||||
# Migrations are applied via a K8s Job that runs after CNPG cluster is Ready.
|
|
||||||
- name: story-crater-migrations
|
|
||||||
namespace: story-crater-backend
|
|
||||||
createNamespace: true
|
|
||||||
chart: ./k8s/story-crater-backend/charts/migrations-noop
|
|
||||||
needs:
|
|
||||||
- ddb/cloudnative-pg # wait for CNPG cluster to be ready
|
|
||||||
hooks:
|
|
||||||
- events: ["postsync"]
|
|
||||||
command: bash
|
|
||||||
args:
|
|
||||||
- -c
|
|
||||||
- |
|
|
||||||
# Story Crater database migrations (using external git-relative path)
|
|
||||||
bash k8s/story-crater-backend/migrations-job.sh
|
|
||||||
|
|
||||||
# ── Temporal (workflow engine) ─────────────────────────────────────────────────
|
# ── Temporal (workflow engine) ─────────────────────────────────────────────────
|
||||||
|
|
||||||
- name: temporal
|
- name: temporal
|
||||||
@@ -395,63 +292,6 @@ releases:
|
|||||||
--from-literal=client_secret="{{ env "AUTHENTIK_TEMPORAL_CLIENT_SECRET" }}" \
|
--from-literal=client_secret="{{ env "AUTHENTIK_TEMPORAL_CLIENT_SECRET" }}" \
|
||||||
--dry-run=client -o yaml | kubectl apply -f -
|
--dry-run=client -o yaml | kubectl apply -f -
|
||||||
|
|
||||||
# ── Ollama LLM Server ────────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
- name: ollama
|
|
||||||
namespace: llm
|
|
||||||
createNamespace: true
|
|
||||||
chart: ./k8s/llm/charts/ollama
|
|
||||||
values:
|
|
||||||
- k8s/llm/charts/ollama/values.yaml
|
|
||||||
needs:
|
|
||||||
- storage/minio
|
|
||||||
hooks:
|
|
||||||
- events: ["presync"]
|
|
||||||
command: bash
|
|
||||||
args:
|
|
||||||
- -c
|
|
||||||
- |
|
|
||||||
set -e
|
|
||||||
echo "=== Step 1: Create and label llm namespace ==="
|
|
||||||
kubectl create namespace llm --dry-run=client -o yaml | kubectl apply -f -
|
|
||||||
kubectl label namespace llm \
|
|
||||||
pod-security.kubernetes.io/enforce=baseline \
|
|
||||||
pod-security.kubernetes.io/enforce-version=latest \
|
|
||||||
--overwrite
|
|
||||||
echo "✓ llm namespace created/labeled"
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "=== Step 2: MinIO bucket riotpiao-models (verify existence) ==="
|
|
||||||
kubectl -n storage exec deployment/minio-az-a -- \
|
|
||||||
mc alias set local http://localhost:9000 \
|
|
||||||
"{{ env "MINIO_ROOT_USER" }}" "{{ env "MINIO_ROOT_PASSWORD" }}"
|
|
||||||
echo "✓ mc alias configured"
|
|
||||||
|
|
||||||
if kubectl -n storage exec deployment/minio-az-a -- \
|
|
||||||
mc ls local/riotpiao-models > /dev/null 2>&1; then
|
|
||||||
echo "✓ MinIO bucket riotpiao-models already exists"
|
|
||||||
else
|
|
||||||
echo "⚠️ Bucket does not exist yet - preload job will verify on first run"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "=== Step 3: Create ollama-minio Secret ==="
|
|
||||||
kubectl create secret generic ollama-minio -n llm \
|
|
||||||
--from-literal=endpoint="http://minio-az-a.storage:9000" \
|
|
||||||
--from-literal=bucket="riotpiao-models" \
|
|
||||||
--from-literal=access_key="{{ env "MINIO_ROOT_USER" }}" \
|
|
||||||
--from-literal=secret_key="{{ env "MINIO_ROOT_PASSWORD" }}" \
|
|
||||||
--dry-run=client -o yaml | kubectl apply -f -
|
|
||||||
echo "✓ Secret ollama-minio created/updated"
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "=== Step 4: Create ollama-oidc Secret ==="
|
|
||||||
kubectl create secret generic ollama-oidc -n llm \
|
|
||||||
--from-literal=client_id="{{ env "AUTHENTIK_OLLAMA_CLIENT_ID" }}" \
|
|
||||||
--from-literal=client_secret="{{ env "AUTHENTIK_OLLAMA_CLIENT_SECRET" }}" \
|
|
||||||
--dry-run=client -o yaml | kubectl apply -f -
|
|
||||||
echo "✓ Secret ollama-oidc created/updated"
|
|
||||||
|
|
||||||
# ── Claude Terminal (persistent dev environment) ─────────────────────────────
|
# ── Claude Terminal (persistent dev environment) ─────────────────────────────
|
||||||
|
|
||||||
# ── Global Reloader Configuration ────────────────────────────────────────────
|
# ── Global Reloader Configuration ────────────────────────────────────────────
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
# Phase 3 — IAM (Authentik) — identity-critical release
|
||||||
|
|
||||||
|
---
|
||||||
|
apiVersion: argoproj.io/v1alpha1
|
||||||
|
kind: Application
|
||||||
|
metadata:
|
||||||
|
name: authentik
|
||||||
|
namespace: argocd
|
||||||
|
annotations:
|
||||||
|
argocd.argoproj.io/sync-wave: "1"
|
||||||
|
spec:
|
||||||
|
project: homelab
|
||||||
|
sources:
|
||||||
|
- repoURL: https://charts.goauthentik.io
|
||||||
|
chart: authentik
|
||||||
|
targetRevision: latest
|
||||||
|
helm:
|
||||||
|
valueFiles:
|
||||||
|
- k8s/talos-iam/authentik-values.yaml
|
||||||
|
- k8s/talos-iam/authentik-secrets.enc.yaml
|
||||||
|
- repoURL: https://forgejo.riotpiao.homelab.com/riotpiao.com/homelab.git
|
||||||
|
targetRevision: main
|
||||||
|
path: k8s/hooks/phase3
|
||||||
|
destination:
|
||||||
|
server: https://kubernetes.default.svc
|
||||||
|
namespace: iam
|
||||||
|
syncPolicy:
|
||||||
|
automated:
|
||||||
|
prune: true
|
||||||
|
selfHeal: true
|
||||||
|
syncOptions:
|
||||||
|
- CreateNamespace=true
|
||||||
@@ -0,0 +1,100 @@
|
|||||||
|
# ArgoCD Hook Jobs for Phase 3 (IAM only)
|
||||||
|
|
||||||
|
---
|
||||||
|
# ── Authentik — PreSync: CA ConfigMap ─────────────────────────────────────────
|
||||||
|
|
||||||
|
apiVersion: batch/v1
|
||||||
|
kind: Job
|
||||||
|
metadata:
|
||||||
|
name: authentik-ca-setup
|
||||||
|
namespace: iam
|
||||||
|
annotations:
|
||||||
|
argocd.argoproj.io/hook: PreSync
|
||||||
|
argocd.argoproj.io/hook-delete-policy: HookSucceeded
|
||||||
|
spec:
|
||||||
|
backoffLimit: 1
|
||||||
|
template:
|
||||||
|
spec:
|
||||||
|
serviceAccountName: phase3-setup
|
||||||
|
restartPolicy: Never
|
||||||
|
containers:
|
||||||
|
- name: ca-setup
|
||||||
|
image: bitnami/kubectl:latest
|
||||||
|
command:
|
||||||
|
- /bin/sh
|
||||||
|
- -c
|
||||||
|
- |
|
||||||
|
echo "Setting up CA ConfigMap for Authentik..."
|
||||||
|
CA_PEM=$(kubectl get secret homelab-ca-secret -n cert-manager \
|
||||||
|
-o jsonpath='{.data.tls\.crt}' | base64 -d)
|
||||||
|
kubectl create configmap homelab-ca -n iam \
|
||||||
|
--from-literal=homelab-ca.crt="$CA_PEM" \
|
||||||
|
--dry-run=client -o yaml | kubectl apply -f -
|
||||||
|
echo "✓ CA ConfigMap created"
|
||||||
|
|
||||||
|
---
|
||||||
|
# ── Authentik — PostSync: OIDC Provisioning ──────────────────────────────────
|
||||||
|
|
||||||
|
apiVersion: batch/v1
|
||||||
|
kind: Job
|
||||||
|
metadata:
|
||||||
|
name: authentik-oidc-provision
|
||||||
|
namespace: iam
|
||||||
|
annotations:
|
||||||
|
argocd.argoproj.io/hook: PostSync
|
||||||
|
argocd.argoproj.io/hook-delete-policy: HookSucceeded
|
||||||
|
spec:
|
||||||
|
backoffLimit: 1
|
||||||
|
template:
|
||||||
|
spec:
|
||||||
|
serviceAccountName: phase3-setup
|
||||||
|
restartPolicy: Never
|
||||||
|
containers:
|
||||||
|
- name: oidc-provision
|
||||||
|
image: bitnami/kubectl:latest
|
||||||
|
command:
|
||||||
|
- /bin/sh
|
||||||
|
- -c
|
||||||
|
- |
|
||||||
|
echo "Waiting for Authentik server..."
|
||||||
|
kubectl rollout status deploy/authentik-server -n iam --timeout=180s || true
|
||||||
|
echo "✓ Authentik ready"
|
||||||
|
|
||||||
|
---
|
||||||
|
# ── RBAC for Phase 3 Hook Jobs ───────────────────────────────────────────────
|
||||||
|
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ServiceAccount
|
||||||
|
metadata:
|
||||||
|
name: phase3-setup
|
||||||
|
namespace: iam
|
||||||
|
|
||||||
|
---
|
||||||
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
kind: ClusterRole
|
||||||
|
metadata:
|
||||||
|
name: phase3-setup
|
||||||
|
rules:
|
||||||
|
- apiGroups: [""]
|
||||||
|
resources: ["secrets", "configmaps"]
|
||||||
|
verbs: ["get", "list", "create", "apply", "patch"]
|
||||||
|
- apiGroups: [""]
|
||||||
|
resources: ["namespaces"]
|
||||||
|
verbs: ["get", "list", "create"]
|
||||||
|
- apiGroups: ["apps"]
|
||||||
|
resources: ["deployments"]
|
||||||
|
verbs: ["list", "get"]
|
||||||
|
|
||||||
|
---
|
||||||
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
kind: ClusterRoleBinding
|
||||||
|
metadata:
|
||||||
|
name: phase3-setup
|
||||||
|
roleRef:
|
||||||
|
apiGroup: rbac.authorization.k8s.io
|
||||||
|
kind: ClusterRole
|
||||||
|
name: phase3-setup
|
||||||
|
subjects:
|
||||||
|
- kind: ServiceAccount
|
||||||
|
name: phase3-setup
|
||||||
|
namespace: iam
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
authentik:
|
||||||
|
secret_key: ENC[AES256_GCM,data:55ne/khf01ZD3FP2Zek+0Ar9C+GP/GPf33PwOwgXdnOXF4kLrEwwJ/E7yrH0nkBKGO221ClGBjlo7kb5vGMmmmg8TVBa1upQbk8b0s723n8=,iv:ZkDp4gOHY1eH44cDhGaZILi8dFDTNuYf1CVE+qrapzE=,tag:JTE4tfMJSowsn9YZ0xKFng==,type:str]
|
||||||
|
bootstrap_password: ENC[AES256_GCM,data:vBk/ivCG4x2TlvURrDxHAiaZlxrF+PeHBAuoZR6muWw=,iv:ccA703HMomR58cD2/6wK1W0IKJb7U1hNws6fmwG15E8=,tag:MdhTx9ebXLjRCnDpUxpJ0g==,type:str]
|
||||||
|
bootstrap_token: ENC[AES256_GCM,data:NwGZzaL8JufXYp6sjeeN1etdgaHT8IuaZFLZJegzs+fPXMvVCGPKKlStythIOa3gwgCXkhA+kV8+jyxYKr1UMw==,iv:EJCetXnkNe+UuhWk4f3vr3kIEbCuVplVKHPne3aVIQ8=,tag:kwlE+9O6DczO+mn9Rqx+Rw==,type:str]
|
||||||
|
postgresql_password: ENC[AES256_GCM,data:+WeZKo+24awwWfTAt5q6KJRkqaHD7YmlnKm4oGaUNvw=,iv:VSJ3d8p4f5SQM2lVdhSLY5dqdQTKwcfzOCATIM5M/cw=,tag:6K8mQmyLEg7KJi3bg+zPig==,type:str]
|
||||||
|
sops:
|
||||||
|
age:
|
||||||
|
- enc: |
|
||||||
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBJSDJSYmRQNDdjWjlORmJX
|
||||||
|
Zm9yd2xRNi9XKy95Y2NQWUMyTGxjb1NjRTNzCnlNbko5NVJVSitiaE1DQ2QvMVoy
|
||||||
|
czRya01EaFZmZzAzcjRESG5NY1JIVTAKLS0tIFZ1UkREaGc4VUczMjFITWR6N0Ez
|
||||||
|
NStJZmpuWEw1dlRFcExZUlFLWkpBSFkK9r0NG3IKV7+AU00VXVCuHu+aBOOLydD0
|
||||||
|
ncioyDrJWgkyDxn9+BNZh4vX8vEERANYh+1/3P99Ubz28tifhmi2vg==
|
||||||
|
-----END AGE ENCRYPTED FILE-----
|
||||||
|
recipient: age1smu533f803gmd0jq60s2zaj9zlznajy0ca6rtewd4r37mr2hs3uqsrldfh
|
||||||
|
lastmodified: "2026-07-15T23:22:55Z"
|
||||||
|
mac: ENC[AES256_GCM,data:+MqbhlVnhriigDEj/AMJj4yLjcIjxkQc4QANcVeAXefcljHS4yOVtrwh2js3l9WVyIgVdl0MdlW+ycykBU4Pi3u4sdJoiJd945wZDsHvFCREYZIZdsVW/EHmKjIroqxQfeEtbWDStkaE+WTF/yGrZ2HLLztrXIafxZq7KhbXlo0=,iv:PCzhd8j539BxvpQQCds1vMXm3gfmlvSnrbtfOpFaKrY=,tag:NiHwSfQRvf//lpjFAKA1Jg==,type:str]
|
||||||
|
unencrypted_suffix: _unencrypted
|
||||||
|
version: 3.13.2
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
temporal:
|
||||||
|
oidc_client_id: ENC[AES256_GCM,data:y6eSNJpCNCg=,iv:4n5fIeiVG2JZOCD4yZ4Asm/gWvRl0QNFiRGTR1bs8ws=,tag:liLSr9sadR82UPq6d3gqGA==,type:str]
|
||||||
|
oidc_client_secret: ENC[AES256_GCM,data:ebk0FVtSfq7JbIT+84cigdLg8zfN+4HTfGxlgqLw6hs1H92SFRHQFXO1l3U=,iv:qxa8aqUVoN31PpzAhs6bNMDCM6yPvOT27urIrM1rfo0=,tag:Vo25X8Znw7eh5DNq1eIJEw==,type:str]
|
||||||
|
sops:
|
||||||
|
age:
|
||||||
|
- enc: |
|
||||||
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSArZ1pyMXZ0Y3RFQVZkcTg5
|
||||||
|
aENyemRueXpIM0FaUVhMc2ZyVDRyWWlzK1JzCjA0OTZ0aGJDNVVSM29CY1RzQWJL
|
||||||
|
eVNiSCtMSXdmbEtKeGt1L3NYMy9ibUEKLS0tIGJnU3A4MjVnZ1pCa1lPMnVoM0xo
|
||||||
|
dWs1cVM5ZCszbXp6eFltRVhGbFc0ajQKyCc8lClnSqWUxhNOr1FDCwn5V7nvjxPN
|
||||||
|
7kjQpldseaRbsy+TM5sFQ1w6Acmun9uYjzs8PtmTNaayc/AFfspufA==
|
||||||
|
-----END AGE ENCRYPTED FILE-----
|
||||||
|
recipient: age1smu533f803gmd0jq60s2zaj9zlznajy0ca6rtewd4r37mr2hs3uqsrldfh
|
||||||
|
lastmodified: "2026-07-15T23:22:55Z"
|
||||||
|
mac: ENC[AES256_GCM,data:0YuRxQHfdeKbjJzxHI4iBc7I2KnalNJmybB6bVQxvdRutsxKXW/bu99yqHkD4y/nI66Pi6d7LhrPhhGat3x2c6Drs7QRYVWnZ75thil6yWsOcpH7H1esxEWTP3cpoMzGdS0aF6zwU9H+WDvfm/t1wpeDpJly3eczcPvfbK1joDU=,iv:TgwfpI+ZVLyd2c/PKWsJbCI9yKkADpPPafJ5No0fLks=,tag:nqwQHtZ263CI+fY9iTUAzQ==,type:str]
|
||||||
|
unencrypted_suffix: _unencrypted
|
||||||
|
version: 3.13.2
|
||||||
Reference in New Issue
Block a user