Mission 3: Create devices in Netbox and use Ansible dynamic inventory
Until now, we didn’t use a traditional Ansible inventory because all our tasks were API calls to external systems like Cisco Catalyst Center and Netbox. These API calls were executed from our localhost, and we didn’t need to connect to devices directly. Essentially, localhost served as the only "host" in our playbooks, with the API interactions abstracting the need for a traditional inventory.
Now, we’re moving to use NetBox as a dynamic inventory. NetBox allows us to dynamically retrieve information about network devices and use it as our Ansible inventory. This opens up two key use cases:
-
Connecting to Switches for normal Ansible operations
- By using the NetBox dynamic inventory, we can gather device information (e.g. IP addresses) and use it to connect directly to switches.
- This allows us to run typical Ansible operations, like configuring switches, updating software, or retrieving status information directly from the devices.
-
Using Switch information for deployment in Catalyst Center
- NetBox provides detailed metadata about switches, such as serial numbers, models, and location data.
- We can use this information to populate workflows in Catalyst Center, automating the deployment with minimal manual effort.
Step 1: Adding the custom script from your data source
-
In Netbox navigate to Customization > Scripts.
-
Click on Add in the top right corner.
-
Select your Data source
pod3
and choose your custom-script undernetbox/pod3_switches.py
.Make sure to select Auto sync enabled.
Example Pod-1:
-
Now you should see your second custom script among the others.
Step 2: Creating your switch with your custom script
-
Still in Customization > Scripts, click on your newly created custom script.
Example Pod-1:
-
Fill the form with the following data. Fill in the site you previously created.
Key Value Tenant pod3 Site $YOUR_SITE
Device Type C9KV-UADP-8P Device Role Branch Switch Device Uplink GigabitEthernet1/0/1 Serial Numbers CML13SW1 Commit changes true Example Pod-1:
-
Click on Run script.
-
After the script successfully executed, navigate to Devices > Devices and click on your newly created switch. Verify that all parameters are set correctly:
- Site:
$YOUR_SITE
- Tenant:
ltrops2341 / pod3
- Serial Number:
CML13SW1
- Primary IPv4:
10.99.3.11
- Site:
-
Navigate to IPAM > Prefixes and check if your Pod Prefix
10.99.3.0/24
was created.
Step 3: Creating and using Ansible dynamic inventory with Netbox
Let's explore our dynamic inventory.
-
Open the file
nb_inventory.yml
located in the folderansible/inventory
. The file should contain the following configuration:--- plugin: netbox.netbox.nb_inventory validate_certs: false config_context: false flatten_custom_fields: false site_data: true virtual_chassis_name: true group_names_raw: true query_filters: - role: branch-switch - status: planned group_by: - tenants compose: ccc_template_name: custom_fields.ccc_template_name ccc_pid: device_type.model ccc_ip: primary_ip.address
-
Query Filters: The
query_filters
parameter allows for precise targeting of devices to include in the dynamic inventory. In this example, we are filtering for all devices assigned the rolebranch-switch
and that are inplanned
state. This ensures that only the relevant devices are retrieved from NetBox. -
Grouping Devices: The
group_by
parameter is used to organize the retrieved devices into Ansible groups. Here, we group devices by theirtenants
, meaning that all branch switches belonging to the same tenant will form a group. This enables granular targeting of devices within a specific tenant or pod.In the playbook, you can limit the execution to match only devices in your tenant or pod, as shown below:
- name: Playbook to manage Cisco Catalyst Center Plug and Play using NetBox inventory hosts: pod3
-
Enriching Metadata with Compose: While the dynamic inventory already provides a wealth of device metadata by default, the compose parameter allows you to enrich this metadata further. These additional variables are dynamically included in your inventory, making them readily available for use in playbooks. This customization enhances your automation workflows by providing device-specific attributes tailored to your operational needs.
-
-
To verify if our dynamic inventory works, we can check with
ansible-inventory --list
and limit the devices to your pod with--limit
:ansible-inventory --list -i ./ansible/inventory/nb_inventory.yml --limit pod3
The output should contain your pod-group with your switch in it at the end.
Example Pod-1:
{ "pod1": { "hosts": [ "WLSN-sw1" ] } }
Step 4: Run the Playbook in check-mode with the dynamic inventory
-
We will run this playbook only in check-mode, as we will deploy to Catalyst Center later through a CI/CD pipeline. To run it type the following:
ansible-playbook ./ansible/playbooks/switch_onboarding.yml -i ./ansible/inventory/nb_inventory.yml --check
-
Verify the content of the
pnp_details.claim_switching_devices
output. You should see your switch with all the required parameters to onboard it.Example Pod-1:
{ "pnp_details.claim_switching_devices": [ { "add_device_method": "Single", "device_info": [ { "hostname": "WLSN-sw1", "pid": "C9KV-UADP-8P", "serial_number": "CML11SW1", "state": "Unclaimed" } ], "project_name": "Onboarding Configuration", "site_name": "Global/pod1/EMEA/WLSN", "state": "merged", "template_name": "Ansible_Day0-Template", "template_params": { "Gateway": "10.99.1.1", "Hostname": "WLSN-sw1", "Interfaces": "GigabitEthernet1/0/1", "MgmtVlan": "99", "Portchannel": 1, "SubnetMask": "255.255.255.0", "SwitchIP": "10.99.1.11", "SystemMTU": 1500 } } ] }