This is part 2 of the CI/CD Demo, on how to run your own demo using CI/CD pipelines for network configuration management. Julio’s previous posts in the NetDevOps Series are available here.

To experience and demonstrate the full NetDevOps configuration pipeline, you may want to setup a local development environment where you can test proposed configuration changes before committing and pushing them to GitLab for the full test builds to occur. This is a completely optional step you might want to skip if you are not interested in testing locally, but I highly recommend going through it, as it provides a more comprehensive approach into what a real-life scenario would look like.

To complete this step, you will need to have a few pre-requisites setup on your local workstation.

1. Common software: install Java JDK, python and sed (brew install gnu-sed in OSX)

2. Network Service Orchestrator: in order to test the configuration pipeline locally, you’ll need to have a local install of NSO on your workstation. Furthermore, you will need to have the same versions of NSO and NEDs (network element drivers) installed as the DevBox within the Sandbox. Using different versions may work, but for best experience matching the versions exactly is recommended.

  • Network Service Orchestrator 4.5.3
  • Cisco IOS NED 5.8
  • Cisco IOS XE NED 6.2.10
  • Cisco NX-OS NED 4.5.10

Once you have downloaded NSO, you would install it on OSX like this:

$ sh nso-4.5.3.darwin.x86_64.signed.bin
$ sh nso-4.5.3.darwin.x86_64.installer.bin ~/ncs-4.5.3 --local-install

You may download the required NEDs from your sandbox devbox via SCP to your own workstation.

$ scp developer@ .
$ scp developer@ .
$ scp developer@ .

Install those NEDs, by running the following two commands for each downloaded binary…

$ sh <bin_file>
$ tar -xzvf <gz_file>

… and then move each uncompressed folder into ~/dev/ncs-4.5.3/packages/neds, replacing the existing ones.

Check all the required NEDs are now installed.

$ ls $NCS_DIR/packages/neds/

Once you have installed these versions, you’ll need to source the ncsrc file for this version before beginning the local development process.

$ source ~/ncs-4.5.3/ncsrc

Note: please don’t forget to include this last command in your startup shell (eg .zshrc, .bashrc or similar)

Now is the time to test your local NSO installation.

First, setup the required structure and environment in your preferred directory.

$ ncs-setup --dest ~/ncs-run

Then start the NCS daemon.

cd ~/ncs-run
$ ncs

Check if NCS started correctly.

$ ncs --status

Start the CLI to connect to NCS…

$ ncs_cli -u admin

… or connect via SSH (default password is admin).

$ ssh -l admin -p 2024 localhost

Point your browser to http://localhost:8080/ (credentials are admin/admin).

If everything works correctly you may now stop the NCS daemon.

$ ncs --stop

Congrats, your NSO local installation is complete!

3. Python + Ansible

The network-as-code mechanism in this demonstration leverages both Ansible and NSO, with Ansible orchestrating the execution and configuration used by NSO to deploy to the network. In order to test locally, you’ll need to have a Python environment (a virtual environment is recommended) that meets these requirements.

  • Python 3.6.5 or higher
  • Ansible 2.6.3 or higher

Once you install them, and with your virtual environment active, now install the requirements.

$ python3 -m venv env
$ source env/bin/activate
$ pip install -r requirements.txt

Let’s now dig into setting up the local environment in your workstation.

1. Clone a copy of the repository from GitLab to your local workstation. Use this specific command to ensure the demo credentials are embedded in the git configuration. Please note this first repo clone might take some time, so you will need to be patient.

$ git clone http://developer:C1sco12345@
$ cd cicd-3tier

2. To simplify the setup and management of the local environment, a Makefile is included in the repository. Simply run make dev to do the following (to see the exact commands being executed for each of these steps, just take a look at the content of your Makefile):

a. Use NCS netsim to start a local simulation of the network including the core, distribution, and access devices
b. Setup a local NCS project directory within the repo, start NCS and import in the netsim simulation
c. Synchronize netsim and NCS
d. Deploy the current network-as-code configuration to NCS and the network devices, using Ansible

$ make dev

Let’s examine what is happening here, by going through the content of the Makefile.

$ cat Makefile

You will see the first line defines the different steps that are part of the dev directive.

dev: netsim nso sync-from dev-deploy

These steps are defined later in the same Makefile. You may also run them independently if you want to execute only that special step (eg. make netsim).

a. Start netsim

    -ncs-netsim --dir netsim create-device cisco-ios core1
    -ncs-netsim --dir netsim add-device cisco-ios core2
    -ncs-netsim --dir netsim add-device cisco-nx dist1
    -ncs-netsim --dir netsim add-device cisco-nx dist2
    -ncs-netsim --dir netsim add-device cisco-nx access1
    -ncs-netsim start

