CCNA 200-301 · 16 of 16

Automation and programmability: when the CLI stops being the interface

Why typing into three hundred devices does not scale, what separating the control plane from the data plane actually buys, REST and the data formats around it, NETCONF and YANG, and what changes for the person who used to type.

Updated 2026-09-09
On this page

Everything in the previous fifteen articles assumed a person at a prompt. That assumption held for thirty years and stopped holding somewhere around the point where a network had more devices than an engineer could visit in a week. The change is not that the CLI disappears — it is that the CLI stops being the interface and becomes an implementation detail, while intent is expressed somewhere it can be reviewed, versioned and applied identically to three hundred devices at once.

The map

Read this first when short on time. Every branch is a section below.

Figure 1. The whole article on one page. Every branch is a section below; fold what you know, open what you do not.

What the CLI cannot do

The command line is excellent at what it was built for: one engineer, one device, full control, immediate feedback. Its limits show up as soon as either number grows.

It does not scale with device count. Adding a VLAN across three hundred switches is the same six commands typed three hundred times. Two minutes each is ten hours, spread over a maintenance window nobody wants to staff.

It produces drift. Three hundred devices configured by hand over five years by a dozen people are three hundred slightly different devices. Nobody knows what is actually deployed, so nobody can predict the effect of a change — and the first accurate inventory usually arrives during an incident.

It has no review step. A command typed into a production device takes effect immediately. There is no diff, no second pair of eyes, no test. This matters because change is the leading cause of outages: not hardware failure, not attacks, but somebody applying something that behaved differently in production than they expected.

Its output is not data. Scripting the CLI means screen-scraping show output written for humans. Column widths shift, fields appear in new software versions, and a script that has worked for two years breaks silently after an upgrade. Parsing formatted text is guessing with extra steps.

In the wild
  • Large operators generate device configurations entirely from a source of truth — an inventory database — so no device is ever configured by hand and drift has nowhere to enter.
  • RANCID and Oxidized were the first widespread response: log in nightly, capture the configuration, commit it to version control, and alert on the diff. Crude and enormously useful.
  • Cloud networking never had a CLI-first era at all, which is why AWS and Azure network configuration was API-driven from the first day.

Control plane, data plane, and what a controller does

Every network device does two separable jobs.

PlaneJobExamples
Control planeDecide how traffic should be forwardedOSPF, spanning tree, ARP, building the routing and MAC tables
Data planeForward each packet according to those decisionsThe hardware lookup that happens millions of times a second
Management planeLet a human or system configure and observe the deviceSSH, SNMP, NETCONF, syslog

Traditionally both planes live in every device, and each device decides for itself. That is robust — there is no single point of failure — and it means the network's behaviour is an emergent result of three hundred independent decisions, which is hard to reason about and harder to change deliberately.

Controller-based networking moves the control plane out. A central controller holds the whole picture, computes what each device should do, and programs it. Devices become forwarders that do what they are told.

flowchart TD
  APP["Applications and scripts"] -->|"northbound API<br/>REST, JSON"| C["Controller<br/>holds the whole topology<br/>and the intended state"]
  C -->|"southbound API<br/>NETCONF, OpenFlow"| D1["Switch"]
  C -->|"southbound"| D2["Switch"]
  C -->|"southbound"| D3["Router"]
Figure 2. The two directions. Northbound faces the people and systems expressing intent; southbound faces the devices. The controller's value is that it is the only thing that has to know both.

The two words worth keeping straight:

The northbound API is the real prize. A request to add a guest network becomes one API call, and the controller works out which of two hundred devices need changing and what to send them. The alternative — a script that knows about every device individually — puts the complexity back where it started.

ProductDomainModel
Cisco DNA CenterCampusController alongside devices that still run their own protocols
Cisco ACIData centrePolicy-based; the fabric is configured from intent
Cisco SD-WANWANCentral policy, tunnels built automatically between sites
MerakiCampus and branchCloud-hosted controller, no on-premises appliance

The trade is honest and worth stating: a controller is a single point of policy, and sometimes a single point of failure. Most designs mitigate it by letting devices keep forwarding on their last known state when the controller is unreachable — the network keeps running, it just stops accepting changes.

REST: HTTP used as an interface

A REST API treats things as resources named by URLs, and uses HTTP verbs to act on them. If you can read a URL, you can mostly read a REST API.

VerbDoesExample
GETRead, changing nothingGET /api/v1/devices
POSTCreate something newPOST /api/v1/vlans
PUTReplace a resource entirelyPUT /api/v1/vlans/20
PATCHChange part of a resourcePATCH /api/v1/vlans/20
DELETERemove itDELETE /api/v1/vlans/20

REST is stateless: every request carries its own authentication and everything else it needs, and the server keeps nothing between calls. That is what lets a load balancer send consecutive requests to different servers, and it is why an API token appears in every single request rather than in a login step.

