Adopt Folly Monitoring CRDs
Use this before wiring folly's
monitoringFluxKustomizationto amonitoring-crdsdependency. It is a one-time, hand-run step against the live folly cluster β one of the few kinds this repo carves out an exception for, because Helm's ownership convention has no git-declared path: Helm decides whether to adopt a pre-existing object by reading labels and annotations off the live object, not off anything aKustomizationcan express. Runbooks/OpenBao Bootstrap is the same shape of exception, for the same reason β a one-time bootstrap action git cannot express, done once and never repeated by drift-correcting machinery.Situation
offsite hit a bootstrap deadlock:
clusters/base/monitoring/opentelemetry-collector-servicemonitor.yamlis a rawServiceMonitor, and Flux server-side dry-runs every object in aKustomizationbefore applying any of them. On a cluster with noServiceMonitorCRD yet, the wholemonitoringKustomizationwas refused β including the kube-prometheus-stackHelmReleasethat would have supplied the CRD. The fix wasclusters/base/monitoring-crds/, aHelmReleasefor theprometheus-operator-crdschart, wired in ahead ofmonitoringviadependsOn(seeclusters/offsite/flux-system/monitoring.yamlandclusters/offsite/flux-system/monitoring-crds.yaml).folly has the identical latent deadlock β a from-scratch rebuild of folly would wedge the same way β but it is not wired to
monitoring-crdsyet, because folly is not building from scratch: its 10monitoring.coreos.comCRDs already exist, installed by kube-prometheus-stack's own bundledcrds/directory. Helm installs a chart'scrds/directory once, without ownership metadata, and never touches it again on upgrade. So folly's live CRDs carry onlyhelm.toolkit.fluxcd.io/name: prom-stackandhelm.toolkit.fluxcd.io/namespace: monitoringlabels β noapp.kubernetes.io/managed-by: Helmlabel, nometa.helm.sh/release-name/meta.helm.sh/release-namespaceannotations.prometheus-operator-crdsis templates-based (charts/crds/templates/, not acrds/directory), so Helm owns what it installs β and Helm refuses to adopt a pre-existing resource that lacks that exact ownership metadata:Unable to continue with install: CustomResourceDefinition "<name>" in namespace "" exists and cannot be imported into the current release: invalid ownership metadata; label validation error: missing key "app.kubernetes.io/managed-by": must be set to "Helm".The stamp has to land before folly's
monitoring-crdsHelmReleaseinstalls, or its first install fails with exactly that error and folly is back to a deadlockedmonitoringKustomizationβ the thing this procedure exists to avoid.
Preconditions
folly's live CRDs are the 10 under
monitoring.coreos.com:alertmanagerconfigs,alertmanagers,podmonitors,probes,prometheusagents,prometheuses,prometheusrules,scrapeconfigs,servicemonitors,thanosrulers.The release name and namespace below (
prometheus-operator-crds/flux-system) must matchclusters/base/monitoring-crds/prometheus-operator-crds.yaml'smetadata.nameandmetadata.namespaceexactly β that is what offsite's liveHelmReleasealready uses, and Helm's adoption check is an exact match, not a prefix or a rename-tolerant one.Confirm no
monitoring-crdsHelmReleaseexists on folly yet (flux --context folly get helmrelease -A | grep monitoring-crdsreturns nothing). If one already exists, this procedure does not apply β the adoption already happened or is mid-flight.
Stamp ownership on the live CRDs
One-time, by hand, against the live folly cluster. This is metadata only β it does not change any CRD's schema, and no workload restarts.
CRDS=( alertmanagerconfigs.monitoring.coreos.com alertmanagers.monitoring.coreos.com podmonitors.monitoring.coreos.com probes.monitoring.coreos.com prometheusagents.monitoring.coreos.com prometheuses.monitoring.coreos.com prometheusrules.monitoring.coreos.com scrapeconfigs.monitoring.coreos.com servicemonitors.monitoring.coreos.com thanosrulers.monitoring.coreos.com ) for crd in "${CRDS[@]}"; do kubectl --context folly label crd "$crd" \ app.kubernetes.io/managed-by=Helm --overwrite kubectl --context folly annotate crd "$crd" \ meta.helm.sh/release-name=prometheus-operator-crds \ meta.helm.sh/release-namespace=flux-system --overwrite done
Verify the stamp
Every CRD should report the label and both annotations back:
for crd in "${CRDS[@]}"; do kubectl --context folly get crd "$crd" -o jsonpath='{.metadata.name}{"\t"}{.metadata.labels.app\.kubernetes\.io/managed-by}{"\t"}{.metadata.annotations.meta\.helm\.sh/release-name}{"\t"}{.metadata.annotations.meta\.helm\.sh/release-namespace}{"\n"}' doneExpected output is 10 lines, each
<crd-name> Helm prometheus-operator-crds flux-system. Any line with an empty column means that CRD's stamp did not take β re-run the label/annotate pair for that name before moving on.
Wire folly to monitoring-crds (separate, reviewed PR)
Only after every CRD verifies clean above. This part is ordinary git-declared state β mirror offsite's wiring exactly, do not improvise a different shape:
Under
clusters/folly/, add amonitoring-crdsdirectory with akustomization.yamlcarryingresources: [../../base/monitoring-crds]β the same shape asclusters/offsite/monitoring-crds/kustomization.yaml.Under
clusters/folly/flux-system/, add amonitoring-crds.yamlKustomizationwithspec.path: ./clusters/folly/monitoring-crdsβ the same shape asclusters/offsite/flux-system/monitoring-crds.yaml.List that new file in
clusters/folly/flux-system/kustomization.yaml'sresources, and adddependsOn: [{name: monitoring-crds}]toclusters/folly/flux-system/monitoring.yamlalongside its existingdependsOn: storage.Merge and let Flux reconcile. Confirm the new
HelmReleaseadopted rather than recreated:flux --context folly get helmrelease prometheus-operator-crds -n flux-system flux --context folly get kustomization monitoring-crds monitoring -n flux-systemAll three should report
Ready. AHelmReleasestuck ininstall retries exhaustedhere means the ownership stamp is incomplete or wrong for at least one CRD β go back to the verify step above rather than deleting and recreating anything.
Rollback
If verification shows a bad stamp, re-run the label/annotate commands for the affected CRD names; both are
--overwriteand idempotent, so re-running the full loop is always safe.If the wiring PR ships and the
monitoring-crdsHelmReleasestill fails ownership validation, the git-side wiring is safe to revert on its own βgit revertthe wiring PR and let Flux reconcile the removal. folly'smonitoringKustomizationreturns to its current unblocked state (nodependsOn: monitoring-crds), and the existing CRDs are untouched either way since nothing in that PR deletes them.The ownership stamp itself is inert until a
HelmReleasenamedprometheus-operator-crdsinflux-systemexists to claim it, so there is normally nothing to undo on the live cluster even if the wiring PR is abandoned. To fully undo the stamp anyway:kubectl --context folly label crd "$crd" app.kubernetes.io/managed-by-andkubectl --context folly annotate crd "$crd" meta.helm.sh/release-name- meta.helm.sh/release-namespace-for each name inCRDS.
Linked references 2
clusters/base/monitoring-crds/ installs the Prometheus Operator CRDs as their own HelmRelease, ahead of monitoring rather than inside it β base/monitoring holds a raw ServiceMonitor, and Flux dry-runs every object in a Kustomization before applying any of them, so a cluster without the CRD already present refuses the whole monitoring Kustomization, including the chart that would supply the CRD. offsite's monitoring Kustomization dependsOn: monitoring-crds for that reason. folly has the same latent ordering problem but is not wired to monitoring-crds yet: its CRDs predate the split and carry no Helm ownership metadata for prometheus-operator-crds to adopt β see Runbooks/Adopt Folly Monitoring CRDs.
Runbooks/Adopt Folly Monitoring CRDs β stamp Helm ownership metadata onto folly's pre-existing Prometheus Operator CRDs before wiring monitoring-crds