OpenTofu in CI/CD & securing state

Automate apply; protect state & supply chain.

Advanced14 min · lesson 12 of 12

The safe automation pattern is the same one every mature Terraform shop uses, run with tofu: on a pull request, tofu plan and post the diff for review; on merge to main, tofu apply the reviewed plan — never an interactive apply from a laptop against production. The plan-on-PR / apply-on-merge split is what makes infra changes reviewable and auditable.

.gitlab-ci.yml
plan:
image: ghcr.io/opentofu/opentofu:1.8
script:
- tofu init
- tofu plan -out=tfplan.bin
- tofu show -json tfplan.bin > plan.json
- conftest test plan.json --policy policy/ # policy gate
artifacts: { paths: [tfplan.bin] }
apply:
script: [tofu apply tfplan.bin] # apply the exact reviewed plan
rules: [{ if: '$CI_COMMIT_BRANCH == "main"' }]
when: manual # human approval for prod
environment: production

Securing the pipeline

Terraform/OpenTofu automation holds the keys to your entire cloud, so the pipeline is a top-tier target. Give CI short-lived cloud credentials via OIDC rather than static keys; protect the state backend and (better) turn on client-side state encryption so a compromised runner cannot read secrets from state; and commit the .terraform.lock.hcl so providers cannot be swapped underneath you. Apply the same least-privilege and protected-environment rules the CI/CD course covers.

The secure OpenTofu pipeline
1PR: plan
diff + scan + policy
2review
human reads the plan
3merge: apply
the exact reviewed plan
4guardrails
OIDC, encrypted state, locks
Plan is visible and gated; apply is the approved plan; credentials are short-lived; state is encrypted and locked.
The state backend is the crown jewels
Whoever can read your state can often read secrets and understand your entire estate; whoever can write it can hijack what OpenTofu manages. Lock it down: least-privilege backend access, versioning for recovery, client-side encryption for the contents, and never expose state in CI logs or artifacts. The pipeline that applies infra deserves the same hardening as the infra itself.