Day 0 Provisioning
Day 0 provisioning workflows with AOS-CX and Ansible
Let's create a Day 0 provisioning workflow that dynamically generates a device configuration from a template and then pushes the configuration to a switch.
Template, Generate, and Upload
Among the most popular Day 0 processes in networking, this workflow operates as follows:
- Dynamically generate a configuration for a switch from a Jinja2 template
- Instruct the device to TFTP-download the resultant configuration to itself
Concepts
- template module: this module accepts a template and renders an output file.
- TFTP server: this server hosts files that a switch can download using the TFTP mechanism. This example assumes that the Ansible control machine is also acting as the TFTP server.
Workflow
- Create a Jinja2 template. This file should resemble an AOS-CX switch configuration, except with parts of the configuration parametrized using variables. These dynamic fields will be populated when the template is rendered. An easy way to create the template is to first manually configure a device fully using the CLI, then copy that "final" configuration from the switch into a Jinja2 file, and then generalize it using variables. Jinja2 templates should reside in a directory named "templates" and possess the ".j2" file extension.
Examples of AOS-CX templates can be found here:
- For Spine / Leaf OSPF Fabric:
- For Spine / VSX Leaf eBGP EVPN VXLAN Fabric:
hostname {{hostname}}
!
!
!
ssh server vrf mgmt
!
!
!
!
!
vlan 1
interface mgmt
no shutdown
ip static {{oobm_ip}}/{{oobm_mask}}
default-gateway {{oobm_default_gateway}}
system interface-group 1 speed 10g
!interface group 1 contains ports 1/1/1-1/1/12
system interface-group 3 speed 10g
!interface group 3 contains ports 1/1/25-1/1/36
system interface-group 4 speed 10g
!interface group 4 contains ports 1/1/37-1/1/48
interface {{vsx_ka}}
no shutdown
description VSX KA
{% if vsx_role == 'primary' %}
ip address {{vsx_ka_ip_primary}}/31
{% else %}
ip address {{vsx_ka_ip_secondary}}/31
{% endif %}
interface {{vsx_isl}}
no shutdown
description VSX ISL
no routing
vlan trunk native 1 tag
vlan trunk allowed all
interface {{spine1_int}}
no shutdown
description Spine1
ip address {{spine1_int_ip}}/31
interface {{spine2_int}}
no shutdown
description Spine2
ip address {{spine2_int_ip}}/31
interface loopback 0
ip address {{loopback0_ip}}/32
interface loopback 1
ip address {{loopback1_ip}}/32
vsx
inter-switch-link {{vsx_isl}}
role {{vsx_role}}
{% if vsx_role == 'primary' %}
keepalive peer {{vsx_ka_ip_secondary}} source {{vsx_ka_ip_primary}}
{% else %}
keepalive peer {{vsx_ka_ip_primary}} source {{vsx_ka_ip_secondary}}
{% endif %}
no split-recovery
router bgp {{asn}}
bgp router-id {{loopback0_ip}}
bgp fast-external-fallover
bgp bestpath as-path multipath-relax
neighbor {{spine1_a_ip}} remote-as {{spine1_asn}}
neighbor {{spine1_b_ip}} remote-as {{spine1_asn}}
neighbor {{spine2_a_ip}} remote-as {{spine2_asn}}
neighbor {{spine2_b_ip}} remote-as {{spine2_asn}}
address-family ipv4 unicast
neighbor {{spine1_a_ip}} activate
neighbor {{spine1_b_ip}} activate
neighbor {{spine2_a_ip}} activate
neighbor {{spine2_b_ip}} activate
redistribute connected
network {{loopback0_ip}}/32
network {{loopback1_ip}}/32
exit-address-family
!
https-server rest access-mode read-write
https-server vrf mgmt
hostname Leaf1b
!
!
!
ssh server vrf mgmt
!
!
!
!
!
vlan 1
interface mgmt
no shutdown
ip static 10.100.1.21/24}
default-gateway 10.10.10.254
system interface-group 1 speed 10g
!interface group 1 contains ports 1/1/1-1/1/12
system interface-group 3 speed 10g
!interface group 3 contains ports 1/1/25-1/1/36
system interface-group 4 speed 10g
!interface group 4 contains ports 1/1/37-1/1/48
interface 1/1/22
no shutdown
description VSX KA
ip address 10.1.2.1/31
interface 1/1/23
no shutdown
description VSX ISL
no routing
vlan trunk native 1 tag
vlan trunk allowed all
interface 1/1/19
no shutdown
description Spine1
ip address 192.168.2.4/31
interface 1/1/20
no shutdown
description Spine2
ip address 192.168.2.6/31
interface loopback 0
ip address 192.168.1.2/32
interface loopback 1
ip address 192.168.100.2/32
vsx
inter-switch-link 1/1/23
role secondary
keepalive peer 10.1.2.0 source 10.1.2.1
no split-recovery
router bgp 65001
bgp router-id 192.168.1.2
bgp fast-external-fallover
bgp bestpath as-path multipath-relax
neighbor 192.168.2.1 remote-as 65101
neighbor 192.168.2.5 remote-as 65101
neighbor 192.168.2.3 remote-as 65102
neighbor 192.168.2.7 remote-as 65102
address-family ipv4 unicast
neighbor 192.168.2.1 activate
neighbor 192.168.2.5 activate
neighbor 192.168.2.3 activate
neighbor 192.168.2.7 activate
redistribute connected
network 192.168.1.2/32
network 192.168.100.2/32
exit-address-family
!
https-server rest access-mode read-write
https-server vrf mgmt
- Define any variables required for the template. It is best to define common variables at the group level to avoid unnecessary repetition and promote proper abstraction.
Examples of inventories can be found here:
- For Spine / Leaf OSPF Fabric:
* [Inventory file](https://github.com/aruba/aruba-switch-ansible/blob/master/inventory/ospf_fabric_inventory.yml): This is an example in which all the template variables are defined in a single file. Although it's easy to locate the variable-containing file, the file itself is lengthy and somewhat repetitive.
- For Spine / VSX Leaf eBGP EVPN VXLAN Fabric:
* [Inventory file](https://github.com/aruba/aruba-switch-ansible/blob/master/inventory/ebgp_evpn_vxlan_fabric.yml): This is an INI-formatted example in which the devices in the environment are grouped, with multiple levels of grouping.
* Group variable files:
* [group_vars/aoscx_switches](https://github.com/aruba/aruba-switch-ansible/blob/master/group_vars/aoscx_switches.yml)
* [group_vars/branch1_dcn_switches](https://github.com/aruba/aruba-switch-ansible/blob/master/group_vars/branch1_dcn_switches.yml)
* [group_vars/leafs](https://github.com/aruba/aruba-switch-ansible/blob/master/group_vars/leafs.yml)
* [group_vars/spines](https://github.com/aruba/aruba-switch-ansible/blob/master/group_vars/spines.yml)
##########################
# EBGP EVPN VXLAN VSX SPINE LEAF FABRIC DEPLOY
# Example Inventory
##########################
[aoscx_switches]
Spine1 ansible_host=10.100.1.1
Spine2 ansible_host=10.100.1.2
Leaf1a ansible_host=10.100.1.11
Leaf1b ansible_host=10.100.1.21
Leaf2a ansible_host=10.100.1.12
Leaf2b ansible_host=10.100.1.22
Leaf3a ansible_host=10.100.1.13
Leaf3b ansible_host=10.100.1.23
[branch1_dcn_switches]
Leaf1a
Leaf1b
Leaf2a
Leaf2b
Leaf3a
Leaf3b
Spine1
Spine2
[leafs]
Leaf1a
Leaf1b
Leaf2a
Leaf2b
Leaf3a
Leaf3b
[spines]
Spine1
Spine2
ansible_user: admin
ansible_password: admin
ansible_net_user: admin
ansible_net_password: admin
ansible_connection: local
config_template: spine.j2
leaf1b_int: 1/1/43
leaf1a_int: 1/1/44
leaf2a_int: 1/1/45
leaf2b_int: 1/1/46
leaf3a_int: 1/1/47
leaf3b_int: 1/1/48
hostname: Spine2
oobm_ip: 10.100.1.2
asn: "{{spine2_asn}}"
leaf1a_int_ip: 192.168.2.3
leaf1b_int_ip: 192.168.2.7
leaf2a_int_ip: 192.168.2.11
leaf2b_int_ip: 192.168.2.15
leaf3a_int_ip: 192.168.2.19
leaf3b_int_ip: 192.168.2.23
loopback0_ip: 192.168.1.12
leaf1a_ip: 192.168.2.2
leaf1b_ip: 192.168.2.6
leaf2a_ip: 192.168.2.10
leaf2b_ip: 192.168.2.14
leaf3a_ip: 192.168.2.18
leaf3b_ip: 192.168.2.22
- Create the Ansible playbook. Write a play and task to render the configuration using the template module, referencing the module documentation page linked in Concepts if necessary. The destination will be the full path to the file wherein the final configuration will be rendered. It is recommended that you validate the generated configuration file by copying its contents onto the switch and checking that the switch reflects the expected state.
---
- hosts: aoscx_switches
tasks:
- name: Generate Config from Template for Device
template: src="leaf.j2" dest="/var/lib/tftpboot/switch_config.conf" mode='0777'
- Lastly, add another task, using the
aoscx_upload_config
module, to make the switch pull the resulting configuration onto itself with TFTP. Since this task calls an AOS-CX module, don't forget to include the role (or collection) in the play!
---
- hosts: aoscx_switches
roles:
- role: arubanetworks.aoscx_role
tasks:
- name: Generate Config from Template for Device
template: src="golden_config_template.j2" dest="/var/lib/tftpboot/switch_config.conf" mode='0777'
- name: Copy Config from TFTP Server to Running Config
aoscx_upload_config:
config_name: 'running-config'
remote_config_file_tftp_path: 'tftp://192.168.1.2/switch_config.conf'
vrf: 'mgmt'
Updated over 1 year ago
What’s Next