Roles
Ansible

Ansible Common Role

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_hostname
  • cisco.nxos.nxos_ntp_global
  • ansible.utils.cli_parse
  • cisco.nxos.nxos_feature
  • cisco.nxos.nxos_evpn_global

Generates

      
  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:

  • Jinja2 template lookups — using ansible.builtin.template to render a Jinja2 template into a variable with set_fact, which is then passed to a module.
  • TextFSM parsing — using ansible.utils.cli_parse to parse CLI output into structured data for comparison and decision-making.
  • Conditional execution — using when to only run tasks when certain conditions are met.
  • Loops — using loop to iterate over lists of features.
  • Blocks — using block to group related tasks under a single conditional.
  • State: overridden — several tasks use 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.

Step 1 - Open Common Role Tasks File

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


Step 2 - Update Common Role Tasks File

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.