Declarative vs Imperative Automation: Why It Matters for Infrastructure Success

|

Jul 8, 2025

When teams first start down the automation path, they often begin with what feels familiar: imperative automation.

After all, manual CLI interaction is imperative by nature. You connect to a device, type a command, perform an action. When you start automating, it makes sense to encode those same steps into a script or workflow.

But the more complex your environment becomes, the more this approach starts to break down. You find yourself writing longer scripts, handling more edge cases, tracking more state, and hitting more failures.

Declarative automation offers a fundamentally different and more scalable model for building automation that’s predictable and easy to maintain.

Below, we outline the key differences between declarative vs imperative automation and explain how adopting declarative models can drive more reliable, trustworthy automation for modern infrastructure.

TL;DR

  • Imperative automation encodes the steps to achieve a result. Declarative automation describes the result you want and lets the system figure out the steps.
  • Declarative models are inherently idempotent. Running them produces the same outcome every time – without unintended side effects.
  • Most teams start imperative and gradually shift toward declarative as complexity grows. The goal isn’t to get to 100% declarative. Instead, aim to use declarative approaches wherever they reduce complexity and improve reliability.

Declarative vs imperative automation: Core distinctions

At the heart of the distinction is this:

  • Imperative automation focuses on how to do something. It encodes each action, step by step.
  • Declarative automation focuses on what the end result should be. It describes the desired state.

In an imperative model, if you want to configure a VLAN, you might write 10 steps to make that happen. You’re telling the system exactly what to do.

In a declarative model, you simply describe the outcome: “I want this VLAN on this interface.” The system figures out the necessary steps and reconciles them against the current state.

The difference is huge. If something goes wrong halfway through an imperative workflow, your system can be left in an inconsistent state. Declarative systems, by contrast, are designed to converge on the intended state, making them inherently idempotent and easier to retry safely.

declarative vs imperative automation comparison

Seeing the difference in code

Here is the same task (ensuring VLAN 100 exists and is assigned to an interface) handled both ways.

Imperative approach (Python + Netmiko):

from netmiko import ConnectHandler

device = {
    "device_type": "cisco_ios",
    "host": "192.168.1.1",
    "username": "admin",
    "password": "secret",
}

with ConnectHandler(**device) as conn:
    # Step 1: check if VLAN already exists
    output = conn.send_command("show vlan id 100")
    if "not found" in output:
        # Step 2: create the VLAN
        conn.send_config_set(["vlan 100", "name PROD"])
    
    # Step 3: check current interface config
    output = conn.send_command("show running-config interface GigabitEthernet0/1")
    if "switchport access vlan 100" not in output:
        # Step 4: assign VLAN to interface
        conn.send_config_set([
            "interface GigabitEthernet0/1",
            "switchport mode access",
            "switchport access vlan 100"
        ])
    
    # Step 5: save config
    conn.send_command("write memory")

This script works, but notice what you are responsible for:

  • Checking current state
  • Handling the “already exists” case
  • Sequencing each step
  • Saving the config

If the connection drops after step 3 but before step 4, the VLAN exists but isn’t assigned. Your system is now in an inconsistent state with no automatic recovery path. Scale this to 200 devices across 10 vendors, and the complexity multiplies.

Declarative approach (Ansible):

- name: Ensure VLAN 100 exists and is assigned
  hosts: switches
  tasks:
    - name: Configure VLAN
      cisco.ios.ios_vlans:
        config:
          - vlan_id: 100
            name: PROD
        state: merged

    - name: Assign VLAN to interface
      cisco.ios.ios_l2_interfaces:
        config:
          - name: GigabitEthernet0/1
            access:
              vlan: 100
        state: merged

Describe what you want: VLAN 100 should exist → it should be named PROD → it should be assigned to this interface.

Ansible checks current state, computes the diff, and applies only the changes needed. Run it again on a device where VLAN 100 already exists correctly, and nothing changes.

What happens when something fails midway:

Imperative Declarative
Failure mid-run System left in partial/inconsistent state System retries and converges to desired state
Running again after failure May cause duplicate actions or errors Safe to re-run — only applies missing changes
Auditing what changed Requires manual inspection Diff shows exactly what will change before execution

Why engineers begin with imperative automation

Nearly every engineer starts with imperative automation—because that’s what we’ve always done.

Manual CLI interaction is procedural. So when you first move into automation, it’s natural to translate that process into scripts. But as you automate more of the environment, imperative automation becomes harder to scale.

Each imperative workflow must explicitly interact with every target endpoint. As the number of endpoints and process steps grows, the complexity increases exponentially. Every time a vendor changes and you need to update the workflow, complexity increases again.

imperative automation workflows illustration

Handling state transitions gets more complex. Dependencies and failure points proliferate. Testing and debugging imperative workflows becomes a nightmare.

This snarl of complexity is exactly what declarative models are designed to avoid.

The rising importance of declarative approaches

Declarative automation has already become foundational in many parts of modern infrastructure.

In the cloud, tools like Terraform are already using this model. You define what you want—a VM, a network—and Terraform handles the logic of creating, updating, or deleting resources as needed. You’re no longer writing out step-by-step procedures for each action.

Likewise, Kubernetes has brought declarative principles to container orchestration: you describe the desired state of the system (for example, 5 replicas of an application) and the platform ensures that state is maintained.

These concepts are now spreading into network automation. Declarative automation provides a bridge toward higher-level capabilities, like self-healing networks, where procedural scripts simply can’t scale to handle the complexity.

What declarative looks like in network automation specifically

