The Flux Operator v2 doesn’t just deploy Flux, it actively manages its lifecycle, treating Flux instances as Kubernetes Custom Resources.

Let’s see it in action. Imagine you want to deploy Flux to manage your Git repository at git@github.com:my-org/my-repo.git.

apiVersion: flux.getup.dev/v1beta1
kind: FluxInstance
metadata:
  name: my-flux-instance
  namespace: flux-system
spec:
  # The Git repository Flux will sync from.
  git:
    url: git@github.com:my-org/my-repo.git
    branch: main
    # Path within the Git repository to sync.
    path: ./clusters/my-cluster
  # The Kubernetes namespace where Flux components will be installed.
  namespace: flux-system
  # Specifies the Kubernetes cluster identity for Flux to use.
  clusterIdentity:
    # A unique name for this cluster.
    name: my-cluster
    # The Kubernetes Service Account Flux will run as.
    serviceAccountName: flux-operator-sa
  # Optional: Specify the Flux version to deploy. Defaults to latest.
  version: v0.36.0

When you kubectl apply -f flux-instance.yaml, the Flux Operator kicks in. It watches for FluxInstance resources. Upon creation, it automates the deployment of all necessary Flux components (Source Controller, Kustomize Controller, Notification Controller, etc.) into the specified namespace. It creates the Kubernetes ServiceAccount, ClusterRole, ClusterRoleBinding, Deployment, and any other required resources. Crucially, it configures these components to point to the git repository defined in the FluxInstance spec.

The Operator continuously monitors the FluxInstance resource. If you update the git.url or git.branch, the Operator will reconcile the Flux components to reflect these changes. It also handles upgrades. If you bump the spec.version, the Operator will update the Flux deployments to the new version, performing rolling updates and ensuring minimal downtime. It watches for the health of the deployed Flux components and can even restart them if they become unhealthy.

The core problem this solves is the manual, error-prone process of bootstrapping and managing Flux. Instead of running a series of flux bootstrap commands and then manually updating deployments and configurations, you declare your desired Flux state in a FluxInstance CR. The Operator then makes the cluster’s reality match that declaration.

Internally, the Flux Operator uses a reconciliation loop. When it detects a FluxInstance resource, it checks if the corresponding Flux components exist and are configured correctly. If not, it creates or updates them. It maintains ownership of the Flux deployments, ensuring they align with the FluxInstance specification. This declarative approach means you don’t need to worry about the imperative steps of installation or upgrade; you simply define what you want.

The clusterIdentity section is more than just metadata; it’s fundamental to how Flux identifies itself within your cluster and how it can be referenced by other Flux components or external systems. The name here is what Flux will use in its internal telemetry and potentially in notifications, while the serviceAccountName dictates the permissions the Flux controller pods will have, which is critical for them to interact with the Kubernetes API to apply your GitOps-managed resources.

One detail often overlooked is how the Operator manages secrets for Git credentials. While the example above uses SSH, if you were to use HTTPS with a token, the Operator expects a Kubernetes Secret to be present in the same namespace as the FluxInstance containing the username and password (or token) fields. The Operator will then reference this secret in the Flux components’ configurations.

The next step in your GitOps journey will likely involve defining how Flux should manage your actual application deployments using Kustomization and HelmRelease custom resources.

Want structured learning?

Take the full Flux course →