Lesson 3 of 5

Configuration Change with NSO

Objective

In this lesson you will use Cisco NSO to make a configuration change on a network device using a safe change-management workflow: perform a dry-run to validate the change, commit the change to the device, and rollback the change if required. This matters in production because orchestration systems like NSO let operators test changes against device models before applying them, preventing outages caused by syntax errors or policy violations. Real-world scenario: pushing a new loopback and static route to a router in a multi-site enterprise where automation must guarantee no disruption to routing and allow fast rollback if an issue is detected.

Quick Recap

Reference the topology used in Lesson 1. No new devices are added for this lesson. We will use the NSO server and Router R1 from the existing lab:

ASCII topology (management network and in-band link shown):

[NSO Server] ncs.lab.nhprep.com
  mgmt0: 192.168.100.10/24
        |
        | 192.168.100.0/24 (mgmt network)
        |
[Router R1] R1
  Loopback0: 10.0.0.1/32
  GigabitEthernet0/0 (mgmt): 192.168.100.11/24
  GigabitEthernet0/1 (in-band): 203.0.113.1/24

Device table

DeviceHostnameManagement IPDevice OS/TypeUsername
NSO serverncs192.168.100.10NSO (ncs)admin
RouterR1192.168.100.11IOS routeradmin

Credentials used in examples:

  • Username: admin
  • Password: Lab@123
  • Domain used in examples: lab.nhprep.com
  • Organization: NHPREP

Tip: The management network (192.168.100.0/24) isolates orchestration traffic from production forwarding. In production deployments you typically use a dedicated management VLAN/subnet exactly for this reason.

Key Concepts

Before making changes with NSO you need to understand these core principles:

  • Configuration candidate vs running: NSO edits a candidate configuration (a transactional workspace) and can validate it (dry-run) before committing it to device running-configs. Think of the candidate as a staging area — like drafting an email before sending it.
  • Dry-run (validation): A dry-run verifies that the proposed change is syntactically and semantically valid against the device model and, when applicable, against the live device state. It prevents accidental invalid configuration from being pushed.
  • Commit and atomicity: A commit in NSO is atomic — either the full change set is applied to all targeted devices, or the operation fails and NSO keeps state consistent. In production this prevents partial deployments.
  • Rollback / versions: NSO maintains configuration history; you can rollback to a previous committed state. This is critical for quick recovery when a change causes unexpected behavior.
  • Device modeling and NETCONF/CLI: NSO interacts with devices using device adapters (e.g., NETCONF, CLI). Understanding the protocol used matters because behavior (validation, rollback support) differs by adapter.

Real-world note: In production, teams use dry-runs in change windows to ensure a change won’t break routing, and keep rollback steps documented for every change.

Step-by-step configuration

We will: 1) Create a candidate config in NSO that adds a Loopback100 to R1 and a matching static route on the router, 2) perform a dry-run to validate, 3) commit the change, 4) demonstrate a rollback to the previous state.

Step 1: Open NSO CLI and enter configuration mode

What we are doing: Connect to the NSO server CLI and enter NSO configuration mode so we can edit device configurations in the NSO candidate datastore.

ssh admin@192.168.100.10
# password: Lab@123

# once on the NSO server
ncs@ncs:~$ ncs_cli -u admin
admin@ncs> config
admin@ncs(config)>

What just happened:

  • The SSH command connects you to the NSO host (192.168.100.10) using the admin account.
  • ncs_cli -u admin launches the NSO command shell.
  • config places you into NSO configuration mode where edits are staged in a candidate datastore. Edits here are not yet applied to devices until you commit.

Real-world note: Using NSO configuration mode is equivalent to editing a transactional database — this prevents partial changes from being applied directly to devices.

Verify:

admin@ncs(config)> show configuration
# Expected output shows current NSO configuration and no uncommitted changes.
# Example (complete expected output)
system {
  admin {
    user admin {
      password "$1$xxxxxxxx";   # hashed password
      full-name "NSO Admin";
    }
  }
}
devices {
  device R1 {
    address 192.168.100.11;
    authgroup default;
    type cli;
  }
}
admin@ncs(config)> show config session
# Expected output:
# No active config sessions or uncommitted changes.

Step 2: Add a Loopback interface to R1 in the candidate

What we are doing: Add a new Loopback100 with IP 10.1.100.1/32 on R1 via NSO candidate configuration. This is a staged change only — NSO will send it to the device only after commit.

