Inra-as-Code
NetDevOps
  • Introduction
  • CXTM Basics
  • CXTM Projects
  • CXTM Test Cases
  • CXTM Test Automation
  • Revisit Imported Test Cases
  • CXTM Batches
  • NetDevOps
  • CXTM Reporting
  • CXTM References
  • Bonus: Project Users
  • Bonus: CXTM REST API

Create IaC Config Change Playbook

In this section, you will create a simple Infrastructure-as-Code (IaC) playbook to make configuration changes for OSPF and BGP on your C8Kv, XR9Kv, CSR1Kv, and N9Kv.

Step 1 - Create and Switch to a New Git Branch

To begin, return to your VSCode Terminal. You will create a new branch in Git to work from. Branching in Git is a strategy to work on your codebase without making changes in the main branch. Doing so de-risks errors and issues you could introduce into the main branch inadvertently. Given this, the main branch should never be used for development and execution against your test network. The main branch is a safe branch. If the lab allowed more time, there are additional concepts such as branch protection rules that you can explore to further protect your main branch from any use except for prod use.

To create a new branch, you can use git checkout -b where the option -b is for the new branch name.

    
        git checkout -b config-changes-testing
    

Step 2 - Create Ansible Tasks for C8Kv

The Ansible task below will make the configuration change to add OSPF and BGP to your C8Kv. This task utilizes Ansible's Cisco IOS Collection modules. For configuration changes where an Ansible module didn't exist, the cisco.ios.ios_config general module is used to send the CLI configuration.

    
        mkdir -p /home/cisco/CiscoLive/LTROPS-2711/ansible/roles/c8kv/tasks/
        touch /home/cisco/CiscoLive/LTROPS-2711/ansible/roles/c8kv/tasks/main.yml
        cat <<EOF >> /home/cisco/CiscoLive/LTROPS-2711/ansible/roles/c8kv/tasks/main.yml
        ---

        - name: Configure OSPF Process
          cisco.ios.ios_ospfv2:
            config:
              processes:
                - router_id: 2.2.2.2
                  process_id: 1
                  areas:
                    - area_id: 0
                  passive_interfaces:
                    interface:
                      set_interface: yes
                      name:
                        - Loopback0
            state: merged

        - name: Configure C8Kv for OSPF Peering to XR9Kv
          cisco.ios.ios_ospf_interfaces:
            config:
              - name: "{{ item }}"
                address_family:
                  - afi: ipv4
                    process:
                      id: 1
                      area_id: 0
            state: merged
          loop:
            - GigabitEthernet3
            - Loopback0

        - name: Configure BGP Process and Neighbors to CSR1Kv & N9Kv
          cisco.ios.ios_bgp_global:
            config:
              as_number: 65001
              bgp:
                router_id:
                  interface: Loopback0
                log_neighbor_changes: true
              neighbor:
                - description: "Config'd by Ansible - iBGP Neighbor to CSR1Kv"
                  address: 1.1.1.1
                  activate: true
                  remote_as: 65001          
                - description: "Config'd by Ansible - iBGP Neighbor to N9Kv"
                  address: 4.4.4.4
                  activate: true
                  remote_as: 65001
            state: merged

        - name: Configure BGP Neighbor Update-Source
          cisco.ios.ios_config:
            lines:
              - neighbor 1.1.1.1 update-source Loopback0
              - neighbor 4.4.4.4 update-source Loopback0
            parents: router bgp 65001

        - name: Configure BGP Network Statements
          cisco.ios.ios_bgp_address_family:
            config:
              as_number: 65001
              address_family:
                - afi: ipv4
                  safi: unicast
                  network:
                    - address: 100.2.2.2
                      mask: 255.255.255.0
            state: merged
        EOF
        


Step 3 - Create Ansible Tasks for CSR1Kv

The Ansible task below will make the configuration change to add BGP neighborship to your C8Kv. This task utilizes Ansible's Cisco IOS Collection modules. For configuration changes where an Ansible module didn't exist, the cisco.ios.ios_config general module is used to send the CLI configuration.

    
        mkdir -p /home/cisco/CiscoLive/LTROPS-2711/ansible/roles/csr1kv/tasks/
        touch /home/cisco/CiscoLive/LTROPS-2711/ansible/roles/csr1kv/tasks/main.yml
        cat <<EOF >> /home/cisco/CiscoLive/LTROPS-2711/ansible/roles/csr1kv/tasks/main.yml
        ---

        - name: Add BGP Neighbor to C8Kv
          cisco.ios.ios_bgp_global:
            config:
              as_number: 65001
              bgp:
                log_neighbor_changes: true
              neighbor:
                - description: "Config'd by Ansible - iBGP Neighbor to C8Kv"
                  address: 2.2.2.2
                  activate: true
                  remote_as: 65001
            state: merged
        
        - name: Configure BGP Update-Source
          cisco.ios.ios_config:
            lines:
              - neighbor 2.2.2.2 update-source Loopback0
            parents: router bgp 65001
        EOF
        


