The common role is responsible for baseline configuration that applies to all NXOS devices in the fabric, regardless of whether they are spines or leafs. This includes setting the device hostname, configuring NTP, managing NXOS features, and enabling NV overlay EVPN. By placing these tasks in the common role, you avoid duplicating configuration across the underlay and overlay roles.
The common role makes use of the following NXOS collection modules along with the pre-staged Jinja2 templates you copied earlier:
cisco.nxos.nxos_hostnamecisco.nxos.nxos_ntp_globalansible.utils.cli_parsecisco.nxos.nxos_featurecisco.nxos.nxos_evpn_globalGenerates
hostname staging-spine1
!
ntp server 10.81.254.131 use-vrf management prefer
!
feature bgp
feature ospf
feature pim
feature interface-vlan
feature vn-segment-vlan-based
feature nv overlay
!
nv overlay evpn
The common role also introduces several important Ansible concepts:
ansible.builtin.template to render a Jinja2 template
into a variable with set_fact, which is then passed to a module.ansible.utils.cli_parse to parse CLI output into structured
data for comparison and decision-making.when to only run tasks when certain conditions are met.loop to iterate over lists of features.block to group related tasks under a single conditional.state: overridden instead of state: merged.
With overridden, Ansible ensures the device configuration exactly matches what is declared in the
task. Any existing configuration on the device that is not defined in the task will be removed. This is useful for
enforcing a desired state and preventing configuration drift, as opposed to merged which only adds or
updates configuration without removing anything extra.Return to your VSCode Terminal to open and build-out the main.yml file found in roles/common/tasks/ using the VSCode code keyword as before.
code-server -r /home/pod06/workspace/nxapilab/ansible-nxos/roles/common/tasks/main.yml
Copy the below YAML into the roles/common/tasks/main.yml file that is opened in VSCode. These tasks use the variables you defined in your group_vars and host_vars.
The first task configures the device hostname using the hostname variable from host_vars.
The second task uses an ansible.builtin.template lookup to render the NTP Jinja2 template into a
variable, which is then passed to the cisco.nxos.nxos_ntp_global module.
The feature management block uses TextFSM to parse the current features from the switch, compares them against the
desired feature list, removes any unwanted features, and enables the required ones.
Finally, NV overlay EVPN is enabled on all devices.
- name: Configure Hostname
cisco.nxos.nxos_hostname:
config:
hostname: "{{ hostname }}"
state: overridden
- name: Generate NTP Config Payload
ansible.builtin.set_fact:
nxos_ntp_config: "{{ lookup('ansible.builtin.template', playbook_dir ~ '/templates/config/nxos_ntp_global.j2') }}"
- name: Configure NTP Server
cisco.nxos.nxos_ntp_global:
config: "{{ nxos_ntp_config | from_yaml }}"
state: overridden
- name: Manage Features
when: features is defined and features | length > 0
block:
- name: Get Features from Switch via TextFSM
ansible.utils.cli_parse:
command: show run | include feature
parser:
name: ansible.utils.textfsm
template_path: "{{ playbook_dir }}/templates/parse/feature.textfsm"
set_fact: parsed_output
- name: Parse Features
ansible.builtin.set_fact:
parsed_features: "{{ parsed_output | map(attribute='feature') | list | unique | default([]) }}"
- name: Determine Features to Unconfigure
ansible.builtin.set_fact:
features_to_unconfigure: "{{ parsed_features | difference(features) | default([]) }}"
- name: Remove Features
cisco.nxos.nxos_feature:
feature: "{{ item }}"
state: disabled
loop: "{{ features_to_unconfigure }}"
when: features_to_unconfigure | length > 0
- name: Enable Features
cisco.nxos.nxos_feature:
feature: "{{ item }}"
state: enabled
loop: "{{ features }}"
- name: Enable NV Overlay EVPN
cisco.nxos.nxos_evpn_global:
nv_overlay_evpn: true
- name: Configure Anycast Gateway MAC Address
cisco.nxos.nxos_overlay_global:
anycast_gateway_mac: "{{ anycast_gw_mac }}"
when: inventory_hostname in groups['leafs']
Continue on to the next section to build-out the underlay and overlay roles, followed by the final pieces needed to execute your Ansible playbook to finish configuring the VXLAN EVPN fabric.