Terraform doesn’t actually manage Flux resources; it tells Flux how to manage them.
Flux, the GitOps tool, is designed to reconcile the state of your Kubernetes cluster with a Git repository. When you use the Terraform Flux provider, you’re not directly creating Kubernetes manifests. Instead, you’re creating Terraform resources that represent Flux’s desired state for reconciling those manifests. Terraform then applies these Flux-specific resources to your cluster, and Flux itself picks them up and does the actual work of syncing your cluster state with Git. Think of it as Terraform being the GitOps operator for GitOps operators.
Let’s see this in action. Imagine you want Flux to automatically deploy an application defined in a Git repository. Here’s how you’d configure it with Terraform:
resource "flux_bootstrap" "default" {
path = "clusters/my-cluster"
url = "ssh://git@github.com/my-org/my-repo.git"
branch = "main"
secret_name = "flux-ssh-key"
}
resource "flux_kustomization" "app" {
path = "./apps/my-app"
url = flux_bootstrap.default.url
depends_on = [flux_bootstrap.default]
}
When you run terraform apply, this doesn’t create a Deployment or a Service. It creates a Kustomization object in your Kubernetes cluster. Flux, which is already running in your cluster (usually bootstrapped separately or via this flux_bootstrap resource), sees this Kustomization object. It then reads the url and path from it, clones the specified Git repository, and applies whatever manifests it finds in that path. The flux_kustomization resource in Terraform is essentially a declarative way to tell Flux, "Go get this stuff from Git and make it happen."
The core problem Flux solves is drift – the divergence between your desired state (in Git) and your actual cluster state. It ensures that your cluster always reflects what’s in your Git repository. The Terraform Flux provider fits into this by allowing you to manage Flux’s own configuration using Terraform. You can use Terraform to:
- Bootstrap Flux: Install Flux onto a cluster and point it to your Git repository.
- Define Kustomizations: Tell Flux which directories in your Git repository contain Kubernetes manifests (Kustomizations or Helm charts) to apply.
- Configure HelmReleases: Manage Helm chart deployments directly through Flux, defining release names, chart versions, values, and more.
- Set up Image Updates: Configure Flux to automatically update container images based on registry scans and Git commits.
Internally, when Terraform applies a flux_kustomization resource, it’s creating a Kubernetes CustomResourceDefinition (CRD) object of kind Kustomization. Flux controllers are constantly watching for these objects. When a new one appears or an existing one is modified, the Flux controller responsible for Kustomizations reads its specification. It then orchestrates the cloning of the Git repository specified by url, checks out the correct branch, and applies the manifests found at the path within that repository to the cluster. The depends_on in the Terraform code ensures that the bootstrap process (which installs Flux and sets up its own Git repository access) completes before Terraform tries to configure a Kustomization that relies on that bootstrap.
The real magic of Flux, and by extension the Terraform provider, is its continuous reconciliation loop. It doesn’t just apply your manifests once. Flux constantly monitors the Git repository for changes and the cluster for drift. If you manually change something in the cluster that contradicts what’s in Git, Flux will detect it and revert the change. If you push a new commit to your Git repository, Flux will detect it and apply the updated manifests to your cluster. This continuous, automated synchronization is the essence of GitOps.
A subtle but crucial aspect of managing Flux via Terraform is understanding the lifecycle of Flux’s own components. When you use flux_bootstrap, Terraform creates the necessary Flux controllers and CRDs. However, if you later delete the flux_bootstrap resource from your Terraform state, Terraform will attempt to uninstall Flux from your cluster. This means any flux_kustomization or flux_helmrelease resources managed by that bootstrap instance will also cease to be reconciled by Flux. It’s essential to manage the Flux installation itself with the same Terraform configuration that manages Flux resources, or to have a clear strategy for how Flux will be maintained if you’re not using Terraform for its installation.
The next concept you’ll likely encounter is managing Helm releases directly, using the flux_helmrelease resource, which offers a more structured way to deploy applications packaged as Helm charts.