The overlay role is responsible for configuring the VXLAN EVPN overlay on leaf devices. This includes
VLAN-to-VNI mappings, L3VNI VRF configuration, anycast gateway SVIs, VXLAN VTEP NVE interface configuration,
L2VNI and L3VNI NVE mappings, EVPN VNI route targets, BGP VRF address-families, and Layer 2/Layer 3
interface configuration. Like the other roles, the overlay role leverages the pre-staged Jinja2 templates
to generate configuration payloads using ansible.builtin.template lookups with
set_fact, which are then passed to the corresponding NXOS collection modules.
The overlay role makes use of the following NXOS collection modules:
cisco.nxos.nxos_overlay_globalcisco.nxos.nxos_vlanscisco.nxos.vrf_globalcisco.nxos.nxos_vrf_interfacescisco.nxos.nxos_interfacescisco.nxos.nxos_l3_interfacescisco.nxos.nxos_l2_interfacescisco.nxos.nxos_vxlan_vtepcisco.nxos.nxos_vxlan_vtep_vnicisco.nxos.nxos_evpn_vnicisco.nxos.nxos_bgp_address_familyGenerates
fabric forwarding anycast-gateway-mac 1234.5678.9000
vlan 101
vn-segment 10101
vlan 102
vn-segment 10102
vlan 500
vn-segment 50000
vrf context AnsibleVRF
vni 50000
rd auto
address-family ipv4 unicast
route-target both auto evpn
interface Vlan500
vrf member AnsibleVRF
ip forward
interface Vlan101
vrf member AnsibleVRF
ip address 192.168.1.1/24
fabric forwarding mode anycast-gateway
interface nve1
source-interface loopback1
host-reachability protocol bgp
member vni 50000 associate-vrf
member vni 10101
mcast-group 239.1.1.1
evpn
vni 10101 l2
rd auto
route-target import auto
route-target export auto
router bgp 65001
vrf AnsibleVRF
address-family ipv4 unicast
advertise l2vpn evpn
The overlay role is organized into the following logical sections:
set_fact.state: overridden.state: overridden.Return to your VSCode Terminal to open and build-out the main.yml file found in roles/overlay/tasks/.
code-server -r /home/pod06/workspace/nxapilab/ansible-nxos/roles/overlay/tasks/main.yml
Copy the below YAML into the roles/overlay/tasks/main.yml file that is opened in VSCode. These tasks use the variables you defined in your group_vars and host_vars along with the pre-staged Jinja2 templates to generate each configuration payload before applying it to the devices.
The first section sets the anycast gateway MAC address on leaf switches and configures the VLAN-to-VNI mappings. It then configures the L3VNI VRFs and associates the anycast gateway SVIs with their respective VRFs.
- name: Generate VLAN(s) Payload
ansible.builtin.set_fact:
nxos_vlans: "{{ lookup('ansible.builtin.template', playbook_dir ~ '/templates/config/nxos_vlans.j2') }}"
when: inventory_hostname in groups['leafs']
- name: Configure VLAN-to-VNI Mappings
cisco.nxos.nxos_vlans:
config: "{{ (nxos_vlans | ansible.builtin.from_yaml) }}"
state: overridden
when: inventory_hostname in groups['leafs']
- name: Generate L3VNI VRF(s) Payload
ansible.builtin.set_fact:
nxos_vrfs: "{{ lookup('ansible.builtin.template', playbook_dir ~ '/templates/config/nxos_vrfs.j2') }}"
when: inventory_hostname in groups['leafs']
- name: Configure L3VNI VRF(s)
cisco.nxos.vrf_global:
config: "{{ nxos_vrfs | ansible.builtin.from_yaml }}"
state: overridden
when: inventory_hostname in groups['leafs']
- name: Generate Anycast Gateways VRF Payload
ansible.builtin.set_fact:
nxos_vrf_interfaces: "{{ lookup('ansible.builtin.template', playbook_dir ~ '/templates/config/nxos_vrf_interfaces.j2') }}"
when: inventory_hostname in groups['leafs']
- name: Configure Anycast Gateways VRF Association
cisco.nxos.nxos_vrf_interfaces:
config: "{{ nxos_vrf_interfaces | ansible.builtin.from_yaml }}"
state: overridden
when: inventory_hostname in groups['leafs']
The next section configures Layer 3 interfaces, Layer 2 interfaces, and loopback interfaces with their IP addresses. It also gathers the current interface state and removes any interfaces that are no longer defined in the variables. The VXLAN VTEP NVE interface is configured on leaf switches.
- name: Generate L3 Interface(s) Payload
ansible.builtin.set_fact:
nxos_interfaces: "{{ lookup('ansible.builtin.template', playbook_dir ~ '/templates/config/nxos_interfaces.j2') }}"
- name: Configure L3 Interface(s)
cisco.nxos.nxos_interfaces:
config: "{{ nxos_interfaces | ansible.builtin.from_yaml }}"
state: overridden
- name: Generate L3 Interface(s) IPv4 Payload
ansible.builtin.set_fact:
nxos_l3_interfaces: "{{ lookup('ansible.builtin.template', playbook_dir ~ '/templates/config/nxos_l3_interfaces.j2') }}"
- name: Configure IP Address on L3 Interfaces
cisco.nxos.nxos_l3_interfaces:
config: "{{ nxos_l3_interfaces | ansible.builtin.from_yaml }}"
state: replaced
- name: Generate Loopback Interface(s) IPv4 Payload
ansible.builtin.set_fact:
nxos_loopback_interfaces_ipv4: "{{ lookup('ansible.builtin.template', playbook_dir ~ '/templates/config/nxos_loopback_interfaces_ipv4.j2') }}"
- name: Configure IP Address on Loopback Interfaces
cisco.nxos.nxos_l3_interfaces:
config: "{{ nxos_loopback_interfaces_ipv4 | ansible.builtin.from_yaml }}"
state: merged
- name: Generate L2 Interface(s) Payload
ansible.builtin.set_fact:
nxos_l2_interfaces: "{{ lookup('ansible.builtin.template', playbook_dir ~ '/templates/config/nxos_l2_interfaces.j2') }}"
- name: Configure L2 Interfaces
cisco.nxos.nxos_l2_interfaces:
config: "{{ nxos_l2_interfaces | ansible.builtin.from_yaml }}"
state: replaced
when:
- layer2_physical_interfaces is defined
- layer2_physical_interfaces is iterable
- name: Configure VXLAN VTEP NVE Interface
cisco.nxos.nxos_vxlan_vtep:
interface: nve1
host_reachability: true
source_interface: Loopback1
shutdown: false
state: present
when: inventory_hostname in groups['leafs']
- name: Get Interface(s)
cisco.nxos.nxos_interfaces:
state: gathered
register: current_nxos_interfaces
- name: Generate L3 Interface(s) to Remove Payload
ansible.builtin.set_fact:
nxos_interfaces_to_remove: "{{ lookup('ansible.builtin.template', playbook_dir ~ '/templates/config/nxos_interfaces_to_remove.j2') }}"
- name: Remove L3 Interface(s)
cisco.nxos.nxos_interfaces:
config: "{{ nxos_interfaces_to_remove | ansible.builtin.from_yaml }}"
state: purged
when: nxos_interfaces_to_remove | ansible.builtin.from_yaml | length > 0
The final section configures the VXLAN VTEP NVE interface L3VNI and L2VNI mappings, L2VNI EVPN route targets, and BGP VRF address-families for advertising L2VPN EVPN routes on leaf switches.
- name: Configure VXLAN VTEP NVE Interface L3VNI & L2VNI Mapping(s)
cisco.nxos.nxos_vxlan_vtep_vni:
interface: nve1
vni: "{{ item.vni_id }}"
assoc_vrf: "{{ true if 'vrf' not in item else omit }}"
multicast_group: "{{ item.mcast_grp if 'mcast_grp' in item else omit }}"
state: present
when: >
(item.name is defined and item.name != 'management') or
(item.vlan_id is defined and item.vlan_id != 1)
loop: "{{ vrfs + networks }}"
- name: Get NVE VNIs
ansible.utils.cli_parse:
command: show nve vni | json
parser:
name: ansible.utils.json
set_fact: parsed_output
- name: Normalize VNI Data From Switch
ansible.builtin.set_fact:
switch_vni_list: "{{ [parsed_output.TABLE_nve_vni.ROW_nve_vni] if parsed_output.TABLE_nve_vni.ROW_nve_vni is mapping else parsed_output.TABLE_nve_vni.ROW_nve_vni }}"
- name: Parsed Defined VRFs and Networks VNIs From Switch
ansible.builtin.set_fact:
switch_vnis: "{{ switch_vni_list | map(attribute='vni') | map('int') | list }}"
- name: Parsed Defined VRFs and Networks VNIs From Data
ansible.builtin.set_fact:
defined_vnis: "{{ (vrfs + networks) | selectattr('vni_id', 'defined') | map(attribute='vni_id') | list | unique | default([]) }}"
- name: Determine VNIs to Unconfigure
ansible.builtin.set_fact:
vnis_to_unconfigure: "{{ switch_vnis | difference(defined_vnis) | list }}"
- name: Remove NVE Interface L3VNI & L2VNI Mapping(s)
cisco.nxos.nxos_vxlan_vtep_vni:
interface: nve1
vni: "{{ item }}"
state: absent
when: vnis_to_unconfigure | length > 0
loop: "{{ vnis_to_unconfigure }}"
- name: Configure L2VNI Under EVPN
cisco.nxos.nxos_evpn_vni:
vni: "{{ item.vni_id }}"
route_distinguisher: auto
route_target_both: auto
state: present
when: item.vlan_id != 1
loop: "{{ networks }}"
- name: Remove L2VNI Under EVPN
cisco.nxos.nxos_evpn_vni:
vni: "{{ item }}"
state: absent
when: vnis_to_unconfigure | length > 0
loop: "{{ vnis_to_unconfigure }}"
- name: Generate BGP VRF Address-Family(ies) Payload
ansible.builtin.set_fact:
nxos_bgp_vrf_af: "{{ lookup('ansible.builtin.template', playbook_dir ~ '/templates/config/nxos_bgp_vrf_af.j2') }}"
when: inventory_hostname in groups['leafs']
- name: Configure BGP VRF Address-Family(ies)
cisco.nxos.nxos_bgp_address_family:
config: "{{ nxos_bgp_vrf_af | ansible.builtin.from_yaml }}"
state: overridden
when: inventory_hostname in groups['leafs']
Continue on to the next section for the final pieces needed to execute your Ansible playbook to finish configuring the VXLAN EVPN fabric.