## Set up Flux Install Flux There are several ways to install Flux. This setup uses the community Helm chart. To install it another way, see the [official Flux documentation](https://fluxcd.io/flux/installation/). Install the chart into your workload cluster: ```console $ helm repo add fluxcd-community https://fluxcd-community.github.io/helm-charts $ helm repo update $ helm install flux2 fluxcd-community/flux2 --namespace flux-system --create-namespace ``` > [!IMPORTANT] > This installation is a starting point, not a production ready configuration. Before deploying to production, follow the [production readiness checklist](/docs/hetzner/apalla/workloads/production/production-readiness-checklist). Also check the component's own documentation for its recommended settings. This brings up the source, kustomize, helm, notification, image automation and image reflector controllers in the `flux-system` namespace. Unlike Argo CD, Flux needs no allow-list of the resource groups it may watch. It only touches the objects a `Kustomization` applies. Install the Flux CLI Run the installation command for your environment: ```console $ curl -s https://fluxcd.io/install.sh | sudo bash ``` ```console $ brew install fluxcd/tap/flux ``` ```powershell title="Powershell" choco install flux ``` You can test if the installation was successful with the `flux --version` command. Verify the installation Flux has no API server and no web UI of its own. There is nothing to port-forward or log in to. Check the controllers and the custom resource definitions instead: ```console $ flux check ► checking prerequisites ✔ Kubernetes 1.36.5 >=1.33.0-0 ► checking version in cluster ✔ distribution: flux-2.9.5 ✔ bootstrapped: false ► checking controllers ✔ helm-controller: deployment ready ✔ kustomize-controller: deployment ready ✔ notification-controller: deployment ready ✔ source-controller: deployment ready ► checking crds ✔ all checks passed ``` Add the Syself Autopilot cluster as a remote target Flux applies to its own cluster by default. To let it manage your Syself Autopilot resources, give it a kubeconfig for the management cluster. Use a scoped kubeconfig, obtained through [Headless access for pipelines](/docs/hetzner/apalla/platform/headless-access). The `gitops` service account it uses is limited to your organization namespace. Do not grant it cluster-admin. Flux only needs to apply your `Cluster` declarations. Store that kubeconfig in a Secret, under the key `value`: ```console $ kubectl create secret generic autopilot-kubeconfig \ --namespace flux-system \ --from-file=value=<./path-to/autopilot/kubeconfig> secret/autopilot-kubeconfig created ``` The key must be named `value`. Flux reads the kubeconfig from that key only. What follows is an example setup. You can operate it in the same way you would any other Flux installation, in accordance with your preferred practices. Add a repository To use your new Flux setup, the first thing you need to do is add a repository. Flux reads from a `GitRepository` object. A private repository also needs a Secret with the credentials. You can create that Secret with the CLI: ```console $ flux create secret git gitops-repo-auth \ --url=https://github.com/your-company/gitops-repo.git \ --username= \ --password= \ --namespace=flux-system ✔ git secret 'gitops-repo-auth' created in 'flux-system' namespace ``` You can also create the Secret declaratively and apply it directly to your cluster. Do not commit it to your GitOps repository, since it contains credentials. If you need to store it in Git, use a sealed secret or an external secret store instead: ```yaml apiVersion: v1 kind: Secret metadata: name: gitops-repo-auth namespace: flux-system stringData: username: mygitusername password: ghp_mytoken type: Opaque ``` Now point a `GitRepository` at the repository and reference that Secret: ```yaml apiVersion: source.toolkit.fluxcd.io/v1 kind: GitRepository metadata: name: gitops-repo namespace: flux-system spec: interval: 1m url: https://github.com/your-company/gitops-repo.git ref: branch: main secretRef: name: gitops-repo-auth ``` You can see all the options for adding a repository in the [Flux documentation](https://fluxcd.io/flux/components/source/gitrepositories/). Create a Kustomization With a repository added, you can tell Flux to apply the manifests it holds to the management cluster. Those manifests include your `Cluster` object itself. Flux therefore syncs the cluster's declaration from Git, which is the pattern described in [Introduction to GitOps](/docs/hetzner/apalla/clusters/gitops/overview). ```yaml apiVersion: kustomize.toolkit.fluxcd.io/v1 kind: Kustomization metadata: name: autopilot-clusters namespace: flux-system spec: interval: 5m path: ./clusters prune: false sourceRef: kind: GitRepository name: gitops-repo kubeConfig: secretRef: name: autopilot-kubeconfig targetNamespace: org- ``` > [!WARNING] > Keep `prune` off for any Kustomization that manages a `Cluster`. With pruning on, deleting a manifest file in Git would delete the running cluster. Tearing a cluster down should be a deliberate, separate action, never a side effect of removing a file. Check that Flux fetched the repository and applied it: ```console $ flux get kustomizations NAME REVISION SUSPENDED READY MESSAGE autopilot-clusters main@sha1:a3d1ca23 False True Applied revision: main@sha1:a3d1ca23 ``` Flux is now fully configured to work with Syself Autopilot. ## Leave the Kubernetes version out of Git Syself Autopilot sets `spec.topology.version` on the `Cluster` object. The value comes from the Cluster Stack release that `spec.topology.classRef.name` points at, and it is rewritten whenever you move the cluster to another release. Leave the field out of your manifest: ```yaml apiVersion: cluster.x-k8s.io/v1beta2 kind: Cluster metadata: name: mycluster namespace: org- spec: topology: classRef: name: hetzner-apalla-1-36-v1 controlPlane: replicas: 3 ``` Flux reports no drift when the field is missing from your manifest, and it needs no configuration to ignore it. It detects drift by sending a server-side apply dry run and comparing the result against the live object. The version Syself Autopilot sets appears on both sides of that comparison, so it is never reported as a difference. The same holds for the topology variables that Syself Autopilot fills in with their defaults. If you do set the version in Git, Syself Autopilot overwrites it with the one the Cluster Stack release expects, and you get no error. To change the Kubernetes version, change `spec.topology.classRef.name` instead, as described in [Upgrade to a new Kubernetes version](/docs/hetzner/apalla/clusters/upgrades/upgrade-to-a-new-kubernetes-version).