İçeriğe Atla
Mustafa Erbay
Tutorials · 10 min read · görüntülenme Türkçe oku
100%

An OPA Pipeline for Terraform Plan Policies

A practical guide to gating infrastructure changes through policy by inspecting Terraform plan output with OPA.

An OPA Pipeline for Terraform Plan Policies — cover image

A common trap I see in teams using Infrastructure as Code is leaving the terraform plan output to a human reviewer and nothing else. Code review is valuable; but checking, by hand and on every PR, things like tagging standards, internet-exposed resources, region selection, cost limits, or encryption requirements isn’t sustainable. An OPA-based pipeline turns the plan output into a policy decision and routes changes through an extra safety layer beyond human judgment.

Diagram showing the Terraform plan and OPA flow

Core flow

The goal is to put Terraform code through two gates before apply:

  1. Generate the upcoming change with terraform plan
  2. Evaluate the plan JSON output against the OPA policy set

This way, the question “what will happen in the cloud account?” stays separate from “is this change allowed?” — but they meet inside the same pipeline.

Producing the plan output as JSON

The first step is standard:

terraform init
terraform plan -out=tfplan.binary
terraform show -json tfplan.binary > tfplan.json

OPA or Conftest typically operates against tfplan.json. The important point is that the policy engine looks at the actual plan result, not at the HCL file. Because module expansion, variable resolution, and provider behavior only become concrete at the plan step.

Sample policy scenarios

High-value rules to start with include:

  • Reject production resources that would receive a public IP
  • Fail the plan when required tags are missing
  • Block storage resources without encryption
  • Reject resources opened outside specific regions
  • Emit a warning for high-cost instance types

A simple Rego sample:

package terraform.guardrails

deny[msg] {
  some rc in input.resource_changes
  rc.type == "aws_s3_bucket"
  after := rc.change.after
  after.tags.environment == "production"
  not after.server_side_encryption_configuration
  msg := sprintf("production bucket encryption missing: %s", [rc.address])
}

This rule alone isn’t enough, but it shows the approach clearly: resource change, target state, and business context are evaluated together.

Pipeline design

A CI flow can typically be structured in this order:

  1. Format and validate
  2. Plan generation
  3. Plan JSON extraction
  4. OPA or Conftest policy evaluation
  5. Writing the results back to the PR comment

In this flow, the policy result shouldn’t be a simple “pass/fail.” Which resource hit which rule should be visible directly on the PR. Otherwise the developer’s fix loop drags out.

Managing the policy set

The reason most policy projects fail isn’t technical — it’s governance. These need to be clarified:

  • Is the policy repository separate from the application code?
  • How will versioning work?
  • Is there an emergency-exception mechanism?
  • How are warning rules separated from blocking rules?

Making every rule blocking from day one provokes pushback in teams. The healthy model is to deliver visibility first, then turn the critical rules into a gate.

Extra controls for enterprise use

In enterprises, policies are produced not only by security but also by platform and finance teams. So splitting rules into three groups helps:

  • Security guardrails
  • Operational and observability requirements
  • Cost and governance rules

For example, you can require a log-collection agent or a monitoring tag on every production resource. That way, IaC validation also carries the observability standard along with it.

Conclusion

Routing Terraform plan output through an OPA pipeline lifts IaC practice out of the “write code and hope” phase. The biggest win is moving platform knowledge out of human memory and into a repeatable policy set. If you start with a small rule set and build plan-based visibility, you can standardize security and governance decisions over time with much less friction.

Paylaş:

Bu yazı faydalı oldu mu?

Yükleniyor...

Bu yazı nasıldı?

ME

Mustafa Erbay

Sistem Mimarisi · Network Uzmanı · Altyapı, Güvenlik ve Yazılım

2006'dan bu yana sistem mimarisi, network, sunucu altyapıları, büyük yapıların kurulumu, yazılım ve sistem güvenliği ekseninde çalışıyorum. Bu blogda sahada karşılığı olan teknik deneyimlerimi paylaşıyorum.

Kişisel Notlar

Bu notlar sadece sizde saklanır. Tarayıcınızda yerel olarak tutulur.

Hazır 0 karakter

Comments

Server-side AI Moderation

Comments are AI-moderated server-side and stored permanently.

?
0/2000

Server-side AI moderation

✉️ Free · No spam · Unsubscribe anytime

Curated digest, hand-picked by me — not the AI

Once a week: the most important post of the week, behind-the-scenes notes, and a "what I actually used this week" section. Less noise, more signal.

  • 📌
    Best of the week Single most-worth-reading post
  • 🔧
    Toolbox notes Real tools I used this week
  • 🧠
    Behind-the-scenes Notes that don't make it to blog

We don't spam. Unsubscribe anytime. · Tracked only by Umami (self-hosted, no Google).

Your Reading Stats

0

Posts Read

0m

Reading Time

0

Day Streak

-

Favorite Category

Related Posts