Check what Flux would change before it adopts something that is already running
Handing a kubectl-applied add-on or Secret to Flux should change nothing. Two read-only checks prove it: kubectl diff and a server-side dry run under Flux's own field manager. And why you must never print the diff of a Secret.
I had two kinds of things to hand over to Flux: an add-on that was installed
once with kubectl apply, and a handful of Secrets that an Ansible role had been
creating. In both cases the goal is that Flux takes ownership and nothing
changes. You can prove that before you merge anything.
Vendor the manifest, don’t wrap it in a HelmRelease
For an add-on that came from a plain manifest, the lowest-risk move is to commit
that exact manifest, with a kustomization.yaml and a Flux Kustomization
(prune: true, wait: true) next to it. The objects stay identical. A
HelmRelease would have to adopt resources that carry no Helm ownership labels.
Two read-only checks
kubectl diff -f components.yaml
kubectl apply -k path/to/the/kustomization --server-side --dry-run=server \
--field-manager=kustomize-controllerThe first shows any difference against the running objects. The second asks the API server whether Flux, under its own field manager name, could apply the objects without an ownership conflict. For my add-on: no differences, and every object accepted.
Dropping extraManifests from a Talos config doesn’t delete what it deployed
either, so ownership has to move first.
Secrets: use the exit code, not the output
For an encrypted Secret in Git, the equivalent check is
sops -d secret.sops.yaml | kubectl diff --server-side --force-conflicts -f -
echo $?Exit 0 means Flux would change nothing, 1 means there is a difference. A Secret
that was created with kubectl apply differs only in the last-applied
annotation, which Flux drops, and in gaining type: Opaque. That counts as
harmless.
The thing I’d like to have known earlier: don’t print that diff to filter it
afterwards. If the live object has the kubectl.kubernetes.io/last-applied-configuration
annotation, the diff prints the whole base64 data of the Secret inside that one
annotation line. A sed that strips key: value lines doesn’t catch it. Look at
the exit code, or compare hashes.