Skip to content
Home
Network Automation: Ansible, NAPALM, and CI/CD for Networks

Network Automation: Ansible, NAPALM, and CI/CD for Networks

Computer Networking Computer Networking 8 min read 1492 words Beginner ExcellentWiki Editorial Team

Network automation applies software engineering practices — version control, automated testing, declarative configuration, and CI/CD — to the management of network infrastructure. Instead of logging into switches and typing CLI commands, network engineers write code that provisions devices, validates state, enforces compliance, and rolls back failures automatically. Manual configuration is slow (average 30+ minutes per change for a skilled engineer according to Cisco TAC data), error-prone (roughly 60 percent of network outages are caused by human error per Gartner), and un-auditable. Automation addresses all three problems.

Infrastructure as Code for Networks

Treating network configuration as code means storing all device configurations in a Git repository, making changes through pull requests with peer review, validating the rendered output against compliance rules, and deploying through automated pipelines. This brings to networking the same benefits that infrastructure as code brought to compute: repeatability, version history, peer review, and automated testing.

The Automation Stack

A typical network automation stack comprises:

  1. Source of truth — NetBox or InfraBox stores structured data about devices, interfaces, IP addresses, and connections.
  2. Template engine — Jinja2 generates device-specific configurations from the source of truth.
  3. Configuration deployment — Ansible, Salt, or Nornir pushes configurations to devices.
  4. Validation — Batfish or pyATS validates configurations before deployment.
  5. Testing — pytest with netmiko or scrapli verifies operational state after deployment.

Ansible for Network Automation

Ansible is the most widely adopted network automation tool because of its agentless architecture: no software needs to be installed on the network device. Communication uses SSH (for CLI-based devices) or API calls (for NX-API, NETCONF, or RESTCONF).

Inventory

Ansible inventory defines device groups and connection variables:

# inventory/hosts.yml
all:
  children:
    core:
      hosts:
        core-01:
          ansible_host: 10.0.0.1
        core-02:
          ansible_host: 10.0.0.2
    access:
      hosts:
        access-switch-[01:50]:
          ansible_host: "10.0.1.{{ 1 + loop_index|int }}"
  vars:
    ansible_network_os: cisco.ios.ios
    ansible_user: netadmin
    ansible_connection: ansible.netcommon.network_cli

Network Modules

Ansible provides platform-specific modules that abstract CLI commands into structured YAML:

- name: Configure BGP on Cisco IOS XE
  cisco.ios.ios_bgp:
    config:
      bgp_as: 65001
      router_id: 10.0.0.1
      neighbors:
        - neighbor: 10.0.0.2
          remote_as: 65002
          description: "Core Link to DC2"

Similar modules exist for OSPF, interface configuration, VLANs, ACLs, and VXLAN across Cisco IOS-XE/NX-OS, Juniper JunOS, Arista EOS, and VyOS.

Jinja2 Templating

Templates separate device configuration structure from variables. A source-of-truth database (NetBox, YAML files) feeds variables into templates:

{% for interface in interfaces %}
interface {{ interface.name }}
 description {{ interface.description }}
 ip address {{ interface.ip }} {{ interface.mask }}
{% if interface.mtu is defined %}
 mtu {{ interface.mtu }}
{% endif %}
{% endfor %}

Ansible loops over the template with different variable sets for each device, producing device-specific configurations without manual editing.

NAPALM

NAPALM (Network Automation and Programmability Abstraction Layer with Multivendor support) provides a unified Python API for network devices. It abstracts the differences between Cisco IOS CLI, Juniper JunOS XML, Arista EOS eAPI, and Nokia SR-OS:

from napalm import get_network_driver

driver = get_network_driver("ios")
device = driver(
    hostname="core-switch-01",
    username="netadmin",
    password=get_secret("core-switch-01"),
    optional_args={"port": 22, "conn_timeout": 10},
)
device.open()
facts = device.get_facts()       # Model, serial, OS version
config = device.get_config()      # Running, startup, candidate
device.load_merge_candidate(filename="changes.cfg")
diff = device.compare_config()    # Show changes before commit
if diff:
    device.commit_config()
else:
    device.discard_config()
device.closed()

The compare_config() method outputs a diff identical to what a CLI show would produce. rollback() reverts to the startup configuration if the commit causes problems.

CI/CD for Networks

A network CI/CD pipeline brings automated quality gates to infrastructure changes:

  1. Validate — syntax-check YAML inventory and Jinja2 templates. Reject broken YAML before it reaches a device.
  2. Generate — render configurations for all devices. Store the generated output in a build artifact.
  3. Test offline — run the generated configurations through Batfish to detect BGP peering misconfigurations, duplicate IPs, ACL shadowing, and STP inconsistencies.
  4. Deploy — push configurations to devices, typically in a rolling fashion to minimize impact. If any device fails to accept the configuration, halt the pipeline.
  5. Verify — run post-deployment tests using pyATS or custom playbooks: ping neighbors, verify OSPF adjacency state, check interface error counters.
  6. Rollback on failure — if verification fails, automatically revert to the previous configuration and notify the operator.