Step 4 - Create Ansible Tasks for XR9Kv

The Ansible task below will make the configuration change to add OSPF peering to your C8Kv. This task utilizes Ansible's Cisco IOSXR Collection module, cisco.iosxr.iosxr_config to send the configuration lines.

    
        mkdir -p /home/cisco/CiscoLive/LTROPS-2711/ansible/roles/xr9kv/tasks/
        touch /home/cisco/CiscoLive/LTROPS-2711/ansible/roles/xr9kv/tasks/main.yml
        cat <<EOF >> /home/cisco/CiscoLive/LTROPS-2711/ansible/roles/xr9kv/tasks/main.yml
        ---

        - name: Configure XR9Kv for OSPF Peering to C8Kv
          cisco.iosxr.iosxr_config:
            exclusive: true
            lines:
            - area 0 interface GigabitEthernet0/0/0/3
            parents: router ospf 1
        EOF
        


Step 5 - Create Ansible Tasks for N9Kv

The Ansible task below will make the configuration change to add BGP neighborship to your C8Kv. This task utilizes Ansible's Cisco NXOS Collection modules.

    
        mkdir -p /home/cisco/CiscoLive/LTROPS-2711/ansible/roles/n9kv/tasks/
        touch /home/cisco/CiscoLive/LTROPS-2711/ansible/roles/n9kv/tasks/main.yml
        cat <<EOF >> /home/cisco/CiscoLive/LTROPS-2711/ansible/roles/n9kv/tasks/main.yml
        ---

        - name: Add BGP Neighbor to C8Kv
          cisco.nxos.nxos_bgp_global:
            config:
              as_number: 65001
              neighbors:
                - description: "Config'd by Ansible - iBGP Neighbor to C8Kv"
                  neighbor_address: 2.2.2.2
                  remote_as: 65001
                  update_source: loopback0
            state: merged
        
        - name: Configure Neighbor BGP IPv4 Unicast Address-Family
          cisco.nxos.nxos_bgp_neighbor_address_family:
            config:
              as_number: 65001
              neighbors:
                - neighbor_address: 2.2.2.2
                  address_family:
                    - afi: ipv4
                      safi: unicast
            state: merged
        EOF
        


Step 6 - Create the Main Ansible Playbook

Ansible calls it's configuration and orchestration framework "playbooks" and are a collections of "play(s)" or tasks for configuration management and deployment to a device or multiple devices. While playbooks can be represented as a single file, Ansible best practices recommend a particular directory structure for playbooks that you build using roles for better organization and reuse. You built all of this over the last three sections. You now need to build the main playbook file, which would look like the below:

The below playbook file you will use for this lab designates the following behaviors, for each role ‘x’:

  • If roles/x/tasks/main.yml exists, tasks listed therein will be added to the play
  • If roles/x/handlers/main.yml exists, handlers listed therein will be added to the play
  • If roles/x/vars/main.yml exists, variables listed therein will be added to the play
  • If roles/x/defaults/main.yml exists, variables listed therein will be added to the play
  • If roles/x/meta/main.yml exists, any role dependencies listed therein will be added to the list of roles (1.3 and later)
  • Any copy, script, template or included tasks (in the role) can reference files in roles/x/{files,templates,tasks}/ (dir depends on task) without having to path them relatively or absolutely
Copy or type the main playbook YAML file. The order of the playbook is to make the OSPF configuration change on the XR9Kv, then to pre-stage the BGP configuration change on the CSR1Kv and N9Kv, and finally the configuration change to bring the C8Kv into the network:

    
        touch /home/cisco/CiscoLive/LTROPS-2711/ansible/playbook.yml
        cat <<EOF >> /home/cisco/CiscoLive/LTROPS-2711/ansible/playbook.yml
        ---
        # main playbook
        
        - hosts: xr
          gather_facts: False
          roles:
            - role: xr9kv
        
        - hosts: csr1kv
          gather_facts: False
          roles:
            - role: csr1kv
        
        - hosts: nx
          gather_facts: False
          roles:
            - role: n9kv
        
        - hosts: c8kv
          gather_facts: False
          roles:
            - role: c8kv
        EOF
        


Continue to the next section to develop a Python script to drive CXTM's API and leverage in multiple stages and steps of your CI pipeline.