diff --git a/stacks/authentik/modules/authentik/main.tf b/stacks/authentik/modules/authentik/main.tf index 798e905b..92b1f132 100644 --- a/stacks/authentik/modules/authentik/main.tf +++ b/stacks/authentik/modules/authentik/main.tf @@ -29,6 +29,7 @@ resource "kubernetes_namespace" "authentik" { labels = { tier = var.tier "resource-governance/custom-quota" = "true" + "keel.sh/enrolled" = "true" } } lifecycle { diff --git a/stacks/kyverno/modules/kyverno/keel-annotations.tf b/stacks/kyverno/modules/kyverno/keel-annotations.tf index c729de9b..10d9d42c 100644 --- a/stacks/kyverno/modules/kyverno/keel-annotations.tf +++ b/stacks/kyverno/modules/kyverno/keel-annotations.tf @@ -74,35 +74,49 @@ resource "kubernetes_manifest" "policy_inject_keel_annotations" { # - cloudflared, headscale, wireguard, xray: VPN/tunnel critical # - infra-maintenance: cluster utilities # - # 2026-05-17 ENROLLMENT EXPANSION: removed 15 namespaces from - # the exclude list per explicit user decision — auto-updates - # are now allowed in monitoring, mailserver, vault, - # descheduler, metrics-server, traefik, technitium, crowdsec, - # redis, reverse-proxy, reloader, headscale, wireguard, xray, - # cloudflared. The `force + match-tag` pairing limits each to - # digest-only watches under the deployment's CURRENT tag - # string — no tag-switching, just rolls on upstream digest - # changes for the pinned tag. A few are on floating tags - # (sclevine/wg:latest, teddysun/xray, prompve/...:latest, - # nginx:1-alpine, redis:8-alpine, error-pages:3); those will - # roll whenever upstream pushes. Acceptable risk — the user - # has alerts in place to catch regressions. + # 2026-05-17 ENROLLMENT EXPANSION (final round): removed an + # additional 9 namespaces from the exclude list per explicit + # user decision (auto-updates now allowed in authentik, + # kyverno, metallb-system, external-secrets, proxmox-csi, + # nfs-csi, vpa, sealed-secrets, infra-maintenance), plus + # aiostreams + woodpecker which were unenrolled by namespace + # label only. The `force + match-tag` pairing limits each + # workload to digest-only watches under the deployment's + # CURRENT tag string — no tag-switching, just rolls on + # upstream digest changes for that pinned tag. + # + # Risks to monitor (worth catching regressions on): + # - kyverno: cluster admission engine. `forceFailurePolicyIgnore` + # keeps the cluster admitting pods if Kyverno is down, and + # the admission controller runs 2 replicas, so a bad-digest + # roll can be recovered from by deleting the bad pod. + # - nfs-csi + proxmox-csi: CSI plugins. We pinned the helm + # chart versions today (commit 128cfbbc for nfs-csi); Keel + # tracks the image's digest under the CURRENT tag — if + # upstream re-pushes a patch under the same tag, Keel rolls. + # - external-secrets + sealed-secrets: cluster bootstrappers. + # Multi-replica + tightly-versioned upstream. + # - metallb-system: networking critical path. Speaker is a + # DaemonSet, controller has 1 replica — a bad roll can + # briefly flap LB IPs. + # - authentik: 2026-05-17 incident bit us when minor bump + # 2026.2.2 → 2026.2.3 broke pgbouncer connections. With + # match-tag=true, digest changes under the same tag string + # are rare (upstream stable patch repushes are uncommon). + # If they happen we get rolled; restore via helm rollback. + # + # Remaining exclusions (7) are irreducible: keel itself, + # calico-system + tigera-operator (operator-managed), + # cnpg-system + dbaas (state-coupled), nvidia (pinned to + # 570.195.03 until NVIDIA ships ubuntu26.04 images per + # code-8vr0), kube-system (k8s built-ins). namespaces = [ "keel", "calico-system", - "authentik", "cnpg-system", "dbaas", - "kyverno", - "metallb-system", - "external-secrets", - "proxmox-csi", - "nfs-csi", "nvidia", "kube-system", - "vpa", - "sealed-secrets", - "infra-maintenance", "tigera-operator", ] } diff --git a/stacks/kyverno/modules/kyverno/main.tf b/stacks/kyverno/modules/kyverno/main.tf index cc5fd890..0a91ccef 100644 --- a/stacks/kyverno/modules/kyverno/main.tf +++ b/stacks/kyverno/modules/kyverno/main.tf @@ -4,6 +4,7 @@ resource "kubernetes_namespace" "kyverno" { name = "kyverno" labels = { "istio-injection" : "disabled" + "keel.sh/enrolled" = "true" } } lifecycle { diff --git a/stacks/metallb/modules/metallb/main.tf b/stacks/metallb/modules/metallb/main.tf index 18955bd3..f67cb6c2 100644 --- a/stacks/metallb/modules/metallb/main.tf +++ b/stacks/metallb/modules/metallb/main.tf @@ -4,7 +4,8 @@ resource "kubernetes_namespace" "metallb" { metadata { name = "metallb-system" labels = { - app = "metallb" + app = "metallb" + "keel.sh/enrolled" = "true" } } lifecycle { diff --git a/stacks/nfs-csi/modules/nfs-csi/main.tf b/stacks/nfs-csi/modules/nfs-csi/main.tf index d030be2f..c3ab4b79 100644 --- a/stacks/nfs-csi/modules/nfs-csi/main.tf +++ b/stacks/nfs-csi/modules/nfs-csi/main.tf @@ -6,6 +6,7 @@ resource "kubernetes_namespace" "nfs_csi" { name = "nfs-csi" labels = { tier = var.tier + "keel.sh/enrolled" = "true" } } lifecycle { diff --git a/stacks/proxmox-csi/modules/proxmox-csi/main.tf b/stacks/proxmox-csi/modules/proxmox-csi/main.tf index e27d6410..b4e08069 100644 --- a/stacks/proxmox-csi/modules/proxmox-csi/main.tf +++ b/stacks/proxmox-csi/modules/proxmox-csi/main.tf @@ -4,6 +4,7 @@ resource "kubernetes_namespace" "proxmox_csi" { labels = { tier = var.tier "resource-governance/custom-quota" = "true" + "keel.sh/enrolled" = "true" } } lifecycle { diff --git a/stacks/sealed-secrets/modules/sealed-secrets/main.tf b/stacks/sealed-secrets/modules/sealed-secrets/main.tf index d1ac8e4a..81340bda 100644 --- a/stacks/sealed-secrets/modules/sealed-secrets/main.tf +++ b/stacks/sealed-secrets/modules/sealed-secrets/main.tf @@ -8,6 +8,7 @@ resource "kubernetes_namespace" "sealed_secrets" { name = "sealed-secrets" labels = { tier = var.tier + "keel.sh/enrolled" = "true" } } lifecycle { diff --git a/stacks/servarr/aiostreams/main.tf b/stacks/servarr/aiostreams/main.tf index f85f3681..df90eec9 100644 --- a/stacks/servarr/aiostreams/main.tf +++ b/stacks/servarr/aiostreams/main.tf @@ -8,6 +8,7 @@ resource "kubernetes_namespace" "aiostreams" { name = "aiostreams" labels = { "istio-injection" : "disabled" + "keel.sh/enrolled" = "true" } } lifecycle { diff --git a/stacks/vpa/modules/vpa/main.tf b/stacks/vpa/modules/vpa/main.tf index 6f1e7ff3..dd73540a 100644 --- a/stacks/vpa/modules/vpa/main.tf +++ b/stacks/vpa/modules/vpa/main.tf @@ -9,6 +9,7 @@ resource "kubernetes_namespace" "vpa" { name = "vpa" labels = { tier = var.tier + "keel.sh/enrolled" = "true" } } }