In this part of the lab you will extend the local fabric to an external fabric using leaf3
Now you will modify the create_fabric
and add_inventory
roles to extend the local staging
fabric using VRF Lite connecting leaf3
to an external fabric.
roles/create_fabric/tasks/manage_external_fabric.yml
subtask file
code-server -r ~/workspace/ndfclab/ansible/roles/create_fabric/tasks/manage_external_fabric.yml
- name: Query NDFC for Fabric
cisco.dcnm.dcnm_rest:
method: GET
path: "/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/fabrics"
register: create_fabric_result
- name: Intialize create_fabric_ext Flag
ansible.builtin.set_fact:
create_fabric_ext: true
- name: Check If Fabric Exists in NDFC
ansible.builtin.set_fact:
create_fabric_ext: false
when: item.fabricName == fabric_external_settings.FABRIC_NAME
loop: "{{ create_fabric_result.response.DATA }}"
loop_control:
label: "{{ item.fabricName }}"
- name: Check If Fabric Exists in NDFC Log
ansible.builtin.debug:
msg: "Fabric {{ fabric_external_settings.FABRIC_NAME }} Already Exists"
when: not create_fabric_ext
- name: Create External Fabric {{ fabric_external_settings.FABRIC_NAME }} in NDFC
vars:
create_fabric_payload:
BGP_AS: "{{ fabric_external_settings.BGP_AS }}"
IS_READ_ONLY: false
cisco.dcnm.dcnm_rest:
method: POST
path: "/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/fabrics/{{ fabric_external_settings.FABRIC_NAME }}/External_Fabric"
json_data: "{{ create_fabric_payload | to_json }}"
when: create_fabric_ext
After successfully populating the file above, save the file using Ctrl+s on the Windows keyboard or by clicking File then Save.
Be sure to save your file! Not saving will result in your code not executing.
roles/add_inventory/tasks/add_fabric_external_devices.yml
subtask file
code-server -r ~/workspace/ndfclab/ansible/roles/add_inventory/tasks/add_fabric_external_devices.yml
- name: Add switches to {{ fabric_external_settings.FABRIC_NAME }}
cisco.dcnm.dcnm_inventory:
fabric: "{{ fabric_external_settings.FABRIC_NAME }}"
config: "{{ fabric_external_inventory }}"
state: merged
- name: save config of fabric {{ fabric_external_settings.FABRIC_NAME }}
cisco.dcnm.dcnm_rest:
method: POST
path: "/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/fabrics/{{ fabric_external_settings.FABRIC_NAME }}/config-save"
- name: re-deploy inventory {{ fabric_external_settings.FABRIC_NAME }}
cisco.dcnm.dcnm_rest:
path: "/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/fabrics/{{ fabric_external_settings.FABRIC_NAME }}/config-deploy?forceShowRun=false"
method: POST
After successfully populating the file above, save the file using Ctrl+s on the Windows keyboard or by clicking File then Save.
Be sure to save your file! Not saving will result in your code not executing.
build_fabric.yml
Ansible PlaybookMake sure you are in the root Ansible directory and execute the bulid_fabric.yml playbook create the external fabric and add an external router to the fabric.
cd ~/workspace/ndfclab/ansible
From the root ansible project directory execute the following command.
ansible-playbook -i hosts.stage.yml build_fabric.yml --tags cf_external,ai_external
Upon a successful run of the playbook your output should look as follows:
[WARNING]: file /home/cisco/Documents/ndfclab/ansible/roles/manage_interfaces/tasks/loopback_interfaces.yml is empty and had no tasks to include [WARNING]: file /home/cisco/Documents/ndfclab/ansible/roles/add_overlay/tasks/resync_fabric.yml is empty and had no tasks to include [WARNING]: file /home/cisco/Documents/ndfclab/ansible/roles/add_overlay/tasks/add_vrf_lite_vrfs.yml is empty and had no tasks to include [WARNING]: file /home/cisco/Documents/ndfclab/ansible/roles/add_overlay/tasks/add_policies.yml is empty and had no tasks to include PLAY [Build VXLAN EVPN Fabric on NDFC] ************************************************************************************************************************************************************************************ TASK [create_fabric : ansible.builtin.debug] ****************************************************************************************************************************************************************************** ok: [10.15.0.98] => { "msg": [ "----------------------------------------------------------------", "+ Calling Role - [create_fabric] +", "----------------------------------------------------------------" ] } TASK [create_fabric : Get Fabric List] ************************************************************************************************************************************************************************************ ok: [10.15.0.98] TASK [create_fabric : ansible.builtin.set_fact] *************************************************************************************************************************************************************************** ok: [10.15.0.98] TASK [create_fabric : ansible.builtin.set_fact] *************************************************************************************************************************************************************************** skipping: [10.15.0.98] => (item=fabric-stage) skipping: [10.15.0.98] TASK [create_fabric : ansible.builtin.debug] ****************************************************************************************************************************************************************************** skipping: [10.15.0.98] TASK [create_fabric : Create External Fabric on NDFC] ********************************************************************************************************************************************************************* ok: [10.15.0.98] TASK [add_inventory : ansible.builtin.debug] ****************************************************************************************************************************************************************************** ok: [10.15.0.98] => { "msg": [ "----------------------------------------------------------------", "+ Calling Role - [add_inventory] +", "----------------------------------------------------------------" ] } TASK [add_inventory : Add switches to external-fabric-stage] ************************************************************************************************************************************************************** [WARNING]: Adding switches to a VXLAN fabric can take a while. Please be patient... changed: [10.15.0.98] TASK [add_inventory : save config of fabric external-fabric-stage] ******************************************************************************************************************************************************** ok: [10.15.0.98] TASK [add_inventory : re-deploy inventory external-fabric-stage] ********************************************************************************************************************************************************** ok: [10.15.0.98] PLAY RECAP **************************************************************************************************************************************************************************************************************** 10.15.0.98 : ok=8 changed=1 unreachable=0 failed=0 skipped=2 rescued=0 ignored=0
Staging
FabricThis file contains the overlay specific variables for attaching VRF and Networks to leaf devices in your staging fabric.
stage
This data file is going back to being stored in the group_vars/stage
directory like previous sections as it is specific data configuration for your staging or test fabric.
When it comes to your production fabric, similar data specific to your production fabric will be stored in the group_vars/prod
directory.
touch ~/workspace/ndfclab/ansible/group_vars/stage/vrf_lite.yml
cat << EOF > ~/workspace/ndfclab/ansible/group_vars/stage/vrf_lite.yml
---
vrf_lite_attach_group:
all_leaf:
- ip_address: 10.15.30.14
vrf_lite:
- peer_vrf: AnsibleVRF # optional
interface: Ethernet1/1 # mandatory
ipv4_addr: 10.31.0.1/30 # optional
neighbor_ipv4: 10.31.0.2 # optional
dot1q: 2 # dot1q can be got from dcnm/optional
EOF
This step will create the Jinja2 templates that will be used to render the VRF file.
touch ~/workspace/ndfclab/ansible/roles/manage_overlay/templates/vrf_lite_attach_vrfs.j2
cat << EOF > ~/workspace/ndfclab/ansible/roles/manage_overlay/templates/vrf_lite_attach_vrfs.j2
---
# This file is auto-generated
# DO NOT EDIT MANUALLY
#
{% for vrf in vrfs %}
- vrf_name: {{ vrf['vrf_name'] }}
{# ------------------------------------------------------ #}
{# Properties Section #}
{# ------------------------------------------------------ #}
vrf_id: {{ vrf['vrf_id'] }}
vlan_id: {{ vrf['vlan_id'] }}
{# ------------------------------------------------------ #}
{# Attach Group Section #}
{# ------------------------------------------------------ #}
attach:
{% for switch in vrf_lite_attach_group.all_leaf %}
- ip_address: {{ switch['ip_address'] }}
vrf_lite:
{% for vrf_lite_item in switch.vrf_lite %}
- peer_vrf: {{ vrf_lite_item['peer_vrf'] }}
interface: {{ vrf_lite_item['interface'] }}
ipv4_addr: {{ vrf_lite_item['ipv4_addr'] }}
neighbor_ipv4: {{ vrf_lite_item['neighbor_ipv4'] }}
dot1q: {{ vrf_lite_item['dot1q'] }}
{% endfor %}
{% endfor %}
deploy: false
{% endfor %}
EOF
roles/manage_overlay/tasks/add_vrf_lite_vrfs.yml
subtask file
code-server -r ~/workspace/ndfclab/ansible/roles/manage_overlay/tasks/add_vrf_lite_vrfs.yml
# ------------------------
# CREATE VRF-Lite SECTION
# ------------------------
- name: Create file to hold rendered VRF information
ansible.builtin.template:
src: vrf_lite_attach_vrfs.j2
dest: "{{ role_path }}/files/vrf_lite_attach_vrfs.yml"
- name: Create and store generated VRF configuration
ansible.builtin.set_fact:
vrf_config: "{{ lookup('file', 'vrf_lite_attach_vrfs.yml') | from_yaml }}"
# --------------------------------------------------------------------
# Manage VRF-Lite Configuration on NDFC
# --------------------------------------------------------------------
- name: Manage NDFC Fabric VRF-Lite VRFs
cisco.dcnm.dcnm_vrf:
fabric: "{{ fabric_settings.FABRIC_NAME }}"
state: replaced
config: "{{ vrf_config }}"
# --------------------------------------------------------------------
# Save and Deploy Configuration on External Fabric
# --------------------------------------------------------------------
- name: save config of fabric {{ fabric_external_settings.FABRIC_NAME }}
cisco.dcnm.dcnm_rest:
method: POST
path: "/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/fabrics/{{ fabric_external_settings.FABRIC_NAME }}/config-save"
- name: re-deploy inventory {{ fabric_external_settings.FABRIC_NAME }}
cisco.dcnm.dcnm_rest:
path: "/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/fabrics/{{ fabric_external_settings.FABRIC_NAME }}/config-deploy?forceShowRun=false"
method: POST
After successfully populating the file above, save the file using Ctrl+s on the Windows keyboard or by clicking File then Save.
Be sure to save your file! Not saving will result in your code not executing.
roles/add_overlay/tasks/resync_fabric.yml
subtask file
code-server -r ~/workspace/ndfclab/ansible/roles/manage_overlay/tasks/resync_fabric.yml
- name: save config of fabric {{ fabric_settings.FABRIC_NAME }}
cisco.dcnm.dcnm_rest:
method: POST
path: "/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/fabrics/{{ fabric_settings.FABRIC_NAME }}/config-save"
- name: re-deploy inventory {{ fabric_settings.FABRIC_NAME }}
cisco.dcnm.dcnm_rest:
path: "/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/fabrics/{{ fabric_settings.FABRIC_NAME }}/config-deploy?forceShowRun=false"
method: POST
- name: save config of fabric {{ fabric_external_settings.FABRIC_NAME }}
cisco.dcnm.dcnm_rest:
method: POST
path: "/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/fabrics/{{ fabric_external_settings.FABRIC_NAME }}/config-save"
- name: re-deploy inventory {{ fabric_external_settings.FABRIC_NAME }}
cisco.dcnm.dcnm_rest:
path: "/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/fabrics/{{ fabric_external_settings.FABRIC_NAME }}/config-deploy?forceShowRun=false"
method: POST
After successfully populating the file above, save the file using Ctrl+s on the Windows keyboard or by clicking File then Save.
Be sure to save your file! Not saving will result in your code not executing.
build_fabric.yml
Ansible PlaybookMake sure you are in the root Ansible directory and execute the bulid_fabric.yml playbook to use VRF Lite to extend the VRF network to the external fabric
cd ~/workspace/ndfclab/ansible
From the root ansible project directory execute the following command.
ansible-playbook -i hosts.stage.yml build_fabric.yml --tags mo_vrf_lite
Upon a successful run of the playbook your output should look as follows:
[WARNING]: file /home/cisco/Documents/ndfclab/ansible/roles/manage_interfaces/tasks/loopback_interfaces.yml is empty and had no tasks to include [WARNING]: file /home/cisco/Documents/ndfclab/ansible/roles/manage_overlay/tasks/add_policies.yml is empty and had no tasks to include PLAY [Build VXLAN EVPN Fabric on NDFC] ************************************************************************************************************ TASK [manage_overlay : ansible.builtin.debug] ***************************************************************************************************** ok: [10.15.0.98] => { "msg": [ "----------------------------------------------------------------", "+ Calling Role - [manage_overlay] +", "----------------------------------------------------------------" ] } TASK [manage_overlay : save config of fabric fabric-stage] **************************************************************************************** ok: [10.15.0.98] TASK [manage_overlay : re-deploy inventory fabric-stage] ****************************************************************************************** ok: [10.15.0.98] TASK [manage_overlay : save config of fabric external-fabric-stage] ******************************************************************************* ok: [10.15.0.98] TASK [manage_overlay : re-deploy inventory external-fabric-stage] ********************************************************************************* ok: [10.15.0.98] TASK [manage_overlay : Create file to hold rendered VRF information] ****************************************************************************** changed: [10.15.0.98] TASK [manage_overlay : Create and store generated VRF configuration] ****************************************************************************** ok: [10.15.0.98] TASK [manage_overlay : Manage NDFC Fabric VRF-Lite VRFs] ****************************************************************************************** changed: [10.15.0.98] TASK [manage_overlay : save config of fabric external-fabric-stage] ******************************************************************************* ok: [10.15.0.98] TASK [manage_overlay : re-deploy inventory external-fabric-stage] ********************************************************************************* ok: [10.15.0.98] PLAY RECAP **************************************************************************************************************************************** 10.15.0.98 : ok=10 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
roles/manage_interfaces/tasks/loopback_interfaces.yml
subtask file
code-server -r ~/workspace/ndfclab/ansible/roles/manage_interfaces/tasks/loopback_interfaces.yml
- name: Create Loopback Interface On External Router
cisco.dcnm.dcnm_interface:
check_deploy: True
fabric: "{{ fabric_external_settings.FABRIC_NAME }}"
state: merged
config:
- name: "lo0"
type: lo
switch:
- "{{ fabric_external_inventory[0].seed_ip }}"
deploy: true
profile:
admin_state: true
mode: lo
int_vrf: "AnsibleVRF"
ipv4_addr: 172.16.1.1
route_tag: "12345"
cmds:
- no shutdown
description: "Ping Test Loopback"
After successfully populating the file above, save the file using Ctrl+s on the Windows keyboard or by clicking File then Save.
Be sure to save your file! Not saving will result in your code not executing.
roles/manage_overlay/tasks/add_policies.yml
subtask file
code-server -r ~/workspace/ndfclab/ansible/roles/manage_overlay/tasks/add_policies.yml
- name: Create and Apply BGP Network Policy To External Router
cisco.dcnm.dcnm_policy:
fabric: "{{ fabric_external_settings.FABRIC_NAME }}"
state: merged
config:
- switch:
- ip: "{{ fabric_external_inventory[0].seed_ip }}"
policies:
- name: bgp_vrf_network
create_additional_policy: false
priority: 500
policy_vars:
BGP_AS: 65999
VRF_NAME: AnsibleVRF
IP_PREFIX: 172.16.1.1/32
After successfully populating the file above, save the file using Ctrl+s on the Windows keyboard or by clicking File then Save.
Be sure to save your file! Not saving will result in your code not executing.
build_fabric.yml
Ansible PlaybookMake sure you are in the root Ansible directory and execute the bulid_fabric.yml playbook to configure a test loopback interface on the external router, apply bgp policy configuring a BGP network statement to inject a prefix from the external router into the border leaf, and then into the local staging fabric for testing external connectivity
cd ~/workspace/ndfclab/ansible
From the root ansible project directory execute the following command.
ansible-playbook -i hosts.stage.yml build_fabric.yml --tags mi_loopback,mo_policies,mo_resync
Upon a successful run of the playbook your output should look as follows:
PLAY [Build VXLAN EVPN Fabric on NDFC] ********************************************************************************************************************************************************* TASK [manage_interfaces : ansible.builtin.debug] *********************************************************************************************************************************************** ok: [10.15.0.98] => { "msg": [ "----------------------------------------------------------------", "+ Calling Role - [manage_interfaces] +", "----------------------------------------------------------------" ] } TASK [manage_interfaces : Create Loopback Interface On External Router] ************************************************************************************************************************ changed: [10.15.0.98] TASK [add_overlay : ansible.builtin.debug] ***************************************************************************************************************************************************** ok: [10.15.0.98] => { "msg": [ "----------------------------------------------------------------", "+ Calling Role - [add_overlay] +", "----------------------------------------------------------------" ] } TASK [add_overlay : save config of fabric fabric-stage] **************************************************************************************************************************************** ok: [10.15.0.98] TASK [add_overlay : re-deploy inventory fabric-stage] ****************************************************************************************************************************************** ok: [10.15.0.98] TASK [add_overlay : save config of fabric external-fabric-stage] ******************************************************************************************************************************* ok: [10.15.0.98] TASK [add_overlay : re-deploy inventory external-fabric-stage] ********************************************************************************************************************************* ok: [10.15.0.98] TASK [add_overlay : Create and Apply BGP Network Policy To External Router] ******************************************************************************************************************** changed: [10.15.0.98] PLAY RECAP ************************************************************************************************************************************************************************************* 10.15.0.98 : ok=8 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Examine the playbook output above and take note that all of the warnings indicating emtpy task files have disappeared now that you have populated all of the role task files.
In your browser, return to NDFC:
Notice there are 4 switches and the roles are identified for each
You've previously already verified the deployment. You just need to verify the deployment to your new switch.
Now that you have configured a test loopback interface on router staging-ext-rtr and applied a BGP policy to inject the route you can test connectivity from Server1 to the External Loopback IP
The first device you will verify is your Site1-S1 switch. Login to your Site1-S1 switch using the copy command below and paste into your VSCode Terminal. When prompted, the password is cisco.123 .
ssh -l cisco 10.15.30.16
If prompted to accept the RSA key fingerprint like below, type or copy yes then input the password above.
cisco@10.15.27.16's password:
ping -c 5 172.16.1.1
Output:
PING 172.16.1.1 (172.16.1.1): 56 data bytes 64 bytes from 172.16.1.1: seq=0 ttl=253 time=11.631 ms 64 bytes from 172.16.1.1: seq=1 ttl=253 time=10.717 ms 64 bytes from 172.16.1.1: seq=2 ttl=253 time=11.234 ms 64 bytes from 172.16.1.1: seq=3 ttl=253 time=10.291 ms 64 bytes from 172.16.1.1: seq=4 ttl=253 time=11.116 ms --- 172.16.1.1 ping statistics --- 5 packets transmitted, 5 packets received, 0% packet loss round-trip min/avg/max = 10.291/10.997/11.631 ms
exit
On the keyword press Ctrl + K + W
. This should close all open tabs to clear your workspace for the next section.
In the next session you will build a CI/CD to manage our Ansible code using Network or Infrastructure as Code Principles