Uninstall
Three scopes, from the smallest.
One module
Section titled “One module”Set kube.<module>.enabled = false and apply
(Enable a module). Turn crossplane off
last: the roles it created for other modules stay otherwise.
The socle, keeping the cluster
Section titled “The socle, keeping the cluster”-
Wait for every module’s
ResourceSetto be Ready, if you just turned one on. -
Destroy the bootstrap module:
Terminal window tofu destroy -target=module.socle.module.socle
flux-system is then left with no ResourceSet, FluxInstance or
Deployment, and no module namespace remains (28 s on floci, 2026-09-30).
Under the hood
The releases go in reverse: the envelope, the Flux instance, the operator,
then on aws the EKS add-ons and CoreDNS, and on aws and azure Cilium. The
socle Kustomization’s deletionPolicy: WaitForTermination holds the
envelope until every catalog ResourceSet is finalized, so the operator is
never removed with work left
(Uninstall order). The
operator uninstalls from the inventory of its last completed reconcile,
hence step 1. CI asserts the empty result on every run (the destroyed
suite).
Everything
Section titled “Everything”tofu destroyThe releases go before the cluster, which needs the API. If the runner can no
longer reach it (it left cluster_endpoint_public_access_cidrs, say), drop
the releases from the state first:
tofu state rm module.socle.module.socletofu destroyWhat is left behind, by design
Section titled “What is left behind, by design”| What | Why | How to remove it |
|---|---|---|
| The Gateway API CRDs | deleting a CRD deletes every Gateway and route | by hand once unused, or with the cluster |
The CRDs of external_secrets, keda, velero, crossplane, argocd_image_updater | they hold your objects | as above |
Module roles, when crossplane went first | nothing is left to delete them | delete the roles under /socle/<cluster>/ in IAM |
| Velero’s bucket | Crossplane may not delete a bucket of data | in the cloud, once its backups are not needed |
A pending Velero Restore | its finalizer holds the namespace | delete the Restore (Restore a backup) |
ImageUpdater objects in argocd, once argocd_image_updater is off | their finalizer holds them, and the argocd namespace, with no controller to release it | delete them before turning the module off, or release them: kubectl -n argocd patch imageupdater <name> --type merge -p '{"metadata":{"finalizers":[]}}' |
| A mirror’s pull secret | flux-system outlives the operator’s release | with the cluster |