Ansible Deep Dive Part 13: Does Ansible Still Matter in an MCP/AI World?

Twelve parts on how to use Ansible well. This last one asks whether any of it still matters, now that a model can be handed shell access and asked to just… fix the thing.

It’s not an abstract question for me. Every post in this series, including this one, was written and published through an MCP server running on my own Ubuntu box, Herald — the same server described across the AI/MCP series elsewhere on this site. I gave Claude write access to my infrastructure well over a year before writing this sentence. So this isn’t “will AI disrupt configuration management” as a hypothetical — I’ve been running the experiment on my own production system the whole time, and the answer it’s produced is more specific than either “yes, obviously” or “no, obviously.”

The case against: why would you still write a playbook?

Here’s the honest version of the disruption argument, because it deserves to be stated well before I push back on it. A modern agent can read a stack trace, understand what a service failing to bind a port means, check whether the process is even running, restart it, tail the logs to confirm it came back clean, and explain in plain English what happened and why — entirely conversationally, no YAML required. For the class of problem that’s genuinely one-off — “why is this specific box slow today” — writing a reusable, idempotent, tested playbook for a question you’ll only ever ask once is real overhead for zero reuse value. An agent that can just go look is strictly faster for that job, and pretending otherwise would be dishonest.

Extend that further: if the agent can reason about desired state from a plain-English description and reach it by whatever means necessary, what’s left for a tool whose entire value proposition is “describe the state you want, and a deterministic engine gets you there”? Isn’t that exactly what the agent is already doing, just without the YAML?

Where that argument breaks: idempotency isn’t optional, it’s the whole point

Run ansible-playbook site.yml against the same host, in the same state, ten times, and you get the exact same nine outcomes and one meaningful change, every time — because Part 3’s idempotency contract is enforced by the module code itself, not by the judgment of whoever’s operating it that day. Ask an agent to “make sure nginx is configured correctly” ten times and you get ten independent bouts of reasoning, each one capable of arriving at a different, individually-reasonable-looking fix. Most of the time that’s fine. The failure mode isn’t “the AI is bad at this” — it’s that reasoning-from-scratch, however good, is not the same category of thing as executing a deterministic function, and infrastructure is exactly the domain where you want the boring, provable kind of correctness rather than the plausible kind.

This is the distinction Part 8’s Molecule idempotence check exists to enforce mechanically: run the same convergence twice, assert nothing changed the second time. That test is only meaningful against something deterministic enough to have a well-defined second run. “Whatever the model decides to do this time” doesn’t have one.

Auditability: the diff you can read before it happens

A playbook is a file. It goes through a pull request. A reviewer reads the diff, understands exactly what will change on which hosts, and approves it before anything touches a real system — and --check --diff (Part 3) shows the actual predicted effect even after that, as a final dry run. That entire review workflow depends on the change being expressed as something static and inspectable ahead of time.

An agent given a broad, freeform mandate — “SSH in and fix it” — collapses the review step into a report of what it already did. You’re reviewing history, not intent. That’s a strictly weaker safety position, and it’s not a hypothetical for me: this project’s own open task list has an entry to harden the mcp-server’s systemd unit specifically because a general write-then-deploy capability is “RCE-by-design” if the blast radius isn’t contained — NoNewPrivileges, ProtectSystem=strict, a restricted ReadWritePaths, all in service of making sure a tool with broad write access can’t do arbitrary damage even when something goes wrong upstream of it.

The actual resolution: well-designed AI tools are Ansible modules wearing a different jacket

Look at how the MCP server on this site is actually built, and the pattern is impossible to miss once you’re looking for it. Claude doesn’t get a raw shell on Herald. It gets write_site_file — writes under src/, public/, and a small allowlist of root configs, nothing else, 1MB capped, atomic. It gets deploy_post — which validates frontmatter, refuses future-dated posts unless explicitly forced, and only then runs the deploy script. It gets delete_site_file, which refuses directories and symlinks outright. Every one of those is a narrow, typed, validated interface wrapped around a specific, bounded action — which is precisely what an Ansible module is: not “run whatever command achieves the goal,” but “here is the one specific state transition this function is allowed to perform, and here’s how it checks whether that transition is even needed.”

The throughline is the same lesson learned twice, a decade apart, in two different domains. Puppet and Chef needed agentless equivalents because a general daemon with broad access was more attack surface than the job required — that’s Part 1. And an LLM with unrestricted shell access is the exact same shape of problem, wearing the fashionable clothing of 2026 instead of 2012. The fix, both times, is the same: replace “broad access, trust the operator’s judgement” with “narrow, typed, idempotent, auditable actions,” whether the operator making the call is a human running ansible-playbook or a model calling an MCP tool.

Where AI genuinely earns its place in this stack

None of the above is an argument that AI has no role here — it has a substantial one, just not the one “does AI replace Ansible” assumes.

Writing the playbook in the first place is a legitimately strong use case — describe the desired end state in plain English, get a first-draft tasks: list back using the right modules, then a human reviews and tests it exactly as they would a colleague’s contribution. Explaining why an idempotence check failed, or why a drift-check playbook (Part 10) just flagged a device, is squarely in an LLM’s strengths — pattern-matching across a diff and a log and producing a plausible explanation is a different task from being trusted to make the change itself. And the genuinely one-off investigative work — “why is this box slow today,” the thing the disruption argument correctly identifies — is exactly where an agent with read access and good judgement outperforms writing a script you’ll run exactly once.

The version of the future I actually believe in isn’t “agents replace playbooks.” It’s closer to: agents author, review, and maintain playbooks, and — when they need to act directly — do it through the same class of narrow, typed, idempotent interface that Ansible modules have always been, rather than through a shell prompt and good intentions. Terraform and Pulumi sit in the same place for provisioning as Ansible does for configuration — desired-state description, plan-before-apply, a diff you review before it’s real — and I’d expect AI’s role there to land the same way: an excellent co-author of the .tf file, not a replacement for having one.

Ansible isn’t a relic waiting for an agent to make it redundant. It’s the substrate that makes agent-driven infrastructure change something you can actually trust — and thirteen parts in, that’s less a prediction than a description of how this very site already runs.