# Terraform CI: lint and policy gates before plan

## Why

`terraform plan` catches syntax and type errors, not bad practice: unencrypted buckets, missing tags, wide-open security groups all plan cleanly. Lint (tflint) and policy (OPA/Conftest, Sentinel on HCP) catch those, but only if they gate the pipeline before apply.

## How

Pipeline order:

1. `terraform fmt -check` and `terraform validate`. Fast, catches formatting and static errors.
2. `tflint` with the provider rulesets you use. Catches deprecated syntax, missing required arguments, naming issues.
3. Policy check: Conftest/OPA against the plan JSON (`terraform show -json tfplan`), or Sentinel policies on HCP Terraform runs.
4. `terraform plan -out=tfplan`, review, then apply.

## Rules for agents

1. Gates that do not block are theater. Wire lint and policy failures to fail the job, not to post a comment nobody reads.
2. Keep the policy set small and load-bearing: encryption defaults, tag requirements, no the all-interfaces address ingress. A 200-rule policy pack everyone waives is worse than five rules everyone follows.
3. Run policy against the plan JSON, not the source. Source-level checks miss values computed from variables and modules.
4. When a policy blocks a legitimate change, fix the policy with a reviewed PR, not with an inline exception. Exceptions accumulate into a second, shadow policy.
