OpenTofu Controller (In-Cluster Terraform)
Relevant source files
- infrastructure/terraform/dummy/terraform.tf
- kubernetes/apps/flux-system/kustomization.yaml
- kubernetes/apps/flux-system/tofu-controller/app/configmap.yaml
- kubernetes/apps/flux-system/tofu-controller/app/externalsecret-vars.yaml
- kubernetes/apps/flux-system/tofu-controller/app/externalsecret.yaml
- kubernetes/apps/flux-system/tofu-controller/app/helmrelease.yaml
- kubernetes/apps/flux-system/tofu-controller/app/kustomization.yaml
- kubernetes/apps/flux-system/tofu-controller/app/ocirepository.yaml
- kubernetes/apps/flux-system/tofu-controller/ks.yaml
- kubernetes/apps/flux-system/tofu-controller/terraforms/authentik.yaml
- kubernetes/apps/flux-system/tofu-controller/terraforms/dummy.yaml
- kubernetes/apps/flux-system/tofu-controller/terraforms/kustomization.yaml
- kubernetes/apps/flux-system/tofu-controller/terraforms/minio.yaml
The tofu-controller (formerly known as the Flux Terraform Controller) is an extension to Flux CD that enables the execution of OpenTofu/Terraform plans directly within the Kubernetes cluster. This allows for a unified GitOps workflow where infrastructure resources (like S3 buckets or OIDC clients) are managed alongside Kubernetes manifests using the same reconciliation principles.
Controller Architecture
The controller is deployed via a HelmRelease in the flux-system namespace kubernetes/apps/flux-system/tofu-controller/app/helmrelease.yaml17-20 It utilizes a specialized runner image, opentofu-runner, to execute the actual Terraform binary in ephemeral pods kubernetes/apps/flux-system/tofu-controller/app/helmrelease.yaml39-42
Data Flow and Reconciliation
The following diagram illustrates how the tofu-controller reconciles a Terraform resource by pulling source code, injecting secrets, and persisting state to an external backend.
Terraform Reconciliation Flow
[Flowchart Diagram]
Sources:kubernetes/apps/flux-system/tofu-controller/app/helmrelease.yaml39-42kubernetes/apps/flux-system/tofu-controller/terraforms/authentik.yaml10-14kubernetes/apps/flux-system/tofu-controller/terraforms/authentik.yaml34-36
Terraform Resources and Modules
The repository defines several Terraform custom resources (CRs) that target specific infrastructure domains. These resources reference the flux-system GitRepository as their source kubernetes/apps/flux-system/tofu-controller/terraforms/dummy.yaml11-14
1. Authentik Provisioning
The authentik Terraform resource manages OIDC applications, groups, and authentication flows. It pulls variables from the terraform-secretkubernetes/apps/flux-system/tofu-controller/terraforms/authentik.yaml34-36 which contains client IDs and secrets synced from Bitwarden for services like Grafana, Open-WebUI, and Forgejo kubernetes/apps/flux-system/tofu-controller/app/externalsecret-vars.yaml23-55
2. S3 and Garage Provisioning
The garage resource (labeled minio.yaml in some manifests) handles the creation of S3 buckets and access keys within the Garage S3 storage system kubernetes/apps/flux-system/tofu-controller/terraforms/minio.yaml1-10 It uses the same secret injection pattern to provide root credentials to the runner kubernetes/apps/flux-system/tofu-controller/app/externalsecret-vars.yaml58-62
3. Dummy Module Pattern
A “dummy” module is maintained for testing and troubleshooting the controller’s ability to communicate with the remote backend and execute null_resource blocks infrastructure/terraform/dummy/terraform.tf20-26 It provides a safe way to validate the s3 backend configuration without affecting production infrastructure kubernetes/apps/flux-system/tofu-controller/terraforms/dummy.yaml1-30
Sources:kubernetes/apps/flux-system/tofu-controller/terraforms/authentik.yaml1-14kubernetes/apps/flux-system/tofu-controller/terraforms/minio.yaml1-10infrastructure/terraform/dummy/terraform.tf1-31
State and Secret Management
The system relies on Cloudflare R2 as a centralized S3-compatible backend for Terraform state files.
Backend Configuration
Each Terraform resource defines its backend configuration inline via spec.backendConfig.customConfigurationkubernetes/apps/flux-system/tofu-controller/terraforms/dummy.yaml15-30 This ensures that the state is not stored inside the cluster, facilitating recovery and multi-environment management. Key parameters include:
- Bucket:
tf-state-bucket-cloudjur-com - Endpoint: Cloudflare R2 S3 API
- Security: Credentials provided via
backendConfigsFromreferencingterraform-backend-secretkubernetes/apps/flux-system/tofu-controller/terraforms/dummy.yaml31-33
Secret Synchronization
The ClusterExternalSecret named terraform-backend-secret is responsible for distributing R2 credentials across namespaces that require Terraform execution kubernetes/apps/flux-system/tofu-controller/app/externalsecret.yaml2-11
Code Entity Mapping: Secrets to Terraform Variables
| K8s Secret Entity | Source (Bitwarden UUID) | Terraform Variable Mapping |
|---|---|---|
terraform-backend-secret | cb424eb9-... | access_key, secret_key (for R2) |
terraform-secret | f3fcbd57-... | authentik_token |
terraform-secret | b63d3bff-... | grafana_id, grafana_secret |
tofu-branch-token | b67e4583-... | token (GitHub PAT) |
Sources:kubernetes/apps/flux-system/tofu-controller/app/externalsecret.yaml2-35kubernetes/apps/flux-system/tofu-controller/app/externalsecret-vars.yaml20-31kubernetes/apps/flux-system/tofu-controller/terraforms/dummy.yaml17-30
Implementation Details
Branch Planner
The controller includes a ConfigMap named branch-plannerkubernetes/apps/flux-system/tofu-controller/app/configmap.yaml2-6 This configuration specifies which namespaces are allowed to utilize the tofu-branch-token for Git operations, specifically targeting the security and flux-system namespaces kubernetes/apps/flux-system/tofu-controller/app/configmap.yaml9-12
Runner Permissions
The tofu-controller Helm values define specific service account permissions for the runner. It is restricted to operating within a subset of namespaces: flux-system, security, and storagekubernetes/apps/flux-system/tofu-controller/app/helmrelease.yaml43-48
Sources:kubernetes/apps/flux-system/tofu-controller/app/configmap.yaml1-12kubernetes/apps/flux-system/tofu-controller/app/helmrelease.yaml39-52