Policy-as-Code Rebellion: Friction Systems

Policy-as-Code Rebellion: Friction Systems

Reading time1 min
#devops#policy-as-code#opa#engineering

In DevOps, creativity and compliance are often at odds. Developers want freedom. Compliance wants control. Somewhere in the middle? Policy-as-Code.

It sounds great on paper. In reality, especially with tools like Open Policy Agent (OPA), it can feel more like a roadblock than a bridge.

To an engineer, it’s like being told to jam on guitar—while wearing oven mitts. The music’s still in your head. But good luck playing it.

Let me show you how this played out at one fast-moving company—and how they found a better way.


The Great Cloud Migration Caper

At a mid-sized startup—we’ll call it Cloud 9—things were moving fast.

New cloud setup? ✅
Terraform pipelines? Running smooth.
EC2 instances? Spinning up like magic.

The engineering team was cruising. Then came the compliance team.

And with them, OPA.

Suddenly, developers had to bake in policies for everything:

  • Which instance types they could use
  • IAM roles and permission boundaries
  • Tags, resource limits—the works

The shift was immediate:

  • Deployments slowed by 35%
  • Cloud costs jumped 20%—thanks to “safe” but bloated configs
  • Morale tanked
# Terraform example: locked-down instance type
resource "aws_instance" "web" {
  count         = 3
  ami           = var.ami_id
  instance_type = "t2.micro" # Compliant, but barely usable
  ...
}

One engineer summed it up perfectly:
“We stopped building features. Started managing policy engines.”


The Kubernetes Quagmire

Six months later, Cloud 9 switched to Kubernetes. This time, they hoped it’d be different. Easier. Cleaner.

It wasn’t.

OPA showed up again—now controlling:

  • Pod security
  • Network segmentation
  • Admission policies

What should’ve been a smooth deployment turned into hours of debugging YAML.

# OPA rule to block insecure container images
package kubernetes.admission

deny["Invalid pod configuration"] {
  input.request.object.spec.containers[_].image == "insecure-image:latest"
}

The fallout:

  • Deploy times up 50%
  • Resource usage up 30%—teams over-provisioned to “be safe”
  • Frustration spread. Some devs even switched teams

The Truce That Worked

This wasn’t about hating policy.

The real tension? Timing. Ownership. Autonomy.

Things started turning around when the teams stopped fighting the tool—and started reshaping the process:

  1. Policies in staging first
    Devs saw where things broke early—before prod. Diff reports suggested fixes. No more guessing.

  2. Testable policies
    Rego tests lived next to unit tests. CI ran them all. Policy became part of the dev cycle, not a surprise at deploy time.

  3. Scoped enforcement
    No more giant rulebooks. Start small. Add more only when it mattered.

  4. OPA wrappers and abstractions
    DevEx teams built scripts that turned infrastructure code into policy templates. Less boilerplate. Less Rego wrangling.


What They Learned

  1. Policy fatigue is real
    Especially when it shows up late, with no context.

  2. Tooling friction isn’t inevitable
    It usually comes from mismatched expectations.

  3. Engineers aren’t anti-compliance
    They just want visibility, support, and some say in the process.

  4. Policy-as-Code can work well
    When it’s treated like real code—tested, versioned, and owned.


In the end, policy isn’t the enemy of speed or creativity.

It’s how you introduce it that makes the difference.

Handled right, policy isn’t handcuffs. It’s a safety net. One you barely notice—until it matters.

So go ahead, play your tune. Just don’t forget to give the clipboard a seat near the stage.