OPA v1.15.2 and Rego let teams stop risky Terraform plans before apply, emit audit-ready decision logs, and scale CI guardrails safely. Read now.
Stop risky Terraform plans before they reach apply
Infrastructure as code moves fast, and a single unsafe plan can open a public bucket, attach an overly broad IAM role, or skip encryption on a store that holds production data. Policy-as-code with OPA and Rego turns those checks into versioned rules that run against the plan output—not against wishful documentation. OPA v1.15.2 evaluates Rego policies as data: you feed it the plan JSON (or a normalized view of it), and it returns allow or deny with reasons. That decision happens in CI or as a gate before apply, so the risky change never reaches the cloud API.
Write policies around the resources and attributes you actually care about: public access flags, missing tags, unapproved regions, or security groups that open management ports to the world. Keep rules narrow and testable. A policy that says “block open SSH” is easier to review and maintain than a vague “follow best practices” checklist that nobody can automate.
Model decisions in Rego so humans can read them
Rego is declarative: you describe what must be true, not the full control flow of an imperative script. For Terraform, that usually means iterating planned resource changes, matching type and configuration, and producing a clear violation message when a rule fails. Good policies return structured results—resource address, rule id, severity, and a short explanation—so engineers fix the plan instead of guessing which line failed.
Treat policies like application code. Put them in the same repo or a shared policy package, require review on changes, and unit-test them with sample plan fixtures. When a new service lands, add fixtures that cover both the safe path and the deny path. That keeps guardrails honest as modules and providers evolve.
- Deny public exposure of data stores and load balancers unless an explicit exception is present.
- Require encryption and retention settings on stateful resources before apply.
- Constrain IAM and network rules to least privilege patterns your org already agreed on.
Emit audit-ready decision logs
A gate that only says “failed” is hard to defend in an audit. OPA can record each evaluation: input summary, policy version, decision, and the rule paths that contributed. Store those logs with the pipeline run id and the commit SHA so you can answer who changed what, which policy blocked or allowed it, and when. That trail matters for regulated environments and for post-incident review when something did slip through after an exception.
Prefer structured logs over free text. Structured records are searchable, can feed dashboards, and make it obvious whether a deny was a real risk or a noisy rule that needs tuning. When you grant a temporary exception, log the exception id and expiry the same way you log a deny—exceptions that leave no record become permanent holes.
Scale CI guardrails without freezing delivery
Start with a small set of high-severity denies in pull request checks, then expand. Run OPA against plan artifacts on every change that touches infrastructure. Keep evaluation fast by limiting input size (plan only, not full state dumps) and by packaging policies so CI pulls a known version. Fail closed on critical rules; use warn-only for new rules while teams learn the failure modes.
Scale comes from consistency, not from one giant policy file. Split rules by domain (network, identity, data, cost tags), share libraries for common helpers, and version the bundle so every pipeline evaluates the same ruleset. When a rule blocks a legitimate pattern, fix the policy or add a reviewed exception path—do not disable the gate. OPA v1.15.2 and Rego give you the engine; the operational win is stopping bad plans early, keeping decision evidence, and growing guardrails at the same pace as your Terraform estate.