This is a continuation of the process of implementing the Break Up network scenario for example.com.
In this Guided Exercise, dynamic advertisement of routes by way of OSPF will not be permitted across network boundaries.
Instead, routes will be explicitly advertised by way of EBGP.
For the purpose of the story, it is to be imagined that the links between networks happen by way of ISP connections to the public internet.
External Border Gateway Protocol is a BGP extension used to advertise routes from neighbor to neighbor between distinct autonomous systems (AS).
These are the business requirements for the final part of the Break Up phase of example.com:
OSPF should be enabled within each of the three autonomous systems, configured to advertise network routes inside the system.
OSPF should not advertise routes across the boundaries of autonomous systems.
Leafs may have a default route that points to the directly connected layer 3 address of their upstream neighbor.
Configure EBGP on edge devices. Advertise routes for networks within each AS by way of BGP. Do not advertise infrastructure-only subnets, unless included by way of route summarization. All three companies agree that their servers should be able to reach servers on any of the three networks, but network devices do not need to be reachable from sources outside of the autonomous system where they reside.
Verify that the servers are reachable from the network, and that all three servers can reach each other.
In this exercise, you will implement EBGP to provide routing and connectivity among otherwise isolated autonomous systems.
Outcomes
You should be able to:
Convert the fully layer 3 interconnected network into three isolated networks.
Add variables to support template-driven configuration.
Create NOS-specific device configuration templates with parameterized configuration statements.
Perform a multivendor play that configures network devices from the updated Jinja2 templates.
Verify that the end result is what was intended.
Open a terminal window on the workstation VM and change to the ~/proj/ directory.
Convert the single, fully layer 3 interconnected OSPF network into three isolated networks.
Prevent spine01 from sending OSPF route announcements out eth5 to cs01.
[student@workstation proj]$ansible -m vyos_config \>-a "lines='set prot ospf passive-interface eth5'" spine01spine01 | SUCCESS => { "changed": true, "commands": [ "set prot ospf passive-interface eth5" ], "filtered": [] }
Prevent spine02 from sending OSPF route announcements out eth5 to cs01.
[student@workstation proj]$ansible -m vyos_config \>-a "lines='set prot ospf passive-interface eth5'" spine02spine02 | SUCCESS => { "changed": true, "commands": [ "set prot ospf passive-interface eth5" ], "filtered": [] }
Prevent cs01 from sending OSPF route announcements out Gi2 and Gi3
Create a Jinja2 template file named j2/ios-ospf-passint-def.j2 with the following content:
router ospf 1 passive-interface default
Create an Ansible Playbook named ios-ospf-passint-def.yml with the following content:
---
- name: set IOS device to OSPF passive interface default
hosts: cs01
vars:
passint_template: j2/ios-ospf-passint-def.j2
tasks:
- name: configure OSPF 1 (process-id 1)
ios_config:
src: "{{ passint_template }}"Perform the play found in your new playbook.
[student@workstation proj]$ansible-playbook ios-ospf-passint-def.ymlPLAY [set IOS device to OSPF passive interface default] ************************ TASK [configure OSPF 1 (process-id 1)] ***************************************** changed: [cs01] PLAY RECAP ********************************************************************* cs01 : ok=1 changed=1 unreachable=0 failed=0
Verify that you now have three, isolated networks.
The spine01 device should now only know about the management network (172.25.250.*) and 10.* networks.
[student@workstation proj]$ansible -m vyos_command \>-a "commands='sh ip ro'" spine01
The spine02 device should only known about the management network and 192.168.* networks.
[student@workstation proj]$ansible -m vyos_command \>-a "commands='sh ip ro'" spine02
The cs01 device should only know about the management network and 172.16.* networks.
[student@workstation proj]$ansible -m ios_command \>-a "commands='sh ip ro'" cs01
Add variables to support template-driven configuration.
If you do not already have a vars file named vars/ebgp-breakup-data.yml, download it now.
[student@workstation proj]$cd vars[student@workstation vars]$wget \>http://materials.example.com/full/vars/ebgp-breakup-data.yml[student@workstation vars]$cd ..[student@workstation proj]$
Create NOS-specific device configuration templates with parameterized configuration statements.
Create a Jinja2 template with EBGP configuration statements for VyOS devices.
Create a file named j2/vyos-bgp.j2 with the following content.
Note the first and third lines of this file are very long; do not include any newlines.
set protocols bgp {{ bgp_data[inventory_hostname]['as'] }} parameters router-id {{ bgp_data[inventory_hostname]['router-id'] | ipaddr("address") }}
{% for nei in bgp_data[inventory_hostname]['neighbors'] %}
set protocols bgp {{ bgp_data[inventory_hostname]['as'] }} neighbor {{ nei['ipv4'] | ipaddr('address') }} remote-as {{ nei['as'] }}
{% endfor %}
{% for net in bgp_data[inventory_hostname]['networks'] %}
set protocols bgp {{ bgp_data[inventory_hostname]['as'] }} network {{ net }}
{% endfor %}
Create a Jinja2 template with EBGP configuration statements for IOS devices.
Create a file named j2/ios-bgp.j2 with the following content.
router bgp {{ bgp_data[inventory_hostname]['as'] }}
{% for net in bgp_data[inventory_hostname]['networks'] %}
network {{ net | ipaddr('network') }} mask {{ net | ipaddr('netmask') }}
{% endfor %}
{% for nei in bgp_data[inventory_hostname]['neighbors'] %}
neighbor {{ nei['ipv4'] | ipaddr('address') }} remote-as {{ nei['as'] }}
{% endfor %}Perform a multivendor play that configures network devices from the updated Jinja2 templates.
Make sure that the border-routers host group exists in the Ansible hosts inventory.
Your inventory file should include the following:
[leafs] leaf[01:02] [spines] spine[01:02][border-routers]spine01spine02cs01[access-layer] leaf01 leaf02 cs01 ...output omitted...
Compose an Ansible Playbook named ebgp-breakup.yml consisting of the following:
---
- name: configure eBGP on VyOS and IOS border routers
hosts: border-routers
vars:
vyos_bgp_tpl: j2/vyos-bgp.j2
ios_bgp_tpl: j2/ios-bgp.j2
vars_files:
- vars/ebgp-breakup-data.yml
tasks:
- name: static routes on cs01 to support non-local BGP routes
ios_config:
lines:
- ip route 10.10.0.0 255.255.0.0 GigabitEthernet2 172.16.2.1
- ip route 192.168.0.0 255.255.0.0 GigabitEthernet3 172.16.5.1
when: inventory_hostname == 'cs01'
- name: "map bgp data to ios device using {{ ios_bgp_tpl }}"
ios_config:
src: "{{ ios_bgp_tpl }}"
when: ansible_network_os == 'ios'
- name: "map bgp data to vyos device using {{ vyos_bgp_tpl }}"
vyos_config:
src: "{{ vyos_bgp_tpl }}"
when: ansible_network_os == 'vyos'
Perform the play found in your new playbook.
Refer to http://materials.example.com/full/j2 if you are having trouble with your templates.
[student@workstation proj]$ansible-playbook ebgp-breakup.yml[student@workstation proj]$ ansible-playbook ebgp-breakup.yml PLAY [configure eBGP on VyOS and IOS border routers] *************************** TASK [static routes on cs01 to support non-local BGP routes] ******************* skipping: [spine01] skipping: [spine02] changed: [cs01] TASK [map bgp data to ios device using j2/ios-bgp.j2] ************************** skipping: [spine01] skipping: [spine02] changed: [cs01] TASK [map bgp data to vyos device using j2/vyos-bgp.j2] ************************ skipping: [cs01] changed: [spine02] changed: [spine01] PLAY RECAP ********************************************************************* cs01 : ok=2 changed=2 unreachable=0 failed=0 spine01 : ok=1 changed=1 unreachable=0 failed=0 spine02 : ok=1 changed=1 unreachable=0 failed=0
Verify that the end result is what was intended.
Perform ad hoc commands to verify neighbor status.
The cs01 device should see two neighbors.
[student@workstation proj]$ansible -m ios_command \>-a "commands='sh ip bgp sum'" cs01
The spine01 and spine02 devices should see one neighbor each.
[student@workstation proj]$ansible -m vyos_command \>-a "commands='sh ip bgp sum'" spines
Perform the play found in the e2e.yml playbook you created earlier.
[student@workstation proj]$ansible-playbook e2e.yml
If all goes well, the play recap should show failed=0 for each device.
PLAY RECAP ********************************************************************* cs01 : ok=3 changed=0 unreachable=0 failed=0 leaf01 : ok=2 changed=0 unreachable=0 failed=0 leaf02 : ok=2 changed=0 unreachable=0 failed=0
This concludes the guided exercise.