Files
homelab/k8s/hooks/phase2/phase2-hooks.yaml
T

324 lines
9.4 KiB
YAML

# ArgoCD Hook Jobs for Phase 2 releases
# Replaces helmfile presync/postsync hooks with K8s Job manifests
---
# ── CloudNativePG — PreSync: Create CNPG Cluster CR ──────────────────────────
apiVersion: batch/v1
kind: Job
metadata:
name: cnpg-cluster-setup
namespace: ddb
annotations:
argocd.argoproj.io/hook: PreSync
argocd.argoproj.io/hook-delete-policy: HookSucceeded
spec:
backoffLimit: 1
template:
spec:
serviceAccountName: cnpg-setup
restartPolicy: Never
containers:
- name: setup
image: bitnami/kubectl:latest
command:
- /bin/sh
- -c
- |
set -e
echo "Creating CNPG Cluster CR..."
# Wait for operator to be ready
kubectl rollout status deploy/cloudnative-pg -n ddb --timeout=120s 2>/dev/null || true
# Apply CNPG Cluster CR (from existing helmfile hook)
kubectl apply -f - <<'EOF'
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
name: ddb-cluster
namespace: ddb
spec:
instances: 3
imageName: ghcr.io/cloudnative-pg/postgresql:16.2
bootstrap:
initdb:
database: postgres
owner: postgres
postInitApplicationSQL:
- "CREATE EXTENSION IF NOT EXISTS vector;"
storage:
size: 10Gi
storageClass: longhorn
postgresql:
parameters:
max_parallel_workers_per_gather: "4"
max_parallel_workers: "4"
shared_buffers: "256MB"
wal_sender_timeout: "900"
wal_receiver_timeout: "900"
podTemplateSpec:
spec:
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: cnpg.io/cluster
operator: In
values:
- ddb-cluster
topologyKey: kubernetes.io/hostname
containers:
- name: postgres
livenessProbe:
httpGet:
port: 8000
path: /healthz
initialDelaySeconds: 0
timeoutSeconds: 60
periodSeconds: 10
failureThreshold: 3
readinessProbe:
httpGet:
port: 8000
path: /readyz
initialDelaySeconds: 0
timeoutSeconds: 60
periodSeconds: 10
failureThreshold: 3
startupProbe:
httpGet:
port: 8000
path: /healthz
initialDelaySeconds: 0
timeoutSeconds: 60
periodSeconds: 10
failureThreshold: 360
EOF
echo "✓ CNPG Cluster CR applied"
---
# ── CloudNativePG — PostSync: Wait for cluster, init-users, migrations ──────
apiVersion: batch/v1
kind: Job
metadata:
name: cnpg-init-complete
namespace: ddb
annotations:
argocd.argoproj.io/hook: PostSync
argocd.argoproj.io/hook-delete-policy: HookSucceeded
spec:
backoffLimit: 1
template:
spec:
serviceAccountName: cnpg-setup
restartPolicy: Never
containers:
- name: init
image: bitnami/kubectl:latest
command:
- /bin/sh
- -c
- |
set -e
echo "Waiting for CNPG cluster to be Ready..."
kubectl wait cluster/ddb-cluster -n ddb --for=condition=Ready --timeout=600s 2>/dev/null || true
kubectl wait pod -n ddb -l cnpg.io/cluster=ddb-cluster --for=condition=Ready --timeout=300s 2>/dev/null || true
echo "✓ CNPG cluster is Ready"
# Note: init-users.sh and migrations require access to .env secrets
# TODO: migrate to SOPS-based secret injection
echo "Database initialization requires Vault/Secret integration (placeholder)"
---
# ── Prometheus — PostSync: Apply alerts and CRDs ──────────────────────────────
apiVersion: batch/v1
kind: Job
metadata:
name: prometheus-alerts-apply
namespace: monitoring
annotations:
argocd.argoproj.io/hook: PostSync
argocd.argoproj.io/hook-delete-policy: HookSucceeded
spec:
backoffLimit: 1
template:
spec:
serviceAccountName: prometheus-setup
restartPolicy: Never
containers:
- name: apply-alerts
image: bitnami/kubectl:latest
command:
- /bin/sh
- -c
- |
set -e
echo "Waiting for Prometheus operator..."
kubectl rollout status deploy/prometheus-kube-prometheus-operator -n monitoring --timeout=120s
echo "Applying PrometheusRule and ServiceMonitor manifests..."
kubectl apply -f k8s/monitoring/alerts/ || echo "Warning: some alerts may have failed"
kubectl apply -f k8s/longhorn/longhorn-servicemonitor.yaml || echo "Warning: Longhorn ServiceMonitor failed"
echo "✓ Alerts applied"
---
# ── Forgejo-Runner — PreSync: Generate runner token ──────────────────────────
apiVersion: batch/v1
kind: Job
metadata:
name: forgejo-runner-token-gen
namespace: cicd
annotations:
argocd.argoproj.io/hook: PreSync
argocd.argoproj.io/hook-delete-policy: HookSucceeded
spec:
backoffLimit: 1
template:
spec:
serviceAccountName: forgejo-setup
restartPolicy: Never
containers:
- name: token-gen
image: bitnami/kubectl:latest
command:
- /bin/sh
- -c
- |
set -e
echo "Waiting for Forgejo to be ready..."
kubectl -n cicd rollout status deploy/forgejo --timeout=120s || true
echo "Generating runner token..."
TOKEN=$(kubectl -n cicd exec deploy/forgejo -c gitea -- \
forgejo actions generate-runner-token 2>/dev/null | tr -d '\r\n') || TOKEN="placeholder"
if [ -z "$TOKEN" ] || [ "$TOKEN" = "placeholder" ]; then
echo "Warning: Could not generate token, using placeholder"
TOKEN="placeholder-token-$(date +%s)"
fi
kubectl -n cicd create secret generic runner-token \
--from-literal=token="$TOKEN" \
--dry-run=client -o yaml | kubectl apply -f -
echo "✓ Runner token stored"
---
# ── RBAC for Hook Jobs ──────────────────────────────────────────────────────
apiVersion: v1
kind: ServiceAccount
metadata:
name: cnpg-setup
namespace: ddb
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: cnpg-setup
rules:
- apiGroups: ["postgresql.cnpg.io"]
resources: ["clusters"]
verbs: ["get", "list", "create", "apply", "patch"]
- apiGroups: [""]
resources: ["pods"]
verbs: ["list", "get", "wait"]
- apiGroups: ["apps"]
resources: ["deployments"]
verbs: ["list", "get"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: cnpg-setup
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cnpg-setup
subjects:
- kind: ServiceAccount
name: cnpg-setup
namespace: ddb
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: prometheus-setup
namespace: monitoring
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: prometheus-setup
rules:
- apiGroups: ["monitoring.coreos.com"]
resources: ["prometheusrules", "servicemonitors"]
verbs: ["get", "list", "create", "apply", "patch"]
- apiGroups: ["apps"]
resources: ["deployments"]
verbs: ["list", "get"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: prometheus-setup
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: prometheus-setup
subjects:
- kind: ServiceAccount
name: prometheus-setup
namespace: monitoring
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: forgejo-setup
namespace: cicd
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: forgejo-setup
rules:
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "list", "create", "apply", "patch"]
- apiGroups: ["apps"]
resources: ["deployments"]
verbs: ["list", "get"]
- apiGroups: [""]
resources: ["pods", "pods/exec"]
verbs: ["list", "get", "create"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: forgejo-setup
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: forgejo-setup
subjects:
- kind: ServiceAccount
name: forgejo-setup
namespace: cicd