Ansible is an open source community project by Red Hat and is the simplest way to automate your IT. Ansible can be used across entire IT teams, ranging from systems administrators to network administrators to developers and managers. Ansible provides an enterprise-ready, task-based, agentless architecture automation solution for not only servers and software, but also networking starting in Ansible 2.1. Further, the Ansible backend makes extensive use of Python. Cisco is a major supported vendor and here you will focus on Ansible networking automation specific to Open NXOS.
Return to your Visual Studio Code Terminal window.
Ansible is available in two packages: the full ansible package, which is considered
"batteries included" and bundles all community collections, and ansible-core, which
provides only the core engine, built-in plugins, and the ansible-galaxy CLI for
managing collections. In this lab you will install ansible-core so that you install
only the specific collections you need, such as the Cisco NXOS collection, keeping your environment
lightweight and predictable.
Install Ansible Core using
pip install ansible-core==2.18.12
by copying or typing the command into your VSCode Terminal.
cd /home/pod06/workspace/nxapilab
pip install ansible-core==2.18.12
Verify Ansible was installed by checking the version. You'll be working with Ansible Core 2.18.12.
ansible --version
Upon a successful installation and verification of the Ansible version, your output should look as follows:
ansible [core 2.18.12]
config file = None
configured module search path = ['/home/pod06/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /home/pod06/.pyenv/versions/3.11.14/envs/nxapilab/lib/python3.11/site-packages/ansible
ansible collection location = /home/pod06/.ansible/collections:/usr/share/ansible/collections
executable location = /home/pod06/.pyenv/versions/nxapilab/bin/ansible
python version = 3.11.14 (main, Jun 1 2025, 18:28:33) [GCC 11.4.0] (/home/pod06/.pyenv/versions/3.11.14/envs/nxapilab/bin/python)
jinja version = 3.1.6
libyaml = True
Since ansible-core does not include any vendor-specific collections, you need to install
the Cisco NXOS collection separately. Ansible Galaxy is used to install collections from
the community repository. The cisco.nxos collection provides all the NXOS-specific modules
you will use throughout this lab to configure the VXLAN EVPN fabric, such as
cisco.nxos.nxos_hostname, cisco.nxos.nxos_bgp_global, and
cisco.nxos.nxos_vxlan_vtep.
Install the Cisco NXOS collection using ansible-galaxy:
ansible-galaxy collection install cisco.nxos:==11.1.3
Verify the collection was installed successfully:
ansible-galaxy collection list cisco.nxos
Collection Version ----------- ------- cisco.nxos 11.1.3
Install ansible-lint using pip install ansible-lint==26.1.1, which is a linting package that will be
automatically picked up by your VSCode IDE since your Python interpreter was set, and will help you with proper syntax.
pip install ansible-lint==26.1.1
TextFSM is a Python library originally developed by Google that parses semi-structured CLI output (such as
show command output from network devices) into structured data using template files. Each template
defines a state machine with regular expressions that extract specific fields from the raw text output,
converting it into rows and columns that can be easily consumed by automation tools.
In this lab, TextFSM is used with the ansible.utils.cli_parse module to parse CLI output from
NXOS devices into structured data. For example, the common role uses a TextFSM template to parse the output
of show run | include feature into a list of currently enabled features, which is then compared
against the desired feature list to determine which features to enable or disable.
Install TextFSM using pip install textfsm==2.1.0:
pip install textfsm==2.1.0
Ansible calls its configuration and orchestration framework "playbooks" which are a collection of "play(s)" or tasks for
configuration management and deployment to a device or multiple devices in a synchronous or asynchronous fashion.
While playbooks can be represented as a single file,
Ansible best practices recommend a particular directory structure for playbooks that you will be building below.
This directory structure lets you organize files into smaller configuration files for better reuse, particularly
into "roles."
Roles in Ansible are a way to automatically load certain variables, tasks, etc depending on
a categorization. A role can be defined for example by device type or protocol.
In this lab, you are working with two distinct
device types, spine and leaf. When you get to defining your configuration tasks and variables, distinctly
differentiating between device types into separate roles can allow for all spine type devices to be configured
the same and all leaf type devices to be configured the same. Additionally, you could create a third role called
common for any overlapping configuration tasks between the spine and leaf switches. Before creating the configuration
tasks using Ansible network modules, let us create the appropriate directory structure.
In your Terminal window you should be at the top level of your project directory. Create a directory called ansible-nxos, then change directory into your newly created playbooks directory.
mkdir ansible-nxos
cd ansible-nxos
Within the ansible-nxos directory create three more directories: group_vars, host_vars, and roles.
mkdir group_vars
mkdir host_vars
mkdir roles
cd roles
You are going to use Ansible Galaxy to create your roles within the roles directory. Ansible Galaxy is the official community for downloading or creating roles and also where Ansible Collections, such as the NXOS collection you'll be using here, are hosted.
Create common role directory structure:
ansible-galaxy init common
Upon successful creation of the common role, you will see the below line printed to the Terminal window:
- Role common was created successfully
Create underlay role directory structure:
ansible-galaxy init underlay
Upon successful creation of the underlay role, you will see the below line printed to the Terminal window:
- Role underlay was created successfully
Create overlay role directory structure:
ansible-galaxy init overlay
Upon successful creation of the overlay role, you will see the below line printed to the Terminal window:
- Role overlay was created successfully
You are only going to focus on the roles/[role_name]/tasks directory in this lab, so go ahead and remove the other folders.
find /home/pod06/workspace/nxapilab/ansible-nxos/roles/*/ 2>/dev/null -mindepth 1 -name tasks -prune -o -exec rm -rf {} \;
View the structure by issuing the tree command on the roles parent directory.
cd /home/pod06/workspace/nxapilab/ansible-nxos
tree roles/
roles/
├── common
│ └── tasks
│ └── main.yml
├── overlay
│ └── tasks
│ └── main.yml
└── underlay
└── tasks
└── main.yml
6 directories, 3 files
You should see 6 directories, 3 files.
Earlier in this lab you used Jinja2 templates with Python to generate device configurations. Ansible also supports
Jinja2 natively as its templating engine, allowing you to generate dynamic configuration files in the same way.
Jinja2 templates use the .j2 file extension and allow you to embed variables, loops, and conditional
logic directly within configuration templates. With Ansible, the variables defined in your inventory, group vars,
and role vars are automatically passed into these templates to produce unique, device-specific configurations.
A set of pre-configured Jinja2 templates are available for download and will be shared across all three roles — common, underlay, and overlay — to render the configuration for interfaces, PIM, OSPF, and BGP. By using a common set of templates, you ensure consistency across roles while still allowing each role to supply its own variables to produce role-specific configurations.
Download the templates using wget into your ansible-nxos directory:
wget -q -r -np -nH --cut-dirs=1 -A "*.j2" -A "*textfsm" -P /home/pod06/workspace/nxapilab/ansible-nxos/ http://10.0.249.65/files/templates/
Verify the templates were downloaded successfully:
ls -l /home/pod06/workspace/nxapilab/ansible-nxos/templates/config/*.j2
/home/pod06/workspace/nxapilab/ansible-nxos/templates/config/nxos_bgp_af.j2 /home/pod06/workspace/nxapilab/ansible-nxos/templates/config/nxos_bgp.j2 /home/pod06/workspace/nxapilab/ansible-nxos/templates/config/nxos_bgp_vrf_af.j2 /home/pod06/workspace/nxapilab/ansible-nxos/templates/config/nxos_interfaces.j2 /home/pod06/workspace/nxapilab/ansible-nxos/templates/config/nxos_interfaces_to_remove.j2 /home/pod06/workspace/nxapilab/ansible-nxos/templates/config/nxos_l2_interfaces.j2 /home/pod06/workspace/nxapilab/ansible-nxos/templates/config/nxos_l3_interfaces.j2 /home/pod06/workspace/nxapilab/ansible-nxos/templates/config/nxos_loopback_interfaces_ipv4.j2 /home/pod06/workspace/nxapilab/ansible-nxos/templates/config/nxos_ntp_global.j2 /home/pod06/workspace/nxapilab/ansible-nxos/templates/config/nxos_ospf_interfaces.j2 /home/pod06/workspace/nxapilab/ansible-nxos/templates/config/nxos_ospf.j2 /home/pod06/workspace/nxapilab/ansible-nxos/templates/config/nxos_vlans.j2 /home/pod06/workspace/nxapilab/ansible-nxos/templates/config/nxos_vrf_interfaces.j2 /home/pod06/workspace/nxapilab/ansible-nxos/templates/config/nxos_vrfs.j2
In the next section, you will put these roles, tasks, NXOS collection modules, and variables into practice.