Skip to content

FluxCD v2 GitOps

Scope

FluxCD v2 GitOps toolkit for Kubernetes. Covers Flux architecture (source-controller, kustomize-controller, helm-controller, notification-controller, image-reflector-controller, image-automation-controller), GitRepository and OCIRepository sources, Kustomization and HelmRelease custom resources, multi-tenancy model, RBAC and service account impersonation, notification providers and alerts, image update automation, dependency ordering, health assessment, variable substitution, SOPS and age-based secret decryption, Flux bootstrap process, monitoring and observability, and multi-cluster management patterns.

Checklist

  • [Critical] Bootstrap Flux with flux bootstrap for self-managing installation: use flux bootstrap github or flux bootstrap gitlab to install Flux components and create the GitOps repository structure; bootstrap configures Flux to manage itself from Git (self-managing), ensuring the Flux installation is declarative and recoverable; choose the target path within the repository (--path=clusters/my-cluster) for multi-cluster repository layouts; store the bootstrap manifests in a dedicated cluster directory
  • [Critical] Define GitRepository sources with authentication and verification: create GitRepository resources pointing to config repositories with appropriate authentication (SSH keys, HTTPS tokens, or cloud IAM via GCP Workload Identity / AWS IRSA); set spec.interval for polling frequency (1-5 minutes for production, shorter for dev); enable commit signature verification (spec.verify.provider: cosign or spec.verify.secretRef for PGP) to ensure only signed commits are applied; use spec.ref.branch or spec.ref.semver for version pinning
  • [Critical] Configure Kustomization resources for declarative application deployment: create Kustomization CRs (Flux-specific, not plain Kustomize) mapping source paths to cluster targets; set spec.prune: true to garbage-collect resources removed from Git; set spec.interval for reconciliation frequency; use spec.path to point to environment-specific overlays; configure spec.dependsOn for ordering (infrastructure before applications); use spec.targetNamespace and spec.serviceAccountName for namespace-scoped deployments with tenant isolation
  • [Critical] Implement secrets management with SOPS decryption: configure Flux to decrypt SOPS-encrypted secrets during reconciliation; create a decryption Secret containing an age private key or reference cloud KMS (AWS KMS, Azure Key Vault, GCP KMS); add spec.decryption to Kustomization resources pointing to the decryption provider and secret; encrypt sensitive values in Git using sops --encrypt with .sops.yaml creation rules; alternative: use External Secrets Operator alongside Flux for runtime secret retrieval
  • [Recommended] Design multi-tenancy with service account impersonation: create per-tenant namespaces with dedicated ServiceAccounts and RBAC RoleBindings; configure Kustomization resources with spec.serviceAccountName to impersonate tenant-scoped service accounts, restricting what each tenant's Flux reconciliation can create; use this pattern to allow teams to manage their own GitOps configurations without cluster-admin access; combine with Kubernetes namespace quotas for resource limits
  • [Recommended] Configure HelmRelease resources for Helm chart deployment: define HelmRelease CRs referencing HelmRepository or GitRepository sources; use spec.values for inline values and spec.valuesFrom for ConfigMap/Secret-based values; configure spec.install.remediation and spec.upgrade.remediation with retry counts and rollback on failure; set spec.dependsOn for ordering (e.g., database before application); use spec.chart.spec.version with semver constraints for controlled upgrades
  • [Recommended] Implement notification and alerting: deploy notification-controller with Provider resources (Slack, Microsoft Teams, Discord, PagerDuty, generic webhook, Azure Event Hub); create Alert resources filtering on event severity and source kinds (Kustomization, HelmRelease, GitRepository); configure alerts for reconciliation failures, health check failures, and drift detection; use Receiver resources to trigger reconciliation from external webhooks (GitHub webhooks for immediate sync on push, avoiding polling delay)
  • [Recommended] Design repository structure for multi-cluster management: use a monorepo with directory-per-cluster layout (clusters/production/, clusters/staging/) where each cluster directory contains its Flux Kustomization entrypoints; share common configurations in infrastructure/ and apps/ directories using Kustomize overlays; each cluster bootstraps Flux pointing to its own cluster directory; alternative: use separate repositories per cluster with shared library repositories referenced as remote sources
  • [Recommended] Configure dependency ordering and health checks: use spec.dependsOn in Kustomization and HelmRelease resources to express deployment dependencies (CRDs before controllers, infrastructure before applications, databases before application services); Flux waits for health checks to pass on dependencies before proceeding; customize health checks with spec.healthChecks for resources that Flux does not natively assess; use spec.timeout to bound how long Flux waits for health
  • [Recommended] Enable image update automation for continuous deployment: deploy image-reflector-controller and image-automation-controller; create ImageRepository resources to scan container registries; create ImagePolicy resources with semver, alphabetical, or numerical policies to select the latest image; add markers in YAML files (# {"$imagepolicy": "flux-system:app"}) for automatic update; configure ImageUpdateAutomation to commit changes back to Git; use for dev/staging environments; gate production with PR-based promotion
  • [Optional] Implement OCI repository sources for Helm and Kustomize: use OCIRepository sources to pull Kustomize overlays or raw manifests from OCI-compliant registries (GHCR, ECR, ACR, Docker Hub); publish configuration bundles as OCI artifacts using flux push artifact; provides versioned, immutable configuration distribution without Git; useful for platform teams distributing shared configurations as artifacts; combine with HelmRepository of type oci for Helm charts in OCI registries
  • [Optional] Configure Flux monitoring with Prometheus metrics: Flux controllers export Prometheus metrics on /metrics endpoints; deploy ServiceMonitor resources for Prometheus Operator scraping; key metrics include reconciliation duration, error counts, and source fetch timing; use the Flux Grafana dashboards (available in the Flux GitHub repository) for visualization; set up alerting on sustained reconciliation failures and increasing error rates
  • [Optional] Evaluate Flux Operator for simplified lifecycle management: Flux Operator (newer project) manages Flux instances as FluxInstance CRDs, simplifying multi-instance management, upgrades, and configuration; suitable for platform teams managing Flux across many clusters; provides a declarative way to configure Flux components without manual bootstrap; evaluate maturity against the standard flux bootstrap approach

Why This Matters

FluxCD v2 provides a lightweight, composable GitOps toolkit built on Kubernetes controllers that reconcile cluster state with Git repositories. Unlike ArgoCD's centralized architecture with a web UI, Flux operates as a set of independent controllers running within the target cluster, making it inherently decentralized. Each cluster runs its own Flux instance, pulling configuration from Git rather than being pushed from a central management plane.

The multi-tenancy model is Flux's strongest differentiator. Through service account impersonation, a single Flux installation can manage deployments for multiple teams where each team's reconciliation runs with only the RBAC permissions granted to their service account. A development team's Flux Kustomization can only create resources in their assigned namespaces, even if they control what manifests Flux applies. This eliminates the blast radius of a misconfigured or compromised tenant configuration -- they cannot affect other tenants' namespaces or cluster-wide resources.

SOPS-based secret management is tightly integrated into Flux's reconciliation workflow. Unlike ArgoCD where secrets management is handled by separate tools (Sealed Secrets, ESO), Flux can natively decrypt SOPS-encrypted files during Kustomize reconciliation. This means teams can store encrypted secrets directly in their Git repositories and Flux transparently decrypts them during application. The age encryption tool (replacing GPG for simplicity) combined with SOPS has become the standard approach for Flux-managed secrets in smaller deployments, while External Secrets Operator remains preferred for organizations with existing secrets managers.

The source-controller architecture separating source fetching from reconciliation is a key design principle. GitRepository, HelmRepository, OCIRepository, and Bucket sources are independent resources that can be shared across multiple Kustomizations and HelmReleases. This separation enables efficient polling (one source fetch serves many consumers) and clean dependency tracking. However, the polling-based model means there is inherent latency between a Git push and cluster reconciliation (configurable via spec.interval). For near-instant sync, Receiver resources can accept webhooks from Git providers to trigger immediate reconciliation.

Common Decisions (ADR Triggers)

  • FluxCD vs ArgoCD -- FluxCD provides lightweight per-cluster controllers, native multi-tenancy via service account impersonation, built-in SOPS decryption, and a composable toolkit architecture. ArgoCD provides a centralized web UI, Application CRDs for explicit management, built-in RBAC with SSO, and multi-cluster management from a single instance. Use FluxCD for platform engineering teams wanting decentralized, lightweight GitOps with strong multi-tenancy. Use ArgoCD for organizations wanting centralized visibility, UI-driven management, and RBAC across teams.
  • Kustomize vs Helm for Flux-managed deployments -- Flux Kustomization resources apply Kustomize overlays with variable substitution. Flux HelmRelease resources deploy Helm charts with values management and rollback. Use Kustomize for internal application manifests where teams prefer plain YAML with overlays. Use Helm for third-party software (cert-manager, ingress-nginx, monitoring stacks) distributed as charts. Most organizations use both through separate Flux resources.
  • SOPS with age vs External Secrets Operator -- SOPS with age encrypts secrets in Git, Flux decrypts during reconciliation (simple, Git-native, no external dependency). External Secrets Operator pulls secrets from external stores at runtime (Vault, AWS Secrets Manager, Azure Key Vault) with rotation support. Use SOPS for smaller deployments wanting Git-native secret management. Use ESO for organizations with existing secrets managers, strict secret rotation requirements, or secrets shared across non-Kubernetes systems.
  • Monorepo vs polyrepo for Flux configuration -- Monorepo stores all cluster configurations in a single repository with directory-per-cluster layout, enabling atomic cross-cluster changes and shared configuration. Polyrepo uses separate repositories per cluster, providing strong isolation and independent access control. Use monorepo for organizations with a central platform team managing cluster configurations. Use polyrepo when clusters are managed by independent teams or span different security domains.
  • Polling-based reconciliation vs webhook-triggered sync -- Default polling (1-5 minute interval) provides eventual consistency without external configuration. Webhook Receivers trigger immediate reconciliation on Git push, reducing sync latency to seconds. Use polling-only for simplicity and when 1-5 minute sync latency is acceptable. Add webhook Receivers for environments requiring near-instant deployment (dev environments, time-sensitive production fixes).
  • Image update automation vs PR-based promotion -- Image update automation automatically commits new image tags to Git when new images are detected. PR-based promotion requires a human or CI pipeline to create a PR updating image references. Use image automation for dev/staging environments wanting continuous deployment. Use PR-based promotion for production environments requiring review gates and audit trails.

See Also

  • general/ci-cd.md -- general CI/CD pipeline patterns and GitOps comparison
  • general/deployment.md -- deployment strategies (rolling, blue-green, canary) and rollback procedures
  • providers/argocd/gitops.md -- ArgoCD as an alternative GitOps platform
  • providers/kubernetes/operations.md -- Kubernetes operations and cluster management
  • providers/kubernetes/security.md -- Kubernetes RBAC for Flux multi-tenancy
  • providers/hashicorp/vault.md -- Vault integration with External Secrets Operator for Flux
  • providers/github/actions.md -- GitHub Actions as the CI component paired with Flux for CD
  • providers/gitlab/ci-cd.md -- GitLab CI as the CI component paired with Flux for CD