admin@ncs(config)> devices device R1 config
admin@ncs(config-device)# interface Loopback100
admin@ncs(config-device-if)# ip address 10.1.100.1 255.255.255.255
admin@ncs(config-device-if)# exit
admin@ncs(config-device)# exit

What just happened:

  • devices device R1 config selects the device configuration subtree in the NSO candidate.
  • The interface Loopback100 and ip address ... lines create interface configuration under the device configuration subtree. These commands update NSO's candidate datastore, not the router yet.
  • At protocol level, NSO has recorded the desired config. NSO will prepare device-specific commands for the adapter (CLI or NETCONF) when commit is executed.

Real-world note: Loopbacks are commonly used for stable router identifiers, routing protocols, and management IPs. Adding them through NSO ensures consistent naming and templating across multiple devices.

Verify:

admin@ncs(config)> show configuration devices device R1
# Expected output (complete expected output):
devices {
  device R1 {
    address 192.168.100.11;
    config {
      interface {
        Loopback100 {
          ip {
            address 10.1.100.1 {
              netmask 255.255.255.255;
            }
          }
        }
      }
    }
  }
}

Step 3: Add a static route on R1 in the candidate

What we are doing: Add a static route for 10.2.0.0/24 via next-hop 203.0.113.254 in the candidate configuration on R1. This demonstrates multi-object changes grouped in one transaction.

admin@ncs(config)> devices device R1 config
admin@ncs(config-device)# ip route 10.2.0.0 255.255.255.0 203.0.113.254
admin@ncs(config-device)# exit

What just happened:

  • The static route command was added to NSO's candidate datastore under R1. NSO will apply this route when changes are committed. Grouping interface and routing changes in one candidate ensures that they are applied together atomically.

Real-world note: Many production changes involve multiple related edits (interface + route). NSO’s transaction model guarantees either all or none are applied.

Verify:

admin@ncs(config)> show configuration devices device R1
# Expected output (complete expected output):
devices {
  device R1 {
    address 192.168.100.11;
    config {
      interface {
        Loopback100 {
          ip {
            address 10.1.100.1 {
              netmask 255.255.255.255;
            }
          }
        }
      }
      ip {
        route {
          "10.2.0.0/24" {
            next-hop 203.0.113.254;
          }
        }
      }
    }
  }
}

Step 4: Perform a dry-run (validation)

What we are doing: Run a dry-run commit so NSO validates the candidate against device models and (if supported by the adapter) checks the device will accept the change. This finds issues before touching devices.

admin@ncs(config)> commit dry-run
# Expected output:
# DRY-RUN: Starting dry-run commit for current candidate
# DRY-RUN: Validating device R1 configuration...
# DRY-RUN: Validation successful, no conflicts found. No changes applied to devices.
# DRY-RUN: Completed

What just happened:

  • commit dry-run instructs NSO to validate the candidate configuration without pushing it to devices. NSO runs model validations and syntax checks, and may simulate device acceptance based on the adapter. This prevents execution of erroneous commands on production devices.

Real-world note: Always perform a dry-run for changes during maintenance windows and for any change touching multiple devices. Dry-runs are especially important when templates or parameterized configs are used.

Verify:

admin@ncs(config)> show dry-run status
# Expected output:
# Last dry-run: success
# Devices validated: R1
# No changes applied

Step 5: Commit the change to devices

What we are doing: Apply (commit) the validated candidate to the device. NSO will translate the candidate into device-specific commands and push them using the configured adapter (e.g., CLI over SSH).

admin@ncs(config)> commit
# Expected output:
# Committing changes to devices...
# Device R1: connecting to 192.168.100.11...
# Device R1: sending configuration...
# Device R1: commit succeeded
# Commit completed

What just happened:

  • commit sends the candidate changes to the target device(s). NSO performs the push operation and waits for adapters to report success. The operation is transactional at the NSO level — if a failure occurs on one device in a multi-device commit, NSO will attempt to maintain consistency per its rollback rules.

Real-world note: For devices using pure CLI adapters, NSO sequences CLI commands and checks for expected prompts/outputs. For NETCONF-capable devices, NSO can perform more granular validation and rollback depending on the device’s capabilities.

Verify (on NSO):

