Last week, @networktocode hosted Netbox Day and it inspired me to dive back into that software and get it running as a Source of Truth for Nornir to automate provisioning, deployment and testing of a demo WAN. #Netbox #Nornir #Python #NetworkAutomation #PythonWithThreeFDDI

Netbox serves as the starting point for Nornir's inventory (instead of the default SimpleInventory) and also server as the location for each device's configuration variables. Devices must be added beforehand with a reachable Primary Management IP for Nornir to connect to.
The configuration variables are held in Netbox's "Config Context" field for each device. While it can be viewed in either JSON or YAML it must be entered in JSON format. Here we've set the variables that will be used for Layer 3 interface and BGP routing configurations.
Script overview:
Initialize Nornir/Netbox
Enable SCP
Get config variables from Netbox
Render config files
Apply Layer 3 configs
Validate Layer 3 connectivity
Apply BGP configs
Validate BGP adjacencies
Update Netbox data
Disable SCP / save configs










The kickoff function pulls some variables from the config file and initializes the Nornir object and the Netbox API object which will be used throughout the rest of the script. It also checks for an empty inventory and prints a banner with a list of devices found.
Variables in the config file include the Netbox URL, disabling the SSL check, the API token and username/password used for Nornir to connect to devices.
SCP functions are Netmiko_send_config tasks. The scp_disable function is used at the end of the script and also includes a netmiko_save_config task.
The get_config_vars function has two steps using the python-netbox module: get the device-id and then get config for that device.
The get_config_vars function has two steps using the python-netbox module: get the device-id and then get config for that device.
Interface and BGP configurations are rendered using Nornir's Jinja2 plugin and written out to text files in the configs directory.
Applying the configs is done through Nornir's napalm_configure plugin using the previously rendered config files. After each step is applied validation occurs. For Layer 3 a ping test is used and for BGP we verify the adjacency is up.
The ping validation got more complicated than I would have liked due to a bug with Nornir's napalm_ping module requiring an explicit source. I submitted a PR that will resolve it in the next release but for now, I had to do some source/destination comparisons to make it work.
BGP validation was a much simpler process using Nornir with a NAPALM "getter" for BGP neighbors and checking if their state was up.
Once all configurations are applied and validated we then update Netbox with the interface details for each device. First we connect to Netbox and the devices to get current data. Below that is a function that will be used later to check if an interface exists in Netbox.
Then we use that data to connect to the Netbox API and update the corresponding fields. Interfaces that don't exist will be created and existing interfaces will be updated. IP addresses will be added to IPAM and associated with their interfaces as well.
And that wraps things up! Huge thanks to @jstretch85 for his work on Netbox and also to @networktocode for hosting last week's event. Link to the code below! #Netbox #Nornir #Python #NetworkAutomation #PythonWithThreeFDDI
https://github.com/ThreeFDDI/nornir-netbox-demo
