From bc714755ea9c89c2522c78c7a222cc8cfd529a5b Mon Sep 17 00:00:00 2001 From: Viktor Barzin Date: Sat, 16 May 2026 23:27:27 +0000 Subject: [PATCH] kyverno: add mutateExistingOnPolicyUpdate=true so existing workloads get annotated Before this, the inject-keel-annotations policy only fired on admission events. Workloads that existed BEFORE their namespace got labeled keel.sh/enrolled=true never received the annotation, so Keel didn't watch them. Live state was 30 of 226 workloads auto-updating. With mutateExistingOnPolicyUpdate=true and the required mutate.targets block, Kyverno's BackgroundScan controller applies the mutate to existing matching Deployments/StatefulSets/DaemonSets on policy update. Co-Authored-By: Claude Opus 4.7 --- .../kyverno/modules/kyverno/keel-annotations.tf | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/stacks/kyverno/modules/kyverno/keel-annotations.tf b/stacks/kyverno/modules/kyverno/keel-annotations.tf index 6a9089cf..aa7b3780 100644 --- a/stacks/kyverno/modules/kyverno/keel-annotations.tf +++ b/stacks/kyverno/modules/kyverno/keel-annotations.tf @@ -30,7 +30,14 @@ resource "kubernetes_manifest" "policy_inject_keel_annotations" { } } spec = { - background = true + # Retroactively mutate workloads that existed BEFORE their namespace + # got the keel.sh/enrolled=true label. Without this, Kyverno only + # fires on admission events, so old workloads stay unannotated and + # Keel doesn't watch them. With this flag, Kyverno's BackgroundScan + # controller applies the mutate on existing matching resources when + # the policy is created or updated. + mutateExistingOnPolicyUpdate = true + background = true rules = [{ name = "add-keel-annotations" match = { @@ -69,6 +76,13 @@ resource "kubernetes_manifest" "policy_inject_keel_annotations" { ] } mutate = { + # Required when mutateExistingOnPolicyUpdate=true — tells the + # background controller which existing resources to mutate. + targets = [ + { apiVersion = "apps/v1", kind = "Deployment" }, + { apiVersion = "apps/v1", kind = "StatefulSet" }, + { apiVersion = "apps/v1", kind = "DaemonSet" }, + ] patchStrategicMerge = { metadata = { annotations = {