curl -X GET https://controller.example.com/api/v1/network/vlans \
     -H "Authorization: Bearer eyJhbGciOi..." \
     -H "Accept: application/json"

The response codes are worth knowing because they tell you which side of the problem to look at:

CodeMeansWhose problem
200 / 201 / 204Fine / created / done with no contentNobody's
400The request was malformedYours
401No or bad credentialsYours
403Authenticated, but not permittedYours, or a permissions question
404No such resourceYours — usually a wrong URL
429Too many requestsYours — add a delay
500 / 503The server failed or is unavailableTheirs

The 401 versus 403 distinction saves real time: 401 means the credential was not accepted, 403 means it was accepted and does not have permission. They send you to completely different places.

Three ways to write the same data

Automation moves structured data around, and three encodings dominate. They are equivalent — the same structure written differently — and each is preferred in a different place.

{
  "vlan": {
    "id": 20,
    "name": "GUEST",
    "ports": ["Gi1/0/16", "Gi1/0/17"],
    "enabled": true
  }
}
<vlan>
  <id>20</id>
  <name>GUEST</name>
  <ports>
    <port>Gi1/0/16</port>
    <port>Gi1/0/17</port>
  </ports>
  <enabled>true</enabled>
</vlan>
vlan:
  id: 20
  name: GUEST
  ports:
    - Gi1/0/16
    - Gi1/0/17
  enabled: true
FormatStructure byWhere you meet it
JSONBraces and bracketsREST APIs, RESTCONF, almost every controller
XMLTagsNETCONF, older enterprise systems
YAMLIndentationAnsible playbooks, Kubernetes, files humans write

YAML's use of indentation for structure makes it pleasant to write and unforgiving to get wrong — a tab character where spaces belong produces an error a long way from the actual mistake. That is the price of the readability, and it is why YAML is used for files people author and JSON for data machines exchange.

NETCONF, RESTCONF and YANG

Screen-scraping fails because show output has no schema. Model-driven interfaces fix this properly.

YANG is a modelling language. A YANG model defines exactly what configuration and state data exists for something — what fields an interface has, their types, which are mandatory, what values are legal. It is a contract, published by the vendor or by a standards body such as OpenConfig, and both sides can validate against it.

NETCONF is the protocol that carries YANG-modelled data as XML over SSH, on port 830. Its important property is that it is transactional:

  1. The client locks the configuration so nobody else changes it concurrently.
  2. It writes to a candidate configuration, which is not yet live.
  3. It validates the candidate against the model.
  4. It commits — and all the changes take effect together, or none of them do.
  5. If something is wrong, it rolls back to the previous state.

Compare that with the CLI, where every line takes effect the instant it is typed. A half-applied ACL is a real state a device can be in, and it is often a broken one. NETCONF makes a change atomic, which is the single biggest reliability difference between the two approaches.

RESTCONF exposes the same YANG models over ordinary HTTPS with JSON, which is easier to use from a script and gives up NETCONF's locking and transactions. The choice is the usual one: RESTCONF for convenience, NETCONF where a change must be all-or-nothing.

Router(config)# netconf-yang
Router(config)# restconf
Router(config)# ip http secure-server
Router(config)# username automation privilege 15 secret AutomationPass
SNMPNETCONFRESTCONF
TransportUDPSSH, port 830HTTPS
EncodingBinaryXMLJSON or XML
SchemaMIBsYANGYANG
TransactionsNoYesNo
Used forReading countersConfigurationConfiguration and reading

The tools people actually use

Ansible

The most common choice for network devices, because it is agentless: it connects over SSH or an API and needs nothing installed on the device. Tasks are written in YAML, which is readable by people who are not programmers.

- name: Ensure guest VLAN exists on all access switches
  hosts: access_switches
  gather_facts: false
  tasks:
    - name: Create VLAN 20
      cisco.ios.ios_vlans:
        config:
          - vlan_id: 20
            name: GUEST
            state: active
        state: merged

    - name: Save configuration
      cisco.ios.ios_config:
        save_when: modified

The property that makes this safe is idempotence: running the playbook twice produces the same result as running it once. Ansible checks the current state, and if VLAN 20 already exists with that name it reports "ok" and changes nothing. That is what allows the same playbook to be run against the whole estate regularly, as a way of correcting drift rather than as a one-off change.

Terraform

Declarative and state-aware. You describe the desired end state, Terraform compares it with a recorded state file, and produces a plan — an explicit list of what it will create, change and destroy — before touching anything. The plan is reviewable, which is a meaningful safety property.

It dominates cloud networking, where every resource has a clean API. On traditional network devices it is used less, largely because the device state is harder to model reliably.

Declarative against imperative