Configuration Backup and Compliance

Continuous backup of device configurations is a high-impact early automation win. A daily cron job using Ansible or Rancid (renamed to oxidized for modern use) connects to every device, retrieves the running config, and commits it to a Git repository. Git diffs show exactly what changed and who changed it. Compliance checks (e.g., “ensure SSH timeout is set to 300 seconds”) can be codified using ansible-lint or custom Python scripts and run against the backup repository.

Source of Truth

A source of truth is a centralized database that stores everything known about the network: device models, serial numbers, OS versions, interface names, IP addresses, VLANs, and cabling connections. NetBox is the dominant open-source solution, providing an IPAM/DCIM platform with a REST API for automation integration. When automation tools query the source of truth rather than scraping devices, they produce consistent, validated configurations. The pipeline becomes: source of truth → Jinja2 templates → device configurations → deployment → verification. Discrepancies between the source of truth and device state indicate unauthorized changes or incomplete updates, triggering alerts.

Nornir as an Alternative

While Ansible is the most popular tool, Nornir offers a Python-native automation framework that gives engineers full control over logic and flow. Nornir runs tasks in parallel across devices using pluggable inventory and connection handlers. Unlike Ansible’s declarative YAML playbooks, Nornir tasks are Python functions, enabling complex logic (conditional branching, loops, error handling) that is difficult in Ansible. For teams with strong Python skills, Nornir provides greater flexibility for custom automation. The trade-off: Ansible’s built-in modules and community content reduce the amount of code a team must write and maintain.

NetDevOps Culture

NetDevOps applies development and operations practices to networking. Network configurations are stored in Git with semantic versioning. Changes go through pull requests with mandatory peer review. A CI pipeline validates syntax, runs Batfish analysis, and generates a diff of before-and-after device configurations. Only after automated validation passes and a human approves the PR is the change deployed. Post-deployment, a convergence check confirms all devices reach the intended state. Teams practicing NetDevOps report 70-90 percent fewer configuration-related incidents according to Cisco DevNet surveys. The cultural shift — from “change control board” approval processes to automated, peer-reviewed, validated deployments — is the most challenging but most rewarding aspect of network automation.

Testing Network Changes with Batfish

Batfish is an open-source network configuration analysis tool. It parses device configs (Cisco, Juniper, Arista, Palo Alto, VyOS) and builds a model of the network. It then answers queries: “Which routes are in the RIB?”, “Are there any firewall rules that are shadowed?”, “Is BGP session 10.0.0.2 functioning from both sides?”. Running Batfish in CI catches configuration errors before they reach production:

from pybatfish.client.session import Session

bf = Session(ssl=False)
bf.set_network("production")
bf.init_snapshot("configs/")
result = bf.q.referencedDeviceConfigs().answer()
stale_refs = result.frame()

FAQ

Q: Is network automation only for large enterprises?
A: No. Even small networks benefit from configuration backups (which Git provides for free), templated device configurations (preventing typos), and automated compliance checks. Start with backup and templating; add deployment pipelines as the network grows.

Q: What is the learning curve for network automation?
A: Basic Ansible playbooks can be written within a week by a network engineer familiar with YAML. Python/NAPALM requires more programming comfort. A recommended progression: start with Ansible’s network modules, then add Jinja2 templating, then introduce NAPALM for custom tasks.

Q: Can automation work with legacy equipment?
A: Yes. Ansible and NAPALM support SSH-based CLI access for legacy devices. The constraint is that the device must support SSH and text-based configuration (sending configure terminal commands). Devices that only support serial console access can still be backed up but are harder to automate for writes.

Q: What is the difference between NETCONF/YANG and CLI automation?
A: NETCONF uses structured XML data models (YANG) rather than text strings. It is deterministic (no “screen scraping” of CLI output), supports transactions, and can roll back cleanly. CLI automation sends text commands and parses output with regex, which is brittle. Prefer NETCONF/RESTCONF when the platform supports it.

Q: How do you test network automation changes safely?
A: Use a lab environment (EVE-NG, GNS3, containerlab) to test playbooks before production. Containerlab is the most modern option — it launches containerized network OS instances (Cisco XRd, Arista cEOS, Nokia SR-Linux) on Docker or Podman and enables full CI integration with GitHub Actions.

Internal Links

References

For a comprehensive overview, read our article on Cabling Standards.

For a comprehensive overview, read our article on Cdn Guide.

Section: Computer Networking 1492 words 8 min read Beginner 756 articles in section Report inaccuracy Back to top