Netmiko vs Ansible: which one, and when
They solve overlapping problems in different ways. The useful question isn't which is better — it's which one fits the task in front of you.
The short version
| Netmiko | Ansible | |
|---|---|---|
| Model | Imperative Python library | Declarative orchestration |
| You write | Scripts | YAML playbooks |
| Idempotent | No — you must build it | Yes, when modules support it |
| Fine control | Complete | Good, but bounded by modules |
| Inventory | Your own file/database | Built in, with groups and vars |
| Best at | Ad-hoc tasks, parsing, backups, data collection | Repeatable state, multi-device rollouts |
| Learning curve | Python | YAML + Ansible concepts |
Use Netmiko when the task is investigative
Anything where you don't know the output in advance: collecting show commands, parsing neighbours, building a topology map, backing up configs, checking interface errors. Netmiko gives you a real SSH session and the raw text, which is exactly what you want.
from netmiko import ConnectHandler
with ConnectHandler(device_type="cisco_ios", host="192.0.2.11",
username="netauto", use_keys=True) as conn:
conn.enable()
output = conn.send_command("show interfaces status")
print(output)
It's also the right tool when the change is conditional on something you just read — "if the port is err-disabled, bounce it" — because you have the data in the same process.
Use Ansible when the task is convergent
"Every access switch should have VLAN 40 with this description and these trunk allowances." Declarative, repeatable, and safe to run twice. Ansible's IOS modules handle the diff and only apply what's missing.
- name: ensure VLAN 40 exists
hosts: access_switches
gather_facts: false
tasks:
- name: vlan 40
cisco.ios.ios_vlans:
config:
- vlan_id: 40
name: cameras
state: merged
Run it with --check --diff first and you get a preview of exactly which devices would change. That preview is the reason Ansible wins for change windows.
Where people get it wrong
Treating Ansible as a scripting language. If your playbook is 200 lines of when: conditions, you wanted Python. Ansible is for state, not logic.
Treating Netmiko as idempotent. It isn't. Running a config script twice re-applies everything. If you need convergence, either check state first or use Ansible.
Ignoring gather_facts: false. On network devices, fact gathering is slow and often fails. Turn it off unless you need it.
The hybrid pattern most networks land on
- Netmiko to collect and verify — what is the device doing right now?
- Ansible to converge — make the intended state true across the group.
- Netmiko again to verify after the change, and to produce the evidence for the change record.
One-off investigation in Python, repeatable state in Ansible, verification back in Python. That's not a compromise; it's each tool doing what it's good at.
Module 6 of Network Automation Lab covers Ansible for IOS with check mode and idempotency; module 7 puts Netmiko and Ansible together for drift detection.