Skip to content

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:

  1. 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.
  2. 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

  1. In Netbox navigate to Customization > Scripts.

  2. Click on Add in the top right corner.

  3. Select your Data source pod3 and choose your custom-script under netbox/pod3_switches.py.

    Make sure to select Auto sync enabled.

    Example Pod-1:

    Example Pod-1

  4. Now you should see your second custom script among the others.

Step 2: Creating your switch with your custom script

  1. Still in Customization > Scripts, click on your newly created custom script.

    Example Pod-1:

    Example Pod-1

  2. 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:

    Example Pod-1

  3. Click on Run script.

  4. 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

    Example WLSN Pod1

  5. 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.

  1. Open the file nb_inventory.yml located in the folder ansible/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 role branch-switch and that are in planned 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 their tenants, 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.

  2. 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

  1. 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
    
  2. 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
          }
        }
      ]
    }