Let’s start with a confession: I think Infrastructure-as-Code solves a lot of problems. Terraform, OpenTofu, Pulumi, all of it. IaC changed how we work. It gave us version control, audit trails, repeatability, and a level of discipline that the old “log in and click around” era couldn’t touch.
But somewhere along the way, we turned that discipline into a kind of dogma. We decided that most every infrastructure change needed to pass through the same elaborate ceremony designed for production, even if it was trivial, temporary, or experimental. Fast forward to today, and the result is that we’ve built a world where spinning up a quick dev environment can feel like applying for a mortgage.
As is often the case in the history of IT innovation, we solved one problem (chaos) and unint…
Let’s start with a confession: I think Infrastructure-as-Code solves a lot of problems. Terraform, OpenTofu, Pulumi, all of it. IaC changed how we work. It gave us version control, audit trails, repeatability, and a level of discipline that the old “log in and click around” era couldn’t touch.
But somewhere along the way, we turned that discipline into a kind of dogma. We decided that most every infrastructure change needed to pass through the same elaborate ceremony designed for production, even if it was trivial, temporary, or experimental. Fast forward to today, and the result is that we’ve built a world where spinning up a quick dev environment can feel like applying for a mortgage.
As is often the case in the history of IT innovation, we solved one problem (chaos) and unintentionally over-rotated into another (rigidity). Between untracked ClickOps and full-blown IaC, there’s now a missing middle ground. I call it the deployment gap, and it’s the space between “move fast” and “don’t break anything” where much of real-world work actually happens.
Let’s peel the layers back on how we got here, why both extremes often are a poor fit, and then look at how a new class of intent-driven, policy-aware tooling can fill the void. Along the way, we’ll discover how the advent of LLMs and MCP has given us an opportunity to expose the choice between ClickOps and IaC as a false dilemma, creatively illustrated as the missing avocado middle.
How We Got Here
Before IaC, infrastructure was a mess of manual clicks and shell scripts. You couldn’t reproduce environments, track who did what, or even be sure the thing running in prod was the same as the thing you tested last week. IaC fixed (almost) all of that. It gave us a shared language, a single source of truth, and the confidence that what’s in Git is what’s in the cloud.
Then GitOps came along and wrapped the whole process in automation and governance. Together, they became the gold standard for production workloads where rigor and traceability matter.
The trouble is that once you have a hammer this good, everything starts to look like a nail. Teams began treating every infrastructure change as if it were production-critical. Need to prototype a new service? Write the Terraform, configure the backend, manage state, wire up CI/CD, get approvals, apply. Even if you’re going to throw it away later this afternoon.
That process is fantastic for uptime. It’s terrible for experimentation.
Meanwhile, developers under pressure to move fast did what developers do: they found workarounds. A few console clicks here, a test bucket there, and you’re in business. It seemed harmless at first, until those one-off resources became orphaned, went unpatched, and got expensive. ClickOps re-entered the picture, quietly and at scale. We call it “unmanaged drift”. We call it “shadow IT”. We call it “brownfield projects”. And what it often is – is people doing their job circumventing the process that’s too tedious, or too difficult to follow. As I’ve been pointing out in some of my other writing – the best way to make people follow the process is to make it more difficult not to do so.
Either way, it’s an outcome that’s the worst of both worlds: fast work that’s untracked and slow work that’s over-engineered.
And the gap between our two extremes got wider.
The Two Extremes
To fix something, you first have to see it clearly. So let’s look at the ends of this spectrum: ClickOps vs IaC + GitOps.
ClickOps is what happens when someone just needs to “get something running.” It’s instant gratification: you click “Create,” and the cloud obediently complies. No syntax errors, no commits, no pipelines. It’s also invisible to your peers, ungoverned by policy, and forgotten the moment you close the browser tab.
Think of it like duct tape: it’s fine for quick fixes, but you don’t want to build your house with it. Every untracked resource adds drift, technical debt, and security risk. Yet the demand for speed that fuels ClickOps is legitimate. When you’re prototyping or debugging, the last thing you want is ceremony.
At the other extreme, Infrastructure-as-Code plus GitOps gives you safety, versioning, policy enforcement, and collaboration. It’s the right choice for anything long-lived or business-critical. But it comes at a cost.
IaC is not just a syntax; it’s a well-developed ecosystem. You need to understand the DSL, the providers, modules, state management, policy engines, and CI/CD. Even for seasoned engineers, the overhead can be heavy. For newcomers, it’s a barrier.
GitOps adds more rigor (approvals, pipelines, reviews) but also more latency. For production, that’s exactly what you want. For a developer who just needs a sandbox to test a feature, it’s like using a cargo container to deliver a pizza.
So, we’ve arrived: at one end, you get velocity without governance, and at the other you get governance without velocity. Both extremes suck when you just want to build.
Filling the Gap: Intent-Driven Infrastructure
What’s missing is a lightweight, governed workflow that bridges speed and safety. Think of it as intent-driven infrastructure: a minimal translation layer between human intent and cloud resources.
The core idea is simple: when I say, “I need a small EC2 instance running Ubuntu,” I shouldn’t have to express that intent as 50 lines of HCL just to get something spun up. That doesn’t mean we abandon rigor. It means that we let the machine handle translation while keeping state, policy, and audit intact.
In an intent-driven model, you describe what you want in plain language via an LLM. The system interprets that intent, applies guardrails, and talks directly to your cloud provider’s APIs. It maintains a known state of what exists, complete with audit history. And when you’re ready for production, you can export that setup into Terraform or your IaC of choice. No YAML, no pipelines, no risk of “rogue” resources. Just speed, but now, with guardrails.
Guardrails Over Gates
One of the big lessons from the DevOps movement is that process gates slow people down, while guardrails keep them safe.
That’s an important distinction. Guardrails are constraints that keep you within safe boundaries while letting you move freely. In an intent-driven world, guardrails look like:
- Policy-as-Code enforcement: No public EC2s, no open S3 buckets, no expensive instance types.
- Session locking: One active session per project to prevent conflicting changes.
- Approval prompts for destructive actions: “Are you sure you want to delete this resource?”
- Drift checks and audit logs: So you always know what changed, by whom, and when.
These aren’t heavyweight governance tools. A more apt analogy is seatbelts. You don’t notice them until you need them, and when you do, they save you (and your cloud bill).
The Lifecycle of an Idea
Let’s map this to a real-world lifecycle.
- Prototype: A developer describes an environment: “Spin up a t3.micro instance with a private IP and attach a policy.” A few minutes, and it’s deployed. The system records what it created and ensures it follows policy.
- Experiment: The team iterates. Maybe it adds a database or a load balancer. Everything is tracked in state, and changes are auditable.
- Promote: Once the concept stabilizes, the environment is exported to IaC. Now it joins the regular GitOps pipeline with full review, versioning, and long-term ownership.
- Clean up: Ephemeral resources are destroyed automatically or on demand, avoiding orphaned costs.
This lifecycle preserves the best of both worlds, where you can finally get fast feedback loops early, but also strong governance later.
The Pressure Making this Idea Necessary, Now
Two forces are converging to make this middle ground essential.
First, AI is shortening feedback loops everywhere. Developers can already prompt a coding assistant to generate app scaffolding in seconds. If infrastructure lags behind, it becomes the new bottleneck. Intent-driven models bring infra up to the same conversational pace without abandoning control.
Second, organizations are under pressure to balance agility and compliance. Security teams can’t afford untracked shadow infrastructure, but they also can’t realistically gate every experiment. A policy-aware, auditable system lets both sides get what they need.
In other words, it’s not about moving fast and breaking things. Rather, it’s about moving fast within guardrails.
Reality Check
Let’s be honest about a few things we tend to gloss over. First, most environments aren’t production. We spend enormous effort on rigor for systems that will live a day or two. That’s wasted energy. Second, speed isn’t reckless—it’s context-dependent. The right level of process depends on the lifespan and risk of what you’re building.
And for what it’s worth, ClickOps isn’t evil. It’s a symptom of a bigger problem. When people click around in the console, they’re telling you your process is too heavy. Listen.
The point is that IaC isn’t the endgame. It was a brilliant step, but it turns out it’s not the final, canonical form of infrastructure management. In many cases describing intent may effectively replace authoring configuration.
Toward a More Human Infrastructure
The longer I work in this space, the more convinced I am that infrastructure shouldn’t feel like programming a compiler. It should feel like collaboration: I express what I need, the system translates it safely, and I stay in control.
That doesn’t mean abandoning code or pipelines. Instead, it means graduating ideas through the right levels of rigor at the right time. We’d use intent-driven workflows for what’s temporary, IaC for what’s durable, and ClickOps for… well, ideally we’d never use ClickOps again.
Another take is to consider that the future of infrastructure isn’t just more YAML. It’s fewer reasons to write YAML in the first place.
Infrastructure-as-Code gave us order. Intent-driven models will give us balance. Because sometimes, you don’t need a hammer or a screw, you just need to build something without smashing your thumb.