Terraform and Kubernetes are the most cited examples of declarative automation, but they operate at the cloud and container layer. For network and infrastructure teams, the equivalent tools look like this:

  • Ansible in declarative mode. Ansible can be used both imperatively (a sequence of shell commands) and declaratively (using resource modules like ios_vlans or nxos_interfaces with state: merged). The declarative approach is significantly more reliable at scale.
  • Nornir with desired-state frameworks. Nornir is a Python automation framework that, when combined with libraries like Nornir-NAPALM, supports desired-state configuration management. You define what the device should look like and the framework handles the reconciliation.
  • Infrahub generators. Infrahub’s generator framework lets you define the intended state of your infrastructure in a source of truth and automatically render and apply configurations from that state. Changes flow from data, not from scripts. The source of truth becomes the single definition of desired state, and generators ensure the actual state converges to it.

You define what, the tool figures out how.

How declarative automation builds trustworthy systems

Declarative models directly address the shortcomings of imperative workflows by breaking down complexity and embedding reliability into the system by design.

They support many of the principles that are essential for trustworthy automation:

  • Predictability: Outcomes are more consistent because you define the end state.
  • Idempotency: Re-applying a declarative definition won’t produce unintended changes.
  • Resilience: If partial failures occur, declarative systems can retry or re-converge, reducing the risk of inconsistent state.

Declarative automation and idempotency are tied together by definition. A declarative system is inherently idempotent. You define the end state, and the system figures out how to get there, or back out of it if something goes wrong.

Instead of building one giant workflow that touches everything, declarative systems decompose the work. Smaller workflows—or what we call agents—are in charge of implementing the idempotent declarative workflow on each endpoint.

These agents can be developed and tested independently, which simplifies both the architecture and the engineering effort, while dramatically increasing trust in the system.

declarative automation workflows illustration

Declarative automation and trust by design

Declarative automation naturally supports the three technical foundations of trustworthy automation:

  1. Idempotency ensures repeatable outcomes.
  2. Dry runs show you exactly what changes will be made before anything is executed.
  3. Transactional execution ensures that changes either complete entirely or leave the system unchanged if a failure occurs.

All three of these technical foundations are easy to support with declarative automation, but difficult or impossible to achieve with imperative approaches.

mapping declarative vs imperative automation to design principles

How to shift from imperative to declarative automation

Moving from imperative to declarative automation can be a big mindset shift. Instead of asking “What steps do I need to automate?”, you start asking, “What state do I want the system to be in?”

That also means thinking differently about tooling and architecture.

State representation becomes central. You need a clear source of truth for intended state. Agents and controllers become part of the system, responsible for driving convergence. Testing becomes more about validating that your definitions produce the right state.

In most environments, a mix of approaches is healthy: declarative automation for common configurations at scale, imperative workflows for complex or exceptional cases like OS upgrades.

A pragmatic transition looks something like this:

  1. Start with new workflows, not existing ones. Rather than rewriting your current scripts, adopt a declarative approach for the next thing you automate. Pick something bounded and repeatable, like VLAN management, interface standards, routing policy templates.
  2. Identify your most painful imperative workflows. These scripts break the most, require the most maintenance, or have the most failure modes.
  3. Build your intent data foundation. Before you can tell a system “converge to this state,” you need to know what that state is.
  4. Run both in parallel during the transition. It’s fine to have some workflows imperative and others declarative while you’re shifting.

The goal isn’t to be 100% declarative, but to adopt a declarative approach wherever it reduces complexity and improves reliability.

Common objections

“Our environment is too complex or too legacy for declarative automation.”

Declarative automation doesn’t require a clean, standardized environment to get started, it requires a clear definition of what you want the environment to look like. Brownfield environments are often the ones that benefit most, because they have the most inconsistency for a declarative system to converge away. Start with one device type, define the desired state for a single configuration area, and prove it out before expanding.

“We don’t have a source of truth.”

If your desired state is in scattered YAML files, Git repos, or someone’s head, there’s no way declarative automation is going to work. That being said, even a partial source of truth for one domain is better than none.

“Our team doesn’t know how to write declarative configs.”

Most engineers who have used Ansible in declarative mode, written Kubernetes manifests, or worked with Terraform pick up declarative automation quickly. The harder shift is the mindset, going from “what do I do” to “what should exist.”

Declarative vs imperative at scale

In modern, multi-vendor networks, automation must scale beyond what imperative approaches can handle.

As the cloud world learned years ago, declarative models provide the foundation for that scale: more predictable behavior, better error handling, simpler maintenance, and greater resilience.

Declarative thinking will increasingly shape the next generation of infrastructure automation tools and practices, not as an absolute replacement for imperative methods, but as a smarter default for most automation workflows.

For any team aiming to build infrastructure automation that scales, adapts to complexity, and earns operator trust, adopting declarative approaches is one of the smartest steps you can take.

If you’re trying to make the transition, here are a few extra resources that might help you get there faster:

Wim Van Deun, OpsMill Product Manager

Wim Van Deun | Network and security engineer deep at heart, with automation creds dating back to when Perl and crontab ruled the land. Brings quiet intensity and strategic execution as OpsMill’s Product Manager. Hardcore trail runner based in Belgium.

REQUEST A DEMO

Infrahub logo

See what Infrahub can do for you

Get a personal tour of Infrahub Enterprise

Learn how we can support your infrastructure automation goals

Ask questions and get advice from our automation experts

By submitting this form, I confirm that I have read and agree to OpsMill’s privacy policy.

Fantastic! 🙌

Check your email for a message from our team.

From there, you can pick a demo time that’s convenient for you and invite any colleagues who you want to attend.

We’re looking forward to hearing about your automation goals and exploring how Infrahub can help you meet them.