admin@ncs(config)> show configuration devices device R1
# Expected output:
devices {
  device R1 {
    address 192.168.100.11;
    config {
      interface {
        Loopback100 {
          ip {
            address 10.1.100.1 {
              netmask 255.255.255.255;
            }
          }
        }
      }
      ip {
        route {
          "10.2.0.0/24" {
            next-hop 203.0.113.254;
          }
        }
      }
    }
  }
}

Verify (directly on Router R1):

ssh admin@192.168.100.11
# password: Lab@123

R1# show running-config interface Loopback100
! Expected complete output:
interface Loopback100
 ip address 10.1.100.1 255.255.255.255
!

R1# show ip route 10.2.0.0
! Expected complete output (static route present):
S    10.2.0.0/24 [1/0] via 203.0.113.254

Step 6: Rollback the change

What we are doing: Demonstrate rolling back to the previous configuration commit using NSO’s rollback capability, returning R1 to its prior state.

admin@ncs(config)> show commit-history
# Expected output:
# Commit ID: 1
# User: admin
# Time: 2026-04-02 10:12:00
# Summary: Added Loopback100 and static route
# Commit ID: 0
# User: initial
# Time: 2026-04-02 09:00:00
# Summary: Initial device config

admin@ncs(config)> rollback 0
# Expected output:
# Rolling back to commit 0...
# Device R1: connecting to 192.168.100.11...
# Device R1: applying rollback...
# Device R1: rollback succeeded
# Rollback completed

What just happened:

  • show commit-history lists NSO commit snapshots with IDs and metadata. rollback 0 instructs NSO to restore the device configuration to the state recorded at commit ID 0. NSO applies the necessary commands to remove the changes performed by commit 1.
  • Rollback is a critical safety net: if a change causes an outage, you can quickly restore a known-good configuration.

Real-world note: Rollbacks can vary in completeness depending on the adapter and device. Some device platforms support atomic rollbacks; others require NSO to compute inverse CLI commands. Always verify the device behavior after a rollback.

Verify (directly on Router R1):

R1# show running-config interface Loopback100
! Expected complete output if rollback succeeded:
% Interface Loopback100 not found

R1# show ip route 10.2.0.0
! Expected complete output:
% Network not in table

Verification Checklist

  • Check 1: NSO candidate contained the intended changes — verify with show configuration devices device R1.
    • How to verify: admin@ncs(config)> show configuration devices device R1 and confirm Loopback100 and static route are present in the candidate before commit (or present in running config after commit).
  • Check 2: Dry-run succeeded and reported no conflicts.
    • How to verify: admin@ncs(config)> commit dry-run success messages, or show dry-run status.
  • Check 3: Commit applied changes to R1.
    • How to verify: SSH into R1 and run show running-config interface Loopback100 and show ip route 10.2.0.0.
  • Check 4: Rollback restored the previous state.
    • How to verify: Run show commit-history in NSO, execute rollback <id>, then verify R1 no longer has Loopback100 or the static route.

Common Mistakes

SymptomCauseFix
Dry-run reports validation error for interface IP overlapCandidate IP conflicts with an existing interface or address poolCheck existing device config with show running-config and adjust the candidate IP to avoid overlap
Commit fails with authentication/connection error to deviceWrong management IP, credentials, or network reachabilityVerify access: ping 192.168.100.11 from NSO and check device credentials; update device entry in NSO authgroup if needed
Rollback completes but device still shows config changesDevice adapter does not support atomic rollback or inverse commands failedManually inspect device running-config and, if needed, remove the offending config directly on device and record the action in NSO
Changes applied unexpectedly to multiple devicesTargeting the wrong device subtree or using a template with broad scopeRe-check the devices device <name> path in NSO candidate and use device-specific templates or constraints

Key Takeaways

  • NSO provides a transactional configuration model: changes are made in a candidate datastore, validated (dry-run), then committed. This reduces risk in production.
  • Always perform a dry-run on critical changes — it catches model and syntax errors before devices are affected.
  • Commit operations are atomic at the NSO level; treating related changes as a single transaction prevents partial deployments.
  • Maintain commit history and test rollback procedures — rollbacks are essential for rapid recovery but may behave differently depending on device adapters.

Final tip: Incorporate NSO dry-runs and commit/rollback steps into your change control runbooks and automation pipelines. In production environments, that practice reduces human error and shortens mean-time-to-repair when issues occur.