Network Automation & Programmability

The CLI is dead. Modern networks require speed, consistency, and scale that only code can provide. Welcome to NetDevOps.

1. The Paradigm Shift: Imperative vs Declarative

Historically, engineers typed commands line-by-line. Today, we define the "Intent" and let the controller figure out the "How".

Imperative (CLI) Declarative (Intent-Based)
"Go to interface G1/0/1. Type 'switchport mode access'. Type 'switchport access vlan 10'." "Interface G1/0/1 should be an access port in VLAN 10."
Focus on the Steps. Focus on the End State.
Risk: Configuration Drift (typos, forgotten commands). Benefit: Idempotency (Applying the same config twice changes nothing).

2. Data Formats: Speaking Machine Language

Humans read text. Machines read structured data. You must know how to translate between them.

JSON (JavaScript Object Notation)
{
  "interface": {
    "name": "GigabitEthernet1",
    "enabled": true,
    "ipv4": "192.168.1.1"
  }
}

Used by REST APIs. Strict syntax (quotes, commas).

YAML (YAML Ain't Markup Language)
interface:
  name: GigabitEthernet1
  enabled: true
  ipv4: 192.168.1.1

Used by Ansible. Human-readable. Whitespace sensitive.

XML (Extensible Markup Language)
<interface>
  <name>GigabitEthernet1</name>
  <enabled>true</enabled>
</interface>

Used by NETCONF. Verbose but robust.

3. APIs: RESTCONF vs NETCONF

Screen scraping (SSH + Regex) is fragile. APIs provide a structured way to interact with devices using YANG Models (standardized schemas).

4. Tooling Landscape

Engineer's Notebook: Python vs Ansible

Ansible: Agentless. Uses YAML playbooks. Great for "Day 0/1" provisioning and configuration management. Low barrier to entry.

Python (Netmiko/Nornir/Scrapli): Maximum flexibility. Great for "Day 2" operations, complex logic, validation, and integration with other systems (like Slack/ServiceNow).

Example: Python (Netmiko)

from netmiko import ConnectHandler

cisco_device = {
    'device_type': 'cisco_ios',
    'host':   '10.10.10.10',
    'username': 'admin',
    'password': 'password',
}

net_connect = ConnectHandler(**cisco_device)
output = net_connect.send_command('show ip int brief')
print(output)