Run Terraform and OpenTofu from Argo CD, GitOps style, with plan approval, drift detection and a UI extension. It is an add-on: no changes to Argo CD are required. The design follows the Flux tofu-controller.
Documentation: https://redhat-developer.github.io/argocd-terraform-controller/
flowchart TB
subgraph argocd[Argo CD]
app[Application]
ui[UI extension<br/>health · actions]
end
tf[Terraform<br/>infra.argocd.io/v1alpha1]
ctrl[Controller<br/>fetch source · plan · approve · apply · drift]
runner[Runner Pod<br/>tofu or terraform]
subgraph out[Results]
state[(State Secret)]
plan[Plan Secret<br/>+ readable ConfigMap]
outputs[Outputs Secret]
end
cloud[(Cloud / provider<br/>resources)]
app -- sync --> tf
ui -. read / approve .-> tf
tf --> ctrl
ctrl -- gRPC + mTLS --> runner
runner --> state
runner --> plan
runner --> outputs
runner --> cloud
- Terraform object (
infra.argocd.io/v1alpha1) describing a Git or OCI source, variables, backend, approval mode, outputs and health checks. Argo CD syncs the object; the controller does the rest. - Terraform and OpenTofu in one runner image; choose per object with
spec.runner.binary: auto | terraform | tofu. - Plan / approve / apply with manual approval by plan ID (from git,
kubectlor the Argo CD UI),autoapproval, plan-only and drift-detection-only modes. - Drift detection on every interval, with automatic remediation in
automode. - State in a Kubernetes Secret through Terraform's
kubernetesbackend by default, or any other backend (s3,gcs,azurerm, …) and Terraform Cloud. - Outputs to a Secret, health checks,
dependsOnbetween stacks, destroy on deletion (optionally deleting the state too), state force-unlock. - Argo CD integration through supported extension points only: health
assessment and resource actions in
argocd-cm, and a UI extension adding a Terraform sidebar dashboard — every Terraform object across your Applications, with a graph of what each one manages (Kubernetes or not: VPCs, buckets, databases…), plan output and an approve button — plus a resource tab, an Application details tab and an application view. - Isolation: the controller holds source credentials and talks to a per-object runner Pod over mTLS; the runner only executes the binary with its own ServiceAccount.
The step-by-step, copy-and-paste version is in docs/getting-started.md.
Install the controller (CRD, RBAC, Deployment):
kubectl apply -f https://github.com/redhat-developer/argocd-terraform-controller/releases/latest/download/install.yamlCreate the runner identity (tf-runner ServiceAccount + RoleBinding) in every
namespace that will host Terraform objects:
kustomize build https://github.com/redhat-developer/argocd-terraform-controller/config/runner | kubectl apply -n my-namespace -f -Integrate with Argo CD (health, actions, UI extension) — see Argo CD integration:
RELEASE=https://github.com/redhat-developer/argocd-terraform-controller/releases/latest/download
kubectl patch configmap argocd-cm -n argocd --type merge --patch "$(curl -fsSL ${RELEASE}/argocd-cm-patch.yaml)"
# The server container is "argocd-server" (upstream install.yaml) or "server" (Helm chart); detect and match it.
SERVER_CONTAINER=$(kubectl get deploy argocd-server -n argocd -o jsonpath='{.spec.template.spec.containers[0].name}')
curl -fsSL ${RELEASE}/argocd-server-extension-patch.yaml | sed "s/- name: argocd-server/- name: ${SERVER_CONTAINER}/" \
| kubectl patch deployment argocd-server -n argocd --patch-file /dev/stdinThen put a Terraform object in a repository synced by an Argo CD Application:
apiVersion: infra.argocd.io/v1alpha1
kind: Terraform
metadata:
name: network
namespace: my-namespace
spec:
source:
git:
url: https://github.com/my-org/infra
ref:
branch: main
path: ./network
interval: 10m
approvePlan: "" # manual: approve in the UI or set the plan ID here
runner:
binary: tofu
writeOutputsToSecret:
name: network-outputsThe Application shows the object as Suspended while a plan waits for approval, Progressing while applying and Healthy once applied, so later sync waves can depend on the infrastructure. The Terraform entry in the Argo CD sidebar lists every object and graphs the resources it manages.
Full documentation is at https://redhat-developer.github.io/argocd-terraform-controller/
(sources in docs/).
- Getting started
- Operator Manual — installation and upgrades, Argo CD integration, state backends, Terraform vs OpenTofu
- User Guide — plan approval, sources, variables and credentials, specification reference
- Developer Guide
- The generated CRD schema is also browsable at doc.crds.dev
Alpha. The API group infra.argocd.io/v1alpha1 may change before v1.
Apache-2.0. Copyright The Argo CD Terraform Controller Authors.
Portions of this software are derived from the Flux IaC tofu-controller, originally created by Weaveworks Ltd. and the Flux IaC contributors, licensed under the Apache License, Version 2.0.