feat(phase0): bootstrap External Secrets Operator and fix helmfile dual-ownership
Phase 0 groundwork for helmfile→ArgoCD migration: 1. Remove 3 bootstrap releases from helmfile (cert-manager, reloader, ingress-nginx) — already managed by terraform/bootstrap-releases.tf; eliminates dual-ownership 2. Bootstrap ESO (External Secrets Operator) as TF-managed release — required for all ExternalSecret resources in phases 1-3 — added to bootstrap-releases.tf + helm-repositories.tf 3. Create ClusterSecretStore connecting ESO to Vault (K8s auth) — enables per-namespace/per-release secret injection — vault config documented in docs/PHASE0-ESO-VAULT-SETUP.md (manual setup) 4. Fix argocd-bootstrap.tf CA cert copy: use jq instead of sed for cleaner metadata handling Changes: - helmfile.yaml.gotmpl: remove cert-manager/reloader/ingress-nginx blocks - terraform/bootstrap-releases.tf: add external-secrets release - terraform/helm-repositories.tf: add external-secrets Helm repo - k8s/external-secrets/clustersecretstore.yaml: ESO→Vault ClusterSecretStore - k8s/argocd/apps/0-wave-0.yaml: stub wave 0 applications (schema fix, rewrite pending Phase 1) - docs/PHASE0-ESO-VAULT-SETUP.md: manual ESO-Vault auth setup procedure Next: Phase 1 will incrementally rewrite ArgoCD Applications + migrate helmfile releases. Co-Authored-By: Claude Haiku 4.5 <[email protected]>
This commit is contained in:
co-authored by
Claude Haiku 4.5
parent
23ec31bd6d
commit
e7f3409d0f
+3
-126
@@ -46,134 +46,11 @@ repositories:
|
||||
- name: cnpg
|
||||
url: https://cloudnative-pg.github.io/charts
|
||||
|
||||
# ── cert-manager ─────────────────────────────────────────────────────────────
|
||||
# ── Bootstrap Releases (managed by Terraform) ────────────────────────────────────
|
||||
# cert-manager, reloader, ingress-nginx, and cilium are bootstrap-managed by
|
||||
# terraform/bootstrap-releases.tf — do NOT add them here, avoid dual-ownership.
|
||||
|
||||
releases:
|
||||
- name: cert-manager
|
||||
namespace: cert-manager
|
||||
createNamespace: true
|
||||
chart: jetstack/cert-manager
|
||||
version: "~v1"
|
||||
values:
|
||||
- k8s/cert-manager/cert-manager-values.yaml
|
||||
set:
|
||||
# CRDs must be installed by the chart — avoids a separate kubectl apply step
|
||||
- name: crds.enabled
|
||||
value: true
|
||||
hooks:
|
||||
- events: ["postsync"]
|
||||
command: bash
|
||||
args:
|
||||
- -c
|
||||
- |
|
||||
# Wait for cert-manager webhooks to be ready before applying CRD instances.
|
||||
# Without this, ClusterIssuer/Certificate creation races the webhook and fails.
|
||||
kubectl rollout status deploy/cert-manager -n cert-manager --timeout=120s
|
||||
kubectl rollout status deploy/cert-manager-webhook -n cert-manager --timeout=120s
|
||||
|
||||
kubectl apply -f - <<'EOF'
|
||||
# Phase 2a — bootstrap issuer (selfSigned) used only to sign the CA cert.
|
||||
# Never referenced by ingresses — its sole job is to sign homelab-ca below.
|
||||
apiVersion: cert-manager.io/v1
|
||||
kind: ClusterIssuer
|
||||
metadata:
|
||||
name: selfsigned-bootstrap
|
||||
spec:
|
||||
selfSigned: {}
|
||||
---
|
||||
# Phase 2b — the cluster CA certificate.
|
||||
# cert-manager stores the signed cert + key in homelab-ca-secret.
|
||||
# isCA: true marks it so it can sign other certs.
|
||||
# 10-year lifetime; renewBefore triggers 30 days early.
|
||||
apiVersion: cert-manager.io/v1
|
||||
kind: Certificate
|
||||
metadata:
|
||||
name: homelab-ca
|
||||
namespace: cert-manager
|
||||
spec:
|
||||
isCA: true
|
||||
commonName: homelab-ca
|
||||
secretName: homelab-ca-secret
|
||||
duration: 87600h
|
||||
renewBefore: 720h
|
||||
privateKey:
|
||||
algorithm: ECDSA
|
||||
size: 256
|
||||
issuerRef:
|
||||
name: selfsigned-bootstrap
|
||||
kind: ClusterIssuer
|
||||
group: cert-manager.io
|
||||
---
|
||||
# Phase 2c — the real issuer all ingresses reference.
|
||||
# Reads the CA cert+key from homelab-ca-secret and signs per-hostname certs.
|
||||
# Annotate any ingress with: cert-manager.io/cluster-issuer: homelab-ca
|
||||
apiVersion: cert-manager.io/v1
|
||||
kind: ClusterIssuer
|
||||
metadata:
|
||||
name: homelab-ca
|
||||
spec:
|
||||
ca:
|
||||
secretName: homelab-ca-secret
|
||||
EOF
|
||||
|
||||
# ── Stakater Reloader ─────────────────────────────────────────────────────────
|
||||
# Watches Deployments for secret.reloader.stakater.com/reload and
|
||||
# configmap.reloader.stakater.com/reload annotations, then triggers a rolling
|
||||
# restart whenever the named Secret or ConfigMap is updated (e.g. cert-manager
|
||||
# renewing a TLS cert, or homelab-ca rotating). This replaces the need for
|
||||
# manual `kubectl rollout restart` on cert renewal.
|
||||
|
||||
- name: reloader
|
||||
namespace: reloader
|
||||
createNamespace: true
|
||||
chart: stakater/reloader
|
||||
version: "~1"
|
||||
|
||||
# Pod Disruption Budgets applied after reloader (ensures all namespaces exist)
|
||||
hooks:
|
||||
- events: ["postsync"]
|
||||
command: bash
|
||||
args:
|
||||
- -c
|
||||
- kubectl apply -f k8s/base/poddisruptionbudgets.yaml
|
||||
|
||||
# ── Ingress ───────────────────────────────────────────────────────────────────
|
||||
|
||||
- name: ingress-nginx
|
||||
namespace: ingress-nginx
|
||||
createNamespace: true
|
||||
chart: ingress-nginx/ingress-nginx
|
||||
values:
|
||||
- k8s/ingress/nginx-values.yaml
|
||||
# ServiceMonitor enabled in nginx-values.yaml requires the Prometheus Operator
|
||||
# CRDs, which the prometheus release installs — must apply after it.
|
||||
needs:
|
||||
- monitoring/prometheus
|
||||
hooks:
|
||||
- events: ["presync"]
|
||||
command: bash
|
||||
args:
|
||||
- -c
|
||||
- |
|
||||
bash k8s/base/namespace-setup.sh ingress-nginx
|
||||
# LB-IPAM pool must exist before any LoadBalancer service is created,
|
||||
# otherwise services stay <pending>. Apply it here as the first hook.
|
||||
kubectl apply -f k8s/cilium/lb-ipam-pool.yaml
|
||||
kubectl apply -f k8s/coredns/coredns-configmap.yaml
|
||||
kubectl apply -f k8s/coredns/coredns-deployment.yaml
|
||||
kubectl rollout restart deployment/coredns -n kube-system
|
||||
kubectl rollout status deployment/coredns -n kube-system --timeout=60s
|
||||
# Wildcard TLS cert — must exist before nginx starts so it can read the secret.
|
||||
# cert-manager issues it in the ingress-nginx namespace; wait until Ready.
|
||||
kubectl apply -f k8s/ingress/wildcard-cert.yaml
|
||||
kubectl wait certificate homelab-tls -n ingress-nginx \
|
||||
--for=condition=Ready --timeout=120s
|
||||
- events: ["postsync"]
|
||||
command: kubectl
|
||||
args:
|
||||
- apply
|
||||
- -f
|
||||
- k8s/ingress/ingress.yaml
|
||||
|
||||
# ── CloudNativePG (centralized database) ──────────────────────────────────────
|
||||
# Single HA cluster (1 primary + 2 replicas) serving Authentik + story-crater-backend.
|
||||
|
||||
Reference in New Issue
Block a user