ImperativeDeclarative
You writeThe steps to takeThe end state you want
Running it twiceMay do the work twiceChanges nothing the second time
ExampleA Python script issuing commandsAn Ansible playbook or Terraform file
Handles driftNo — it does not know the current stateYes — it corrects back to the described state

The CLI is imperative by nature, which is exactly why it produces drift: it describes a change, not a state, so nothing ever compares the device against what it was supposed to be.

What changes for the person who used to type

The networking knowledge does not change. Everything in the previous fifteen articles is still what you need to know — a controller that builds a broken spanning tree is still a broken spanning tree, and an API that applies the wrong ACL still locks you out. What changes is how the knowledge is delivered.

None of that removes the need to understand what a native VLAN mismatch does, or why an ACL is placed where it is. It makes those decisions reviewable, repeatable and reversible — which is a better place to be doing them from.

In the wild
  • Netmiko and NAPALM are Python libraries that sit between the two eras: Netmiko drives the CLI over SSH reliably, NAPALM offers a common interface across vendors. Both remain widely used where model-driven interfaces are not available.
  • Batfish analyses configurations offline and can answer questions like "after this change, can the guest VLAN still reach the finance server?" without touching a device.
  • Public cloud made this normal outside networking first: nobody configures a load balancer in AWS by hand at scale, and the expectation has steadily moved back into the campus.
Control plane
The part of a device that decides how traffic should be forwarded, as distinct from the data plane that forwards it.
Northbound API
The interface a controller offers to applications and scripts, almost always REST.
Southbound API
The interface a controller uses to program devices — NETCONF, RESTCONF or OpenFlow.
YANG
A modelling language defining exactly what configuration and state data a device exposes, so both sides can validate against a schema.
Idempotent
An operation that produces the same result whether run once or many times — the property that makes automation safe to repeat.

Recap

  • The CLI does not scale with device count, produces configuration drift, has no review step, and its output is text rather than data.
  • Screen-scraping show output breaks silently when a software upgrade changes the format.
  • The control plane decides how to forward, the data plane forwards, and the management plane is how you configure and observe.
  • A controller centralises the control plane; southbound faces devices, northbound faces applications.
  • REST uses HTTP verbs against URLs, is stateless, and carries authentication in every request.
  • 401 means the credential was rejected; 403 means it was accepted but lacks permission.
  • JSON, XML and YAML encode the same structures — JSON on the wire, XML for NETCONF, YAML for files people write.
  • YANG is the schema, NETCONF carries it as XML over SSH with transactions, RESTCONF carries it over HTTPS with JSON and without them.
  • NETCONF's candidate-and-commit model makes a change atomic, which the CLI cannot do.
  • Ansible is agentless and idempotent, so a playbook can be run repeatedly to correct drift.
  • Declarative tools describe the end state and correct drift; imperative scripts describe steps and cannot.
  • The networking knowledge is unchanged — what changes is that configuration lives in version control, is reviewed before it is applied, and is tested before it reaches production.

Questions

Say the answer out loud before opening it.

What are the practical limits of configuring devices by CLI?

It does not scale with device count, it produces drift, it has no review step, and its output is formatted text rather than structured data.

  • The same change across three hundred devices is three hundred manual repetitions.
  • Devices configured by hand over years diverge, so nobody knows what is actually deployed.
  • Commands take effect immediately, with no diff and no second pair of eyes.

The output problem is the subtle one: a script that parses show output can break silently after a software upgrade changes a column width.

What is the difference between the control plane and the data plane?

The control plane decides how traffic should be forwarded; the data plane forwards each packet according to those decisions.

  • OSPF, spanning tree and ARP are control plane; the hardware table lookup is data plane.
  • Traditionally both live in every device and each device decides for itself.
  • The management plane is a third: SSH, SNMP, NETCONF and syslog.

Separating them matters because the control plane is where policy lives, and centralising policy is what makes a network changeable as a whole rather than device by device.

What do northbound and southbound APIs mean?

Southbound is controller to device; northbound is application to controller.

  • Southbound protocols include NETCONF, RESTCONF and OpenFlow.
  • Northbound is almost always REST, consumed by scripts, portals and other systems.
  • The controller is the only component that needs to understand both.

The northbound API is where the value is: a request expressed once becomes whatever changes are needed across however many devices, without the caller knowing anything about them.

What does it mean that REST is stateless?

Every request carries everything needed to serve it, including authentication, and the server keeps nothing between calls.

  • There is no login step that establishes a session the server remembers.
  • A token or key appears in every request's headers.
  • It allows consecutive requests to be handled by different servers behind a load balancer.

It also means the client is responsible for anything sequential, such as paging through a long list, since the server does not remember where the last request left off.

What do the HTTP verbs do in a REST API?

GET reads, POST creates, PUT replaces a whole resource, PATCH modifies part of one, and DELETE removes it.

  • GET should never change anything, which is why it is safe to retry.
  • PUT is idempotent — sending it twice leaves the same result — whereas POST may create two resources.
  • PATCH is used when sending the entire resource would be wasteful or risky.

That idempotence distinction matters for retries: a failed POST cannot simply be repeated without checking whether the first one actually succeeded.

What is the difference between a 401 and a 403?

401 means the credential was missing or not accepted; 403 means it was accepted but does not have permission for this action.

  • 401 sends you to check the token, key or password.
  • 403 sends you to check the account's role or permissions.
  • 404 is different again and usually means the URL is wrong.

Some APIs deliberately return 404 instead of 403 for resources the caller may not see, so that the existence of a resource is not disclosed to someone unauthorised.

When would you use JSON, XML and YAML?

JSON for REST and RESTCONF, XML for NETCONF, and YAML for configuration files that people write and read.

  • All three encode the same structures — objects, lists and scalars.
  • YAML uses indentation, which makes it readable and sensitive to whitespace errors.
  • XML is more verbose but carries namespaces and schema validation, which NETCONF relies on.

The common pipeline is all three at once: a human writes YAML, the tool converts it to JSON or XML on the wire, and the device validates it against a schema.

What is YANG and why does it matter?

A modelling language that defines exactly what configuration and state data a device exposes, including field names, types and constraints.

  • It replaces guessing about text output with validating against a schema.
  • Models can be vendor-specific or standard, such as those from OpenConfig.
  • Both NETCONF and RESTCONF carry YANG-modelled data.

Standard models are the more interesting half, because they make it possible to write one piece of automation that works across vendors rather than one per platform.

Why is NETCONF's transactional model an improvement on the CLI?

Because a set of changes is applied as one unit: it commits entirely or not at all, and can be rolled back.

  • Changes go to a candidate configuration that is validated before being committed.
  • The configuration can be locked so nobody else changes it concurrently.
  • A CLI change takes effect line by line, so a half-applied ACL is a real and often broken state.

This is the single largest reliability difference between the two approaches, and it is why NETCONF is preferred for anything where a partial change would be dangerous.

What does idempotent mean and why does it matter?

An operation produces the same result whether it runs once or many times, so repeating it is safe.

  • An Ansible playbook checks current state and only changes what differs.
  • Running it against the whole estate regularly corrects drift rather than compounding changes.
  • An imperative script that appends a line every time it runs is not idempotent.

It is what turns automation from a one-off change mechanism into a continuous enforcement mechanism, which is the more valuable of the two.

Why is Ansible common for network devices specifically?

Because it is agentless — it connects over SSH or an API and needs nothing installed on the device, which network hardware generally does not allow anyway.

  • Playbooks are YAML, so they are readable without being a programmer.
  • Vendor modules understand device configuration rather than just sending text.
  • It is idempotent, so the same playbook can be run repeatedly.

Puppet and Chef use long-running agents, which suits servers and rules them out for most switches and routers.

What is the difference between declarative and imperative configuration?

Declarative describes the desired end state and lets the tool work out the steps; imperative describes the steps themselves.

  • Declarative tools compare current state with desired state and correct the difference.
  • Imperative scripts do not know the current state, so running them twice may do the work twice.
  • The CLI is imperative, which is precisely why it produces drift.

Terraform's plan step makes the declarative model concrete: it shows exactly what will be created, changed and destroyed before anything happens.

What is configuration drift and how does automation address it?

Drift is the accumulated divergence between what devices are actually configured with and what anyone believes they are configured with; automation addresses it by making a repository the source of truth and reapplying it.

  • Hand-configured devices diverge over years as people make undocumented changes.
  • An idempotent playbook run regularly corrects any device that no longer matches.
  • Nightly configuration capture with a diff surfaces drift even where enforcement is not in place.

The important shift is that the device stops being the authority on its own configuration, so a difference becomes something to fix rather than something to document.

What is the risk of controller-based networking?

The controller is a single point of policy and potentially a single point of failure.

  • A compromised controller can reconfigure the entire network.
  • An unavailable controller means no changes can be made anywhere.
  • Most designs let devices keep forwarding on their last known state, so traffic continues while changes are blocked.

It also concentrates skill: fewer people need to know each device, and more depends on a smaller number who understand the controller and its models.

Does automation reduce the value of understanding networking?

No. It changes how the knowledge is applied, not whether it is needed.

  • An API that applies a wrong ACL locks you out exactly as a typed one does, only faster and on more devices.
  • Reviewing a proposed change requires knowing what it will do.
  • Diagnosing why a controller produced a particular configuration requires understanding the protocols underneath.

What automation removes is the repetition, and what it adds is a review step — both of which make the underlying knowledge more valuable rather than less.