nextcloud: disable Keel auto-upgrades

Keel bumped library/nextcloud :32.0.3-apache → :32.0.9-apache on
2026-05-26 19:42 UTC. The new image needs `occ upgrade` to migrate
the DB schema, which Keel does not run, so Nextcloud landed in
maintenance mode (needsDbUpgrade=true) and stayed there for ~22h —
external probes saw 503, ExternalAccessDivergence kept firing.

Disable Keel for this workload:
- Drop the `keel.sh/enrolled=true` label from the namespace so
  Kyverno's `inject-keel-annotations` policy no longer matches.
- Layer `keel.sh/policy=never` label + annotation onto the
  Helm-managed Deployment via `kubernetes_labels` /
  `kubernetes_annotations` (the chart at 8.8.1 doesn't expose
  Deployment-level commonLabels/commonAnnotations). Keel reads the
  annotation; the label is defense-in-depth for the Kyverno
  exclude rule should the namespace ever get re-enrolled.

Verified: Keel logged `image no longer tracked, removing watcher`
within seconds of the annotation landing, and `tg plan` is clean.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Viktor Barzin 2026-05-27 18:37:05 +00:00
parent d72c7169c0
commit ee159b02ba

View file

@ -30,7 +30,14 @@ resource "kubernetes_namespace" "nextcloud" {
tier = local.tiers.edge
"resource-governance/custom-limitrange" = "true"
"resource-governance/custom-quota" = "true"
"keel.sh/enrolled" = "true"
# Keel disabled for nextcloud: the 2026-05-26 Keel-driven bump
# 32.0.3-apache 32.0.9-apache left the pod in maintenance mode
# (needsDbUpgrade=true) for ~22h because Keel doesn't run
# `occ upgrade` after rolling the image. Defense-in-depth:
# (a) namespace not enrolled here, (b) workload carries the
# `keel.sh/policy=never` label + annotation below so even if the
# ns label gets re-added, Kyverno excludes this Deployment.
# "keel.sh/enrolled" = "true"
}
}
lifecycle {
@ -39,6 +46,41 @@ resource "kubernetes_namespace" "nextcloud" {
}
}
# Workload-level Keel opt-out (see namespace comment above).
# Keel reads the ANNOTATION `keel.sh/policy` (it's what un-tracks the
# image watcher); the LABEL exists for the Kyverno exclude rule in
# `inject-keel-annotations` (defense-in-depth in case the namespace
# label gets re-added later). Both are set via these helper resources
# because the nextcloud chart 8.8.1 doesn't expose Deployment-level
# commonLabels / commonAnnotations.
resource "kubernetes_labels" "nextcloud_keel_optout" {
api_version = "apps/v1"
kind = "Deployment"
metadata {
name = "nextcloud"
namespace = kubernetes_namespace.nextcloud.metadata[0].name
}
labels = {
"keel.sh/policy" = "never"
}
force = true
depends_on = [helm_release.nextcloud]
}
resource "kubernetes_annotations" "nextcloud_keel_optout" {
api_version = "apps/v1"
kind = "Deployment"
metadata {
name = "nextcloud"
namespace = kubernetes_namespace.nextcloud.metadata[0].name
}
annotations = {
"keel.sh/policy" = "never"
}
force = true
depends_on = [helm_release.nextcloud]
}
resource "kubernetes_manifest" "external_secret" {
manifest = {
apiVersion = "external-secrets.io/v1beta1"