---
title: Flux Instance CRD
description: Flux Operator API for FluxCD lifecycle management
---
# Flux Instance CRD
**FluxInstance** is a declarative API for the installation, configuration
and automatic upgrade of the Flux distribution.
A single custom resource of this kind can exist in a Kubernetes cluster
with the name `flux` that must be created in the same namespace
where the flux-operator is deployed.
## Example
The following example shows a FluxInstance custom resource that
installs the upstream Flux distribution with all available components,
and configures the flux-operator to automatically upgrade Flux
to the latest stable version:
```yaml
apiVersion: fluxcd.controlplane.io/v1
kind: FluxInstance
metadata:
name: flux
namespace: flux-system
annotations:
fluxcd.controlplane.io/reconcile: "enabled"
fluxcd.controlplane.io/reconcileEvery: "1h"
fluxcd.controlplane.io/reconcileTimeout: "5m"
spec:
distribution:
version: "2.x"
registry: "ghcr.io/fluxcd"
components:
- source-controller
- kustomize-controller
- helm-controller
- notification-controller
- image-reflector-controller
- image-automation-controller
cluster:
type: kubernetes
size: medium
multitenant: false
networkPolicy: true
domain: "cluster.local"
storage:
class: "standard"
size: "10Gi"
commonMetadata:
labels:
app.kubernetes.io/name: flux
kustomize:
patches:
- target:
kind: Deployment
patch: |
- op: replace
path: /spec/template/spec/nodeSelector
value:
kubernetes.io/os: linux
- op: add
path: /spec/template/spec/tolerations
value:
- key: "CriticalAddonsOnly"
operator: "Exists"
```
You can run this example by saving the manifest into `fluxinstance.yaml`.
**1.** Apply the resource on the cluster:
```shell
kubectl apply -f fluxinstance.yaml
```
**2.** Run `kubectl get fluxinstance` to see the status of the resource:
```console
$ kubectl -n flux-system get fluxinstance
NAME AGE READY STATUS REVISION
flux 59s True Reconciliation finished in 52s v2.3.0@sha256:4cc5babdb1279ad0177bf513292deadbfa3f7b7c3da0be7fa53b39ab434f7219
```
**3.** Run `kubectl describe fluxinstance` to see the reconciliation status components, conditions and events:
```console
$ kubectl -n flux-system describe fluxinstance flux
Status:
Components:
Digest: sha256:161da425b16b64dda4b3cec2ba0f8d7442973aba29bb446db3b340626181a0bc
Name: source-controller
Repository: ghcr.io/fluxcd/source-controller
Tag: v1.3.0
Digest: sha256:48a032574dd45c39750ba0f1488e6f1ae36756a38f40976a6b7a588d83acefc1
Name: kustomize-controller
Repository: ghcr.io/fluxcd/kustomize-controller
Tag: v1.3.0
Digest: sha256:a67a037faa850220ff94d8090253732079589ad9ff10b6ddf294f3b7cd0f3424
Name: helm-controller
Repository: ghcr.io/fluxcd/helm-controller
Tag: v1.0.1
Digest: sha256:c0fab940c7e578ea519097d36c040238b0cc039ce366fdb753947428bbf0c3d6
Name: notification-controller
Repository: ghcr.io/fluxcd/notification-controller
Tag: v1.3.0
Digest: sha256:aed795c7a8b85bca93f6d199d5a14bbefaf925ad5aa5316b32a716cfa4070d0b
Name: image-reflector-controller
Repository: ghcr.io/fluxcd/image-reflector-controller
Tag: v0.32.0
Digest: sha256:ab5097213194f3cd9f0e68d8a937d94c4fc7e821f6544453211e94815b282aa2
Name: image-automation-controller
Repository: ghcr.io/fluxcd/image-automation-controller
Tag: v0.38.0
Conditions:
Last Transition Time: 2024-06-03T12:20:57Z
Message: Reconciliation finished in 52s
Observed Generation: 1
Reason: ReconciliationSucceeded
Status: True
Type: Ready
Last Applied Revision: v2.3.0@sha256:4cc5babdb1279ad0177bf513292deadbfa3f7b7c3da0be7fa53b39ab434f7219
Last Attempted Revision: v2.3.0@sha256:4cc5babdb1279ad0177bf513292deadbfa3f7b7c3da0be7fa53b39ab434f7219
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Progressing 6m20s flux-controller Installing revision v2.3.0@sha256:4cc5babdb1279ad0177bf513292deadbfa3f7b7c3da0be7fa53b39ab434f7219
Normal ReconciliationSucceeded 5m9s flux-controller Reconciliation finished in 52s
```
**4.** Run `kubectl logs` on the flux-operator pod to see the reconciliation logs:
```shell
kubectl -n flux-system logs deployment/flux-operator
```
**5.** Run `kubectl events` to see the events generated by the flux-operator:
```shell
kubectl -n flux-system events --for FluxInstance/flux
```
**6.** Run `kubectl delete` to remove the FluxInstance resource and
to uninstall Flux without affecting any Flux-managed workloads:
```shell
kubectl -n flux-system delete FluxInstance/flux
```
## Writing a FluxInstance spec
As with all other Kubernetes config, a FluxInstance needs `apiVersion`,
`kind`, and `metadata` fields. The name of a FluxInstance object must be a
valid [DNS subdomain name](https://kubernetes.io/docs/concepts/overview/working-with-objects/names#dns-subdomain-names).
A FluxInstance also needs a
[`.spec` section](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#spec-and-status).
### Distribution configuration
The `.spec.distribution` field is required and specifies the Flux distribution to install.
Example using the upstream Flux distribution:
```yaml
spec:
distribution:
version: "2.x"
registry: "ghcr.io/fluxcd"
```
#### Distribution version
The `.spec.distribution.version` field is required and specifies the version of the Flux distribution to install.
The version field value must be a valid [semver](https://semver.org/) range or an exact version.
Example using a semver range to configure the automatic upgrade
to the latest Flux minor version:
```yaml
spec:
distribution:
version: "2.x"
```
Example using a semver range to configure the automatic upgrade
to the latest Flux patch version of the `2.3` series:
```yaml
spec:
distribution:
version: "2.3.x"
```
Example using an exact version to install a specific Flux version:
```yaml
spec:
distribution:
version: "2.3.0"
```
#### Distribution registry
The `.spec.distribution.registry` field is required and specifies the container registry
where the Flux distribution images are pulled from.
Example using the upstream Flux distribution registry:
```yaml
spec:
distribution:
version: "2.x"
registry: "ghcr.io/fluxcd"
```
#### Distribution registry mirrors
The `.spec.distribution.variant` field is required, when specifying a third-party
registry where the Flux distribution images are pulled from. This is useful for registry
mirrors, for example in corporate environments.
Valid values are `upstream-alpine`, `enterprise-alpine` and `enterprise-distroless`.
Example using a hypothetical `ghcr.io` mirror:
```yaml
spec:
distribution:
version: "2.x"
registry: "my-ghcr-mirror.io/fluxcd"
variant: "upstream-alpine"
```
Example using a hypothetical mirror of the ControlPlane enterprise registry:
```yaml
spec:
distribution:
version: "2.x"
registry: "my-ghcr-mirror.io/controlplaneio-fluxcd/distroless"
variant: "enterprise-distroless"
```
#### Distribution image pull secret
The `.spec.distribution.imagePullSecret` field is optional and specifies the name of the Kubernetes secret
that contains the credentials to pull the Flux distribution images from a private registry.
Example using the ControlPlane enterprise registry:
```yaml
spec:
distribution:
version: "2.3.x"
registry: "ghcr.io/controlplaneio-fluxcd/distroless"
imagePullSecret: "flux-enterprise-auth"
```
The image pull secret must be created in the same namespace where the FluxInstance is deployed
and must be of type `kubernetes.io/dockerconfigjson`.
Example generating a secret for the ControlPlane enterprise registry:
```sh
kubectl create secret docker-registry flux-enterprise-auth \
--namespace flux-system \
--docker-server=ghcr.io \
--docker-username=flux \
--docker-password=$ENTERPRISE_TOKEN
```
#### Distribution artifact
The `.spec.distribution.artifact` field is optional and specifies the OCI artifact URL
containing the Flux distribution manifests. When specified, the operator will pull the
artifact on a regular interval to determine the latest Flux version available
including CVE patches and hotfixes.
Example using the official distribution artifact:
```yaml
spec:
distribution:
version: "2.x"
registry: "ghcr.io/fluxcd"
artifact: "oci://ghcr.io/controlplaneio-fluxcd/flux-operator-manifests"
```
#### Distribution artifact pull secret
The `.spec.distribution.artifactPullSecret` field is optional and specifies the name of the Kubernetes secret
that contains the credentials to pull the Flux distribution manifests from a private registry.
Example using a private registry:
```yaml
spec:
distribution:
version: "2.3.x"
registry: "ghcr.io/controlplaneio-fluxcd/distroless"
artifact: "oci://private.registry.com/controlplaneio-fluxcd/flux-operator-manifests"
artifactPullSecret: "flux-private-auth"
```
The manifest pull secret must be created in the same namespace where the FluxInstance is deployed
and must be of type `kubernetes.io/dockerconfigjson`.
### Components configuration
The `.spec.components` field is optional and specifies the list of Flux components to install.
When not specified, the operator will install the default set of components: `source-controller`,
`kustomize-controller`, `helm-controller` and `notification-controller`.
The supported components are:
```yaml
spec:
components:
- source-controller
- kustomize-controller
- helm-controller
- notification-controller
- image-reflector-controller
- image-automation-controller
- source-watcher
```
Note that the `source-watcher` component requires Flux v2.7.0 or later.
### Cluster configuration
The `.spec.cluster` field is optional and specifies the Kubernetes cluster configuration.
Example using the OpenShift cluster configuration:
```yaml
spec:
cluster:
type: openshift
size: medium
multitenant: true
multitenantWorkloadIdentity: true
objectLevelWorkloadIdentity: true
tenantDefaultServiceAccount: "flux"
tenantDefaultDecryptionServiceAccount: "flux-decryption"
tenantDefaultKubeConfigServiceAccount: "flux-kubeconfig"
networkPolicy: true
domain: "cluster.local"
```
#### Cluster type
The `.spec.cluster.type` field is optional and specifies the type of the Kubernetes cluster.
This field is used to enable specific configuration for AKS, EKS, GKE and OpenShift clusters.
The supported values are `kubernetes` (default), `openshift`, `azure`, `aws` and `gcp`.
#### Cluster size
The `.spec.cluster.size` field is optional and specifies the size of the Kubernetes cluster.
The size is used to determine the vertical scaling profile for the Flux controllers based on
the number of applications and the deployment frequency.
The supported values are `small`, `medium` and `large` which correspond to the following
configuration for Flux `kustomize-controller` and `helm-controller`:
| Size | Concurrency | CPU limit | Memory limit | Requeue deps |
|------------|-------------|-----------|--------------|--------------|
| **small** | 5 | 1000m | 512Mi | 10s |
| **medium** | 10 | 2000m | 1Gi | 5s |
| **large** | 20 | 3000m | 3Gi | 5s |
For all sizes, the `source-controller` is configured to cache artifacts
and the concurrency is set between 2 and 10.
The `small` size is suitable for edge clusters with limited resources (Raspberry Pi) or
for clusters with tens of apps and moderate deployment frequency.
The `medium` size is suitable for clusters with hundreds of apps, while the `large`
size is for clusters with up to a thousand apps and high deployment frequency.
When Flux manages thousands of apps,
the recommended scaling strategy is to use [sharding](#sharding-configuration).
#### Cluster multitenant
The `.spec.cluster.multitenant` field is optional and specifies whether to enable Flux
[multi-tenancy lockdown](https://fluxcd.io/flux/installation/configuration/multitenancy/).
By default, it is `false` (disabled).
The `.spec.cluster.tenantDefaultServiceAccount` is optional and specifies the default
service account used by Flux when reconciling `Kustomization` and `HelmRelease`
resources found in the tenant namespaces.
#### Cluster workload identity
The workload identity configuration provides fine-grained control over service account
usage across Flux controllers, enabling secure multi-tenant deployments in cloud environments.
##### Object-level workload identity
The `.spec.cluster.objectLevelWorkloadIdentity` field is optional and specifies whether to
enable the object-level workload identity feature gate and RBAC for the Flux controllers.
This feature allows Flux resources to specify their own service accounts via the
`spec.serviceAccountName` field.
Version requirements:
- Flux v2.6.0 and later: Supported for `source-controller`, `kustomize-controller`,
`notification-controller`, `image-reflector-controller`, and `image-automation-controller`
- Flux v2.7.0 and later: Additionally supported for `helm-controller`
Example:
```yaml
spec:
cluster:
objectLevelWorkloadIdentity: true
```
##### Multitenant workload identity
The `.spec.cluster.multitenantWorkloadIdentity` field is optional and enables workload identity
multi-tenancy lockdown. When enabled, Flux controllers will use tenant-specific service accounts
as defaults, preventing cross-tenant access in workload identity scenarios.
Requirements:
- Requires `objectLevelWorkloadIdentity: true`
- Available in Flux v2.7.0 and later
- Designed for cloud environments with workload identity (AWS IRSA, Azure Workload Identity, GCP Workload Identity)
Example:
```yaml
spec:
cluster:
objectLevelWorkloadIdentity: true
multitenantWorkloadIdentity: true
```
##### Service account configuration
When `multitenantWorkloadIdentity` is enabled, you can configure default service accounts
for different controller operations:
- `.spec.cluster.tenantDefaultServiceAccount` (optional): Default service account for
`source-controller`, `notification-controller`, `image-reflector-controller`, and
`image-automation-controller` operations. Defaults to `"default"`. (Also used by
`kustomize-controller` and `helm-controller` for Kubernetes API operations when
[`.spec.cluster.multitenant`](#cluster-multitenant) is set to `true`.)
- `.spec.cluster.tenantDefaultDecryptionServiceAccount` (optional): Default service account
for `kustomize-controller` SOPS decryption operations. Defaults to `"default"`.
- `.spec.cluster.tenantDefaultKubeConfigServiceAccount` (optional): Default service account
for `kustomize-controller` and `helm-controller` remote cluster access via
`spec.kubeConfig.configMapRef`. Defaults to `"default"`.
Complete example:
```yaml
spec:
cluster:
objectLevelWorkloadIdentity: true
multitenantWorkloadIdentity: true
tenantDefaultServiceAccount: "flux-tenant"
tenantDefaultDecryptionServiceAccount: "flux-decryption"
tenantDefaultKubeConfigServiceAccount: "flux-kubeconfig"
```
Use cases:
- **Cloud workload identity**: Each tenant namespace has service accounts bound to cloud IAM roles
- **Secret management**: Different service accounts for decryption operations (e.g. SOPS with cloud KMS)
- **Multi-cluster**: Separate service accounts for accessing remote clusters via cloud IAM
- **Zero-trust**: Prevent controllers from accessing resources outside their intended scope
See the complete workload identity documentation for CNCF Flux
[here](https://fluxcd.io/flux/integrations/).
#### Cluster network policy
The `.spec.cluster.networkPolicy` field is optional and specifies whether to restrict network access
to the Flux namespace from other namespaces. By default, network policy is enabled.
#### Cluster domain
The `.spec.cluster.domain` field is optional and specifies the cluster internal domain name.
By default, the domain is set to `cluster.local`.
### Storage configuration
The `.spec.storage` field is optional and specifies the persistent storage for Flux internal artifacts.
When specified, the operator will create a persistent volume claim named `source-controller` with
the specified storage class and size and mount it to the Flux source-controller `/data` volume.
#### Storage class
The `.spec.storage.class` field is required and specifies the storage class to use for the persistent volume claim.
Example using the standard storage class:
```yaml
spec:
storage:
class: "standard"
size: "10Gi"
```
#### Storage size
The `.spec.storage.size` field is required and specifies the size of the persistent volume claim.
### Sharding configuration
The `.spec.sharding` field is optional and specifies the sharding configuration for the Flux controllers.
Example:
```yaml
spec:
sharding:
key: "sharding.fluxcd.io/key"
shards:
- "shard1"
- "shard2"
storage: persistent
```
For each shard, the operator will create a separate set of controllers, e.g.:
```console
$ kubectl -n flux-system get deployments -l app.kubernetes.io/part-of=flux
NAME
source-controller
source-controller-shard1
source-controller-shard2
kustomize-controller
kustomize-controller-shard1
kustomize-controller-shard2
helm-controller
helm-controller-shard1
helm-controller-shard2
```
Note that only the `source-controller`, `kustomize-controller` and `helm-controller` controllers
support sharding.
To assign a resource to a specific shard, add the `sharding.fluxcd.io/key` label with the shard value,
e.g.: `sharding.fluxcd.io/key: shard1`.
#### Sharding key
The `.spec.sharding.key` field is optional and specifies the sharding key label to use for the Flux controllers.
By default, the key is set to `sharding.fluxcd.io/key`.
#### Shards
The `.spec.sharding.shards` field is required and specifies the list of sharding values to use for the Flux controllers.
### Sharding storage
The `.spec.sharding.storage` field is optional and specifies the storage type to use
for the source-controller shards.
The supported values are `ephemeral` (default) and `persistent`.
When set to `persistent`, the operator will create a persistent volume claim for each shard using
the storage class and size specified in the `.spec.storage` field.
### Common metadata
The `.spec.commonMetadata` field is optional and specifies common metadata to be applied to all Kubernetes resources
part of the Flux instance.
It has two optional fields:
- `labels`: A map used for setting [labels](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/)
on an object. Any existing label will be overridden if it matches with a key in
this map.
- `annotations`: A map used for setting [annotations](https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/)
on an object. Any existing annotation will be overridden if it matches with a key
in this map.
Example common metadata:
```yaml
spec:
commonMetadata:
labels:
app.kubernetes.io/name: flux
annotations:
toolkit.fluxcd.io/tenant: sre-team
```
### Kustomize patches
The `.spec.kustomize.patches` field is optional and specifies the Kustomize patches to apply to the Flux controllers.
Example:
```yaml
spec:
kustomize:
patches:
- target:
kind: Deployment
name: "(kustomize-controller|helm-controller)"
patch: |
- op: replace
path: /spec/template/spec/volumes/0
value:
name: temp
emptyDir:
medium: Memory
```
### Reconciliation configuration
The reconciliation behaviour can be configured using the following annotations:
- `fluxcd.controlplane.io/reconcile`: Enable or disable the reconciliation loop. Default is `enabled`, set to `disabled` to pause the reconciliation.
- `fluxcd.controlplane.io/reconcileEvery`: Set the reconciliation interval. Default is `1h`.
- `fluxcd.controlplane.io/reconcileArtifactEvery`: Set the artifact reconciliation interval. Default is `10m`.
- `fluxcd.controlplane.io/reconcileTimeout`: Set the reconciliation timeout. Default is `5m`.
To trigger an immediate reconciliation, the following annotation can be set to the current timestamp:
- `reconcile.fluxcd.io/requestedAt`: Set to the current timestamp to trigger an immediate reconciliation.
- `reconcile.fluxcd.io/forceAt`: Set to the current timestamp to trigger a forced reconciliation, migrating all Flux resources to their latest API version.
To force a reconciliation with the Flux Operator CLI:
```sh
flux-operator -n flux-system reconcile instance flux --force
```
### Sync configuration
The `.spec.sync` field is optional and specifies the Flux sync configuration.
When set, a Flux source and a Flux Kustomization are generated to sync
the cluster state with the source repository.
The Flux objects are created in the same namespace where the FluxInstance is deployed
using the namespace name as the Flux source and Kustomization name. The naming convention
matches the one used by `flux bootstrap` to ensure compatibility with upstream, and
to allow transitioning a bootstrapped cluster to a FluxInstance managed one.
Sync fields:
- `kind`: The source kind, supported values are `GitRepository`, `OCIRepository` and `Bucket`.
- `url`: The URL of the source repository, can be a Git repository HTTP/S or SSH address, an OCI repository address or a Bucket endpoint.
- `ref`: The source reference, can be a Git ref name e.g. `refs/heads/main`, an OCI tag e.g. `latest` or a Bucket name.
- `path`: The path to the source directory containing the kustomize overlay or plain Kubernetes manifests to sync from.
- `pullSecret`: The name of the Kubernetes secret that contains the credentials to pull the source repository. This field is optional.
- `provider`: The provider name used for OIDC-based authentication.
Supported values are `aws`, `azure` and `gcp` for `OCIRepository`/`Bucket`,
and `azure` or `github` for `GitRepository`. This field is optional.
- `interval`: The sync interval. This field is optional, when not set the default is `1m`.
- `name`: The name of the generated Flux source and Kustomization objects.
This field is optional, when not set the default is the FluxInstance namespace name.
Note that this field is considered immutable, and cannot be changed after the FluxInstance is created.
#### Sync from Git over HTTP/S
Example:
```yaml
spec:
sync:
kind: GitRepository
url: "https://gitlab.com/my-group/my-fleet.git"
ref: "refs/heads/main"
path: "clusters/my-cluster"
pullSecret: "git-token-auth"
```
If the source repository is private, the Kubernetes secret must be created
in the same namespace where the FluxInstance is deployed, and have the following format:
```yaml
apiVersion: v1
kind: Secret
metadata:
name: git-token-auth
namespace: flux-system
type: Opaque
stringData:
username: "git-username"
password: "git-token"
```
To generate the secret with the Flux CLI:
```sh
flux create secret git git-token-auth \
--namespace flux-system \
--url=https://gitlab.com/my-group/my-fleet.git \
--username=git-username \
--password=git-token
```
#### Sync from Git over SSH
Example:
```yaml
spec:
sync:
kind: GitRepository
url: "ssh://git@github.com/my-org/my-fleet.git"
ref: "refs/heads/main"
path: "clusters/my-cluster"
pullSecret: "git-ssh-auth"
```
If the source repository is private, the Kubernetes secret must be created
in the same namespace where the FluxInstance is deployed, and have the following format:
```yaml
apiVersion: v1
kind: Secret
metadata:
name: git-ssh-auth
namespace: flux-system
type: Opaque
stringData:
identity: |
-----BEGIN OPENSSH PRIVATE KEY-----
...
-----END OPENSSH PRIVATE KEY-----
known_hosts: |
github.com ecdsa-sha2-nistp256 AAAA...
```
To generate the secret with the Flux CLI:
```sh
flux create secret git git-ssh-auth \
--namespace flux-system \
--url=ssh://git@github.com/my-org/my-fleet.git \
--private-key-file=my-private.key
```
#### Sync from OCI over HTTP/S
Example:
```yaml
spec:
sync:
kind: OCIRepository
url: "oci://ghcr.io/my-org/my-fleet-manifests"
ref: "latest"
path: "clusters/my-cluster"
pullSecret: "oci-token-auth"
```
If the container registry is private, the Kubernetes secret must be created
in the same namespace where the FluxInstance is deployed, and be of type `kubernetes.io/dockerconfigjson`:
```yaml
apiVersion: v1
kind: Secret
metadata:
name: oci-token-auth
namespace: flux-system
type: kubernetes.io/dockerconfigjson
data:
.dockerconfigjson: "base64-encoded-docker-config"
```
To generate the secret with the Flux CLI:
```sh
flux create secret oci oci-token-auth \
--namespace flux-system \
--url=ghcr.io \
--username=ghcr-username \
--password=ghcr-token
```
#### Sync from S3-compatible storage over HTTP/S
Example:
```yaml
spec:
sync:
kind: Bucket
url: "minio.my-org.com"
ref: "my-bucket-fleet"
path: "clusters/my-cluster"
pullSecret: "bucket-auth"
```
If the Bucket is private, the Kubernetes secret must be created
in the same namespace where the FluxInstance is deployed, and have the following format:
```yaml
apiVersion: v1
kind: Secret
metadata:
name: bucket-auth
namespace: flux-system
type: Opaque
stringData:
accesskey: "my-accesskey"
secretkey: "my-secretkey"
```
### Resources migration configuration
The `.spec.migrateResources` field is optional and instructs the operator to migrate
the Flux custom resources stored in Kubernetes etcd to the latest API version as
specified in the Flux CRDs. The migration runs after the Flux distribution is upgraded
from a minor version to another and only when a new API version is introduced.
By default, the field value is set to `true`. Note that disabling the migration may
result in upgrade failures due to deprecated API versions being removed in future Flux releases.
## FluxInstance Status
### Conditions
A FluxInstance enters various states during its lifecycle, reflected as Kubernetes Conditions.
It can be [reconciling](#reconciling-fluxinstance) while applying the resources on the cluster,
it can be [ready](#ready-fluxinstance),
it can [fail during reconciliation](#failed-fluxinstance),
or it can [fail due to misconfiguration](#stalled-fluxinstance).
The FluxInstance API is compatible with the **kstatus** specification,
and reports `Reconciling` and `Stalled` conditions where applicable to
provide better (timeout) support to solutions polling the Kustomization to
become `Ready`.
#### Reconciling FluxInstance
The flux-operator marks a FluxInstance as _reconciling_ when it starts
the reconciliation of the same. The Condition added to the FluxInstance's
`.status.conditions` has the following attributes:
- `type: Reconciling`
- `status: "True"`
- `reason: Progressing` | `reason: ProgressingWithRetry`
The Condition `message` is updated during the course of the reconciliation to
report the action being performed at any particular moment such as
building manifests, detecting drift, etc.
The `Ready` Condition's `status` is also marked as `Unknown`.
#### Ready FluxInstance
The flux-operator marks a FluxInstance as _ready_ when the Flux configuration was
built and applied on the cluster and all health checks are observed to be passing.
When the FluxInstance is "ready", the flux-operator sets a Condition with the
following attributes in the FluxInstance’s `.status.conditions`:
- `type: Ready`
- `status: "True"`
- `reason: ReconciliationSucceeded`
#### Failed FluxInstance
The flux-operator may get stuck trying to reconcile and apply a
FluxInstance without completing. This can occur due to some of the following factors:
- The distribution artifact is not accessible.
- The distribution version is not available.
- The kustomization of the Flux components fails to build.
- Garbage collection fails.
- Running health checks fails.
When this happens, the flux-operator sets the `Ready` Condition status to False
and adds a Condition with the following attributes to the FluxInstance’s
`.status.conditions`:
- `type: Ready`
- `status: "False"`
- `reason: ArtifactFailed | BuildFailed | HealthCheckFailed | ReconciliationFailed`
The `message` field of the Condition will contain more information about why
the reconciliation failed.
While the FluxInstance has one or more of these Conditions, the flux-operator
will continue to attempt a reconciliation with an
exponential backoff, until it succeeds and the FluxInstance is marked as [ready](#ready-fluxinstance).
#### Stalled FluxInstance
The flux-operator may fail the reconciliation of a FluxInstance object terminally due
to a misconfiguration. When this happens, the flux-operator adds the `Stalled` Condition
to the FluxInstance’s `.status.conditions` with the following attributes:
- `type: Stalled`
- `status: "True"`
- `reason: BuildFailed`
Misconfigurations can include:
- The build of the Flux manifests fails. In this case the condition reason is `BuildFailed`.
When this happens, the flux-operator will not attempt to reconcile the FluxInstance
until the misconfiguration is fixed. The `Ready` Condition status is also set to `False`.
### History
With `.status.history` the operator tracks the reconciliation attempts over time, providing insights
into the FluxInstance's behavior which can be used for audit, anomaly detection and debugging purposes.
The history is stored as a list of snapshots, ordered by last reconciliation time. Each snapshot contains:
- `digest`: A SHA256 digest that uniquely identifies the Flux configuration being reconciled
- `firstReconciled`: The timestamp when this particular configuration was first reconciled
- `lastReconciled`: The timestamp of the most recent reconciliation attempt for this configuration
- `lastReconciledDuration`: How long the most recent reconciliation attempt took
- `lastReconciledStatus`: The status of the most recent reconciliation (e.g., `ReconciliationSucceeded`, `BuildFailed`, `ReconciliationFailed`)
- `totalReconciliations`: The total number of reconciliations for this configuration
- `metadata`: Additional information about the reconciliation, including the Flux semantic version being applied
The operator deduplicates entries based on the digest and status.
The history is automatically truncated to keep only the 5 most recent entries.
Example:
```yaml
status:
history:
- digest: sha256:43ad78c94b2655429d84f21488f29d7cca9cd45b7f54d2b27e16bbec8eff9228
firstReconciled: "2025-07-15T10:11:00Z"
lastReconciled: "2025-07-15T11:12:00Z"
lastReconciledDuration: 2.818583s
lastReconciledStatus: ReconciliationSucceeded
totalReconciliations: 2
metadata:
flux: "v2.6.4"
- digest: sha256:ec8dbfe61777b65001190260cf873ffe454451bd2e464bd6f9a154cffcdcd7e5
firstReconciled: "2025-06-14T13:10:00Z"
lastReconciled: "2025-07-15T10:00:00Z"
lastReconciledDuration: 4.813292s
lastReconciledStatus: ReconciliationSucceeded
totalReconciliations: 120
metadata:
flux: "v2.6.3"
```
### Components status
In order to provide visibility into the Flux components that are installed,
the flux-operator records the status of each component in the `.status.components` field,
including the image repository, tag and digest.
Example:
```text
Status:
Components:
Digest: sha256:161da425b16b64dda4b3cec2ba0f8d7442973aba29bb446db3b340626181a0bc
Name: source-controller
Repository: ghcr.io/fluxcd/source-controller
Tag: v1.3.0
Digest: sha256:48a032574dd45c39750ba0f1488e6f1ae36756a38f40976a6b7a588d83acefc1
Name: kustomize-controller
Repository: ghcr.io/fluxcd/kustomize-controller
Tag: v1.3.0
```
### Inventory Status
In order to perform operations such as drift detection, garbage collection, upgrades, etc.,
the flux-operator needs to keep track of all Kubernetes objects that are
reconciled as part of a FluxInstance. To do this, it maintains an inventory
containing the list of Kubernetes resource object references that have been
successfully applied and records it in `.status.inventory`. The inventory
records are in the format `id: <namespace>_<name>_<group>_<kind>, v: <version>`.
Example:
```yaml
status:
inventory:
entries:
- id: flux-system_source-controller__ServiceAccount
v: v1
- id: flux-system_source-controller__Service
v: v1
- id: flux-system_source-controller_apps_Deployment
v: v1
```
### Last applied revision
`.status.lastAppliedRevision` is the last revision of the Flux distribution
that was successfully applied to the cluster.
The revision is in the format `<version>@sha256:<digest>`.
The version is the Flux distribution exact semver version that was applied to the cluster.
The digest is the SHA256 hash of the Flux distribution manifests and customisations
that was applied to the cluster.
### Last attempted revision
`.status.lastAttemptedRevision` is the last revision of the Flux distribution
that was attempted to be applied to the cluster.
Example:
```text
Status:
Last Applied Revision: v2.3.0@sha256:4cc5babdb1279ad0177bf513292deadbfa3f7b7c3da0be7fa53b39ab434f7219
Last Attempted Revision: v2.3.0@sha256:4cc5babdb1279ad0177bf513292deadbfa3f7b7c3da0be7fa53b39ab434f7219
```
## FluxInstance Metrics
The Flux Operator exports metrics for the FluxInstance resource.
These metrics are refreshed every time the operator reconciles the instance.
Metrics:
```text
flux_instance_info{uid, kind, name, exported_namespace, ready, suspended, registry, revision}
```
Labels:
- `uid`: The Kubernetes unique identifier of the resource.
- `kind`: The kind of the resource (e.g. `FluxInstance`).
- `name`: The name of the resource (e.g. `flux`).
- `exported_namespace`: The namespace where the resource is deployed (e.g. `flux-system`).
- `ready`: The readiness status of the resource (e.g. `True`, `False` or `Unkown`).
- `reason`: The reason for the readiness status (e.g. `Progressing`, `BuildFailed`, `HealthCheckFailed`, etc.).
- `suspended`: The suspended status of the resource (e.g. `True` or `False`).
- `registry`: The container registry used by the instance (e.g. `ghcr.io/fluxcd`).
- `revision`: The Flux revision installed by the instance (e.g. `v2.3.0@sha256:75aa209c6a...`).
Example:
```text
flux_instance_info{
exported_namespace="flux-system",
kind="FluxInstance",
name="flux",
ready="True",
reason="ReconciliationSucceeded",
registry="ghcr.io/fluxcd",
revision="v2.3.0@sha256:75aa209c6a2e25b97114ccf092246d02ab4363bc136edefc239d2a88da882b63",
suspended="False",
uid="16ca7202-9319-445b-99d0-617c25bda182"
}
```