How do you extend Flux with custom controllers and CRDs to implement organization-specific GitOps workflows?
Quick Answer
Flux can be extended by writing custom Kubernetes controllers that watch Flux CRDs or introduce new CRDs that interact with the Flux reconciliation loop. These custom controllers leverage the Flux runtime library and controller-runtime framework to add capabilities like custom approval gates, environment promotion, or integration with internal deployment platforms.
Detailed Answer
Flux was designed with extensibility as a core principle. Its architecture is composed of specialized controllers, each managing a specific CRD: source-controller handles GitRepository and HelmRepository resources, kustomize-controller handles Kustomization resources, helm-controller handles HelmRelease resources, and notification-controller handles alerts and providers. This modular design means organizations can add their own controllers that either extend existing Flux CRDs through webhooks, introduce new CRDs that participate in the GitOps workflow, or compose Flux primitives into higher-level abstractions tailored to their platform.
The most common extension pattern involves writing a custom controller using the controller-runtime framework combined with the Flux runtime library. The Flux runtime library at github.com/fluxcd/pkg provides shared reconciliation utilities, condition management, status reporting, and event recording that maintain consistency with built-in Flux controllers. For example, an organization might create a DeploymentApproval CRD that gates Flux Kustomization reconciliation behind a manual approval stored in an external system like ServiceNow or Jira. The custom controller watches DeploymentApproval resources, checks the external approval system, and sets a condition that a validating webhook uses to allow or block Flux reconciliation.
Another powerful extension pattern is the environment promotion controller. Many organizations need to promote changes through dev, staging, and production environments with automated testing gates between each stage. A custom PromotionPipeline CRD can define the stages, the tests required at each gate, and the Flux Kustomizations that should be updated when promotion succeeds. The controller watches for successful reconciliations in the source environment, triggers integration tests, and upon success updates the target environment's Git branch or path to reference the promoted commit. This extends Flux beyond simple Git-to-cluster synchronization into a full deployment pipeline.
Integration with internal platforms often requires custom source controllers. While Flux ships with GitRepository, OCIRepository, HelmRepository, and Bucket sources, an organization might store configurations in an internal artifact registry, a database-backed configuration management system, or a proprietary API. Writing a custom source controller that implements the Flux Source interface allows these systems to participate seamlessly in the Flux reconciliation workflow. The custom source produces an artifact tarball that downstream Kustomization or HelmRelease resources consume just like any built-in source.
Testing and operating custom controllers requires the same rigor as any production Kubernetes operator. The controller-runtime envtest package provides a lightweight API server for integration tests without a full cluster. Custom controllers should expose Prometheus metrics following the same conventions as Flux built-in controllers, including reconciliation duration histograms, error counters, and condition gauges. They should also emit Kubernetes events that Flux notification-controller can forward to Slack, Teams, or PagerDuty. Version compatibility with Flux releases must be tracked carefully, as Flux CRD schema changes across versions can break custom controllers that depend on specific fields or status conditions.