Infrastructure as Code: Declarative vs Imperative (And Why Your Automation Still Breaks)
IaC Series – Issue 2 of 6: When Your Network Becomes Software
The Moment Everything Gets Confusing
You start automating your network.
At first, it feels great.
No more clicking around in GUIs.
No more late-night “what changed?” guessing games.
You write a script like this:
Create VLAN 20
Assign ports
Enable trunk
Boom. Automation.
You sit back, sip your coffee, and think:
“Yeah… I’m basically DevOps now.”
Then something weird happens.
You run the same script again…
And now things break.
The Problem You Didn’t Know You Had
Your script isn’t wrong.
It’s just… bossy.
This is what we call imperative automation.
You’re telling the network:
“Do these exact steps. In this exact order. No questions.”
And the network is like:
“Cool… but I already did some of that.”
Now you’ve got:
Duplicate configs
Unexpected errors
Or worse… silent failures
Your automation didn’t fail.
It did exactly what you told it to do.
That’s the problem.
Imperative vs Declarative (The Real Difference)
Let’s make this painfully clear.
Imperative (What most network engineers start with):
create vlan 20
assign ports
enable trunkYou are controlling how the network gets there.
Step by step. Like a checklist.
Declarative (What IaC actually wants):
vlans:
- id: 20
name: usersYou are describing what the network should look like.
Not how to build it.
Here’s the simplest way to think about it:
Imperative: “Do these steps.”
Declarative: “This is the outcome — figure it out.”
Why Your Scripts Break (Even When They’re “Correct”)
Imperative automation assumes one dangerous thing:
The starting state is always what you expect.
It’s almost never true.
Real networks have:
Old configs nobody remembers
Manual changes at 2AM
“Temporary” fixes from 6 months ago
That one engineer who “just tweaked something real quick”
So when your script runs:
Maybe VLAN 20 already exists
Maybe ports are already assigned
Maybe the trunk is already enabled
Now your script either:
Errors out
Overwrites something it shouldn’t
Or quietly does nothing useful
Declarative Thinking Changes Everything
Declarative systems don’t care how things got messed up.
They only care about one thing:
“Does the current state match the desired state?”
If not… fix it.
If yes… do nothing.
That’s why declarative automation is:
Idempotent (safe to run over and over)
Predictable
Much harder to break at scale
Controllers, Templates… and the IaC Confusion
This is where things get a little awkward.
Because a lot of network engineers think:
“We already have templates. We’re basically doing Infrastructure as Code.”
And to be fair… you’re not wrong.
Tools like:
Panorama device groups
Aruba Central group configs
Meraki network templates
Absolutely make your life better.
They give you:
Consistency
Centralized management
Less copy/paste chaos
Compared to pure CLI chaos, that’s a huge step forward.
But Here’s the Problem
They’re not actually Infrastructure as Code.
They’re centralized configuration.
And that’s not the same thing.
Because in most environments:
The source of truth is still the controller UI.
Which means…
Someone logs into the controller
Makes a quick change
Clicks commit
Moves on with their day
And just like that:
The network changed
Nobody reviewed it
Nothing was versioned
No one knows why it changed next week
This Is Still Imperative Thinking (Just With a GUI)
Even with templates, you’re still doing this:
“Go into the controller and make this change.”
That’s imperative.
You’re still telling the system how to change, not defining what it should be.
What IaC Actually Changes
Infrastructure as Code flips the model.
Instead of this:
“Log into the controller and update the template”
You do this:
Define config in a repo
Submit a change
Review it
Merge it
Let automation push it
Now the flow becomes:
Code → Automation → Controller → Devices
Not:
Engineer → Controller → Hope nothing breaks
The Controller’s New Job
In IaC, the controller doesn’t disappear.
It just gets demoted a little 😄
It becomes:
A deployment platform — not the source of truth
Why This Matters More Than People Realize
Because without this shift, you still have:
No real version control
No safe rollback
No audit trail that actually helps
No guarantee your “template” matches reality
You’ve improved consistency…
But you haven’t solved control.
⚠️ Where This Starts Getting Interesting
Because once you stop telling the network how to change…
And start defining what it should be…
You run into a new problem:
How do you actually enforce that state safely?
🔓 What Paid Subscribers Get in This Issue
If your automation only works when you babysit it…
this is the part you don’t want to miss.
In the rest of this issue, I break down:
How to make imperative tools (like Ansible) behave like declarative systems
The 3 rules that turn fragile scripts into safe, repeatable automation
Real-world patterns for checking state before making changes
How to stop writing “run once and pray” automation
Why most network automation fails silently—and how to fix it
This is the difference between:
“I have scripts”
and
“I have automation I actually trust in production”
Keep reading with a 7-day free trial
Subscribe to The Config Report to keep reading this post and get 7 days of free access to the full post archives.