These ncs-netsim commands create netsim devices in the netsim directory, with the specified NEDs (ie. cisco-ios or cisco-nx) and a certain name (ie. coreX, distX, accessX). Then the last step starts them locally in your workstation. netsim devices are a quick and easy way to test configuration changes locally, with no risk.

You may check your netsim devices started correctly and their ports configuration, with:

$ ncs-netsim is-alive
$ ncs-netsim list

You can also connect to your netsim devices CLI, and check with show run that nothing is configured yet. For example, to connect to core1:

$ ncs-netsim cli-c core1

b. Start NSO

-ncs-setup --dest . --package cisco-ios --package cisco-nx

This nso directive prepares the current directory (–dest .) for a local NCS project, with the NEDs it will use (ie. cisco-ios and cisco-nx), and then it starts NCS.

It is important to note that NCS will automatically detect and add existing local netsim devices.

You may login into NSO CLI and check the discovered devices (your netsim devices in this case) with:

$ ncs_cli -C -u admin

admin connected from using console on JGOMEZ2-M-D2KW
admin@ncs# show devices brief
access1 - cisco-nx
core1 - cisco-ios
core2 - cisco-ios
dist1 - cisco-nx
dist2 - cisco-nx

You may also see the devices configuration stored in NSO (not configured yet). For example, for core1:

admin@ncs# show running-config devices device core1

c. Synchronize netsim and NCS

-curl -X POST -u admin:admin http://localhost:8080/api/running/devices/_operations/sync-from

This step will synchronize initial configurations from netsim devices into NCS. Check the configuration of your devices in NCS again, and you will see they include interfaces definitions now (eg. Loopback, Eth, FE).

d. Apply configurations

-ansible-playbook --syntax-check -i inventory/dev.yaml site.yaml
-ansible-playbook -i inventory/dev.yaml site.yaml

This last directive uses Ansible to first check the syntax (linting), and then executes the site.yaml playbook on the list of devices defined in the dev.yaml inventory file.

The inventory file (dev.yaml) lists the devices that will be configured by the playbook, with their hostnames, credentials (if necessary) and management IP addresses:

  • NSO
  • One access switch
  • Two core routers
  • Two distribution switches

Overview: Architecture and Technologies in Play

If you review the playbook itself (site.yaml) you will find it executes the following steps:

  1. Synchronize old configurations from NSO to devices
  2. Push new configurations to NSO
  3. Synchronize new configurations from NSO to devices

Specifically for the second step you might be wondering where are those new configurations?

Take a look at this extract from site.yaml, describing that second step:

- name: Push new configurations to NSO
hosts: all
connection: local
gather_facts: no

    - name: Device configuration
        url: "{{ nso.url }}"
        username: "{{ nso.username }}"
        password: "{{ nso.password }}"
            - name: "{{ nso_device_name }}"
                "{{ config }}"

That tasks description uses the nso_config module, and provides the required NCS URL, username and password, as parameters defined in the inventory file mentioned before.

The data section is the one that describes what configuration to apply, and there you may find you need to provide the device_name and config. Device names come again from the inventory file. BUT configurations are stored in the host_vars directory, where Ansible looks for variables as required. That directory stores individual YAML files, one per device, with the required configuration to apply to NCS devices.

These configuration files in the host_vars directory will be important for us throughout the demo, as they store the configuration we want to apply, and therefore we will use them to apply changes to our network.

After dev_deploy is completed you will see configurations correctly applied (and synchronized) to your netsim devices and NCS ones. You may check it worked fine with the same commands described in previous steps. For example, for core1:

$ ncs-netsim cli-c core1

admin connected from using console on JGOMEZ2-M-D2KW
core1# show running-config


$ ncs_cli -C -u admin

admin connected from using console on JGOMEZ2-M-D2KW
admin@ncs# show running-config devices device core1

(Note: after you complete the rest of this demo, when you don’t need the local environment anymore, you can easily delete everything by running make clean. It will shutdown netsim devices, NSO, and delete any related remnants.)

Your local environment is now completely setup, congrats!

See you next week to explore the actual CICD demo, stay tuned!

Any questions or comments please let me know in the comments section below, Twitter or LinkedIn.


Join DevNet to access the learning labs, docs, and sandboxes you need for network automation.

And check out the NetDevOpsLive! webinar series, and this expert-led, video course for learning network programmability basics.


We’d love to hear what you think. Ask a question or leave a comment below.
And stay connected with Cisco DevNet on social!

Twitter @CiscoDevNet | Facebook | LinkedIn

Visit the new Developer Video Channel


Julio Gomez

Programmability Lead, EMEAR

Systems Engineers