1. See what you have today
The example is a Flux fleet in confighub/examples, with 46 objects across these directories.
| Directory | Files |
|---|---|
apps/ | 9 |
clusters/ | 13 |
image-automation/ | 4 |
infrastructure/ | 8 |
tenants/ | 8 |
Each cluster's directory names the layers it runs, the layers have overlays per environment, and image automation writes new tags into the dev overlay of the app.
2. See what ConfigHub would hold
The plan reads all of it and says what ConfigHub would hold. It runs nothing and changes no cluster.
$ cub flux plan . --require Healthy
Flux fleet: 3 clusters, 4 layers, 10 variants
Read 46 objects
Clusters, one stage each, in order: dev-1 (clusters/dev), staging-1 (clusters/staging), prod-1 (clusters/prod)
Reconcile order (dependsOn): infrastructure -> apps, tenants -> image-automation
infrastructure
base flux-infrastructure-base from gitops/flux/expert-fleet/infrastructure/base
helm edge-router: chart edge-router 2.4.x from HelmRepository platform-charts
stage dev
dev-1 variant flux-infrastructure-dev-1 -> Target flux-targets/dev-1
Kustomization flux-system/infrastructure, path gitops/flux/expert-fleet/infrastructure/dev
label environment=dev
stage staging
staging-1 variant flux-infrastructure-staging-1 -> Target flux-targets/staging-1
Kustomization flux-system/infrastructure, path gitops/flux/expert-fleet/infrastructure/staging
label environment=staging
HelmRelease/edge-router replace /spec/values/replicaCount = 2
stage prod
prod-1 variant flux-infrastructure-prod-1 -> Target flux-targets/prod-1
Kustomization flux-system/infrastructure, path gitops/flux/expert-fleet/infrastructure/prod
label environment=prod
GitRepository/fleet-repo replace /spec/ref/branch = production
HelmRelease/edge-router replace /spec/values/replicaCount = 3
apps (after infrastructure)
base flux-apps-base from gitops/flux/expert-fleet/apps/base/apptique
stage dev
dev-1 variant flux-apps-dev-1 -> Target flux-targets/dev-1
Kustomization flux-system/apps, path gitops/flux/expert-fleet/apps/dev
adds namespace.yaml
namespace apptique-dev
label environment=dev
image nginx 1.27.3-alpine (written by image automation)
Deployment/frontend replace /spec/replicas = 1
substitutes cluster_name=dev-1
substitutes environment=dev
Flux spec.healthChecks[0].namespace = apptique-dev
stage staging
staging-1 variant flux-apps-staging-1 -> Target flux-targets/staging-1
Kustomization flux-system/apps, path gitops/flux/expert-fleet/apps/staging
adds namespace.yaml
namespace apptique-staging
label environment=staging
image nginx 1.27.2-alpine
Deployment/frontend replace /spec/replicas = 2
substitutes cluster_name=staging-1
substitutes environment=staging
Flux spec.healthChecks[0].namespace = apptique-staging
stage prod
prod-1 variant flux-apps-prod-1 -> Target flux-targets/prod-1
Kustomization flux-system/apps, path gitops/flux/expert-fleet/apps/prod
adds namespace.yaml
namespace apptique-prod
label environment=prod
image nginx 1.26.3-alpine
Deployment/frontend replace /spec/replicas = 4
substitutes cluster_name=prod-1
substitutes environment=prod
Flux spec.healthChecks[0].namespace = apptique-prod
in flight nginx: 1.27.3-alpine on dev-1; 1.27.2-alpine on staging-1; 1.26.3-alpine on prod-1
tenants (after infrastructure)
base flux-tenants-base from gitops/flux/expert-fleet/tenants/base/team-checkout
stage dev
dev-1 variant flux-tenants-dev-1 -> Target flux-targets/dev-1
Kustomization flux-system/tenants, path gitops/flux/expert-fleet/tenants/dev
label environment=dev
GitRepository/team-checkout replace /spec/ref/branch = main
stage staging
staging-1 variant flux-tenants-staging-1 -> Target flux-targets/staging-1
Kustomization flux-system/tenants, path gitops/flux/expert-fleet/tenants/staging
label environment=staging
GitRepository/team-checkout replace /spec/ref/branch = main
stage prod
prod-1 variant flux-tenants-prod-1 -> Target flux-targets/prod-1
Kustomization flux-system/tenants, path gitops/flux/expert-fleet/tenants/prod
label environment=prod
GitRepository/team-checkout replace /spec/ref/branch = production
image-automation (after apps)
base flux-image-automation-base from gitops/flux/expert-fleet/image-automation
stage dev
dev-1 variant flux-image-automation-dev-1 -> Target flux-targets/dev-1
Kustomization flux-system/image-automation, path gitops/flux/expert-fleet/image-automation
adds imagerepository.yaml
adds imagepolicy.yaml
adds imageupdateautomation.yaml
note one cluster uses this layer, so its whole directory is the base
note only on dev-1
Sources
- HelmRepository platform-charts oci://ghcr.io/confighub/charts (gitops/flux/expert-fleet/infrastructure/base/sources/charts.yaml)
- GitRepository fleet-repo https://github.com/confighub/examples (gitops/flux/expert-fleet/infrastructure/base/sources/fleet-repo.yaml)
branch: dev-1 main, staging-1 main, prod-1 production
- GitRepository team-checkout https://github.com/confighub/examples (gitops/flux/expert-fleet/tenants/base/team-checkout/sync.yaml)
branch: dev-1 main, staging-1 main, prod-1 production
Writes to Git by itself
- ImageUpdateAutomation apptique-dev commits to branch main, path gitops/flux/expert-fleet/apps/dev, running on dev-1
Not in Git
- which chart edge-router runs: HelmRelease edge-router pins it to "2.4.x", so helm-controller decides at reconcile time and what runs can change with no change in ConfigHub. Pin one exact version to close that, and to make a flattening verdict possible
- what the HelmReleases in infrastructure render: the charts are pulled at reconcile time
- apps: ${cluster_name}, ${environment}, supplied per cluster by postBuild
Tenants (stay as they are)
- team-checkout/team-checkout runs as ServiceAccount team-checkout, reading GitRepository team-checkout; governed as part of tenants
Bootstrap (stays outside ConfigHub)
- gitops/flux/expert-fleet/clusters/dev/flux-system
- gitops/flux/expert-fleet/clusters/prod/flux-system
- gitops/flux/expert-fleet/clusters/staging/flux-system
Handover (apply will write it as handover.sh; plan runs nothing)
1. keep each layer's Flux Kustomization under its own name and switch its sourceRef to an OCIRepository on the ConfigHub gateway, so Flux keeps its inventory and nothing is reinstalled
2. first prove each variant renders exactly what Git renders today: infrastructure, apps, tenants, image-automation prune, so anything the release lacks is deleted
3. suspend ImageUpdateAutomation apptique-dev: it would commit to Git that no longer deploys; its tag should become a proposed ConfigHub change on that variant
4. GitRepository fleet-repo promotes by branch (dev-1 main, staging-1 main, prod-1 production); after handover the ChangeWorkflow's stages decide, not the branch
5. GitRepository team-checkout promotes by branch (dev-1 main, staging-1 main, prod-1 production); after handover the ChangeWorkflow's stages decide, not the branch
6. leave flux-system alone: flux bootstrap owns it, like the Sveltos management record
Next
cub flux apply . --require Healthy --out ./flux-onboarding
That writes apply.sh, handover.sh and cleanup.sh. It runs nothing.3. See which version runs where
Each row is a cluster, and each column a layer it runs as a variant in ConfigHub.
| Cluster | infrastructure | apps | tenants | image-automation | nginx it runs |
|---|---|---|---|---|---|
| dev-1 | yes | yes | yes | yes | nginx 1.27.3-alpine |
| staging-1 | yes | yes | yes | no | nginx 1.27.2-alpine |
| prod-1 | yes | yes | yes | no | nginx 1.26.3-alpine |
Dev runs the newest version, which image automation wrote there, and staging and prod run older ones, set in their own overlays. In ConfigHub the three clusters are three stages in that order, so a version moves from dev to staging to prod.
4. Try it yourself, with no account
Install cub and the flux plugin as Bring your Flux fleet into ConfigHub shows, first.
# fetch the example at the commit this page was built from
$ git clone https://github.com/confighub/examples.git && git -C examples checkout 7f1b8f2fc849bb6488bc2c58f1469172018fc9dd
$ cd examples/gitops/flux/expert-fleet
# read the plan; it runs nothing
$ cub flux plan . --require Healthy
# write what Flux would run after the handover, and the scripts, to onboard/
$ cub flux apply . --require Healthy --out onboard
See it live in ConfigHub
Everything above runs on your own machine with no account. To see the same example in ConfigHub, load it into your own organization with the commands below.
With your own account
# sign in to your organization
$ cub auth login
# fill ConfigHub with the bases and variants the plan names; it changes no cluster
$ CONFIGHUB_OCI=<gateway> bash onboard/apply.sh
onboard/cleanup.sh takes everything back out. The handover is a separate step in the Flux Guide.
5. Technical notes and disclaimers
- The plan ran on 2026-10-26 with cub v0.9.0 and flux plugin 0.4.1, inside a checkout of the example. The recorded files and their receipt hold every input and output.
- The versions are what the repository says each cluster should run, read from its files. Nothing on this page reads a live cluster.