BettaClowd

Building a Better Agile Cloud with programmability and other cool networking things and cloud stuff!!!!!!!!! Please see archive for past demo videos.

Tuesday, April 4, 2017

Using Ansible 2.2 to program Cisco Nexus switches from the API(s)

Use Ansible to treat your Cisco network as Code!
DevOps in the NetOps... :)

Demo Video:

Introduction:
This demo uses Ansible 2.2 to program Nexus switches using the device API (called NX-API).

Ansible:
Ansible is an open source IT configuration management and automation tool. Similar to Puppet and Chef, Ansible has made a name for itself among system administrators that need to manage, automate, and orchestrate various types of server environments. Unlike Puppet and Chef, Ansible is agentless, and does not require a software agent to be installed on the target node (server or switch) in order to automate the device. By default, Ansible requires SSH and Python support on the target node, but Ansible can also be easily extended to use any API. In the Ansible modules developed for NX-OS as part of this project, Ansible modules make API calls against the NX-API to gather real-time state data and to make configuration changes on Cisco Nexus devices.
To review Nexus modules please see: http://docs.ansible.com/ansible/list_of_network_modules.html#nxosor from linux: /usr/share/ansible/cisco_nxos

Prerequisites:
VIRL is optional. An actual Cisco Nexus switch can be substituted. 
Get VIRL:http://virl.cisco.com/getvirl/
Virl on dcloud:https://dcloud-cms.cisco.com/demo_news/ansible-for-cisco-nexus-switches-v1
Virl on Devnet:https://devnetsandbox.cisco.com/RM/Diagram/Index/54657202-fa36-45d4-ac1c-f02ba6b31349?diagramType=Topology
Download Ansible: https://ansible-tips-and-tricks.readthedocs.io/en/latest/ansible/install/
Ansible/Cisco Nexus how to on Devnet:https://developer.cisco.com/site/nx-os/docs/automation/ansible/#what-is-nexus-nx-api
Download the Ansible playbooks .yml files from this Demo: https://github.com/andubiel/ansiblenexusbeginner/archive/master.zip
Authenticating Ansible for your nexus:
Create file
~$ sudo vim .netauth
Make changes using a text editor (example above is using vim) such that it follows the format below. Your file MUST continue to look the one provided (just insert the username and password for your switches).
# the .netauth file
# make sure you input the proper creds for your device
---

cisco:
  nexus:
    username: "cisco"
    password: "cisco"
Enable NX-API on Switch:
***************************************************************************
NX-OSv is strictly limited to use for evaluation, demonstration and    *
NX-OS education. NX-OSv is provided as-is and is not supported by      *
Cisco's Technical Advisory Center. Any use or disclosure, in whole or  *
in part of the NX-OSv Software or Documentation to any third party for *
any purposes is expressly prohibited except as otherwise authorized by *
Cisco in writing.                                                      *
***************************************************************************

nx-osv-1# conf t
Enter configuration commands, one per line.  End with CNTL/Z.
nx-osv-1(config)# feature nxapi
Hosts file:
By default ansible will use a hosts file for inventory that is located in /etc/ansible
root@virl:/usr/share/ansible# cd /etc/ansible/

root@virl:/etc/ansible# ls

ansible.cfg  hosts  roles

root@virl:/etc/ansible#
When issuing the ansible-playbook command -i {name of hosts} can be used to point to an inventory located in the local file path instead of /etc/ansible/hosts.
root@virl:/home/virl/nxos-ansible/nxos-ansible# vi hosts

[all:vars]
ansible_connection = local

[spine]
#n9k1
#n9k2 

[leaf]    
nx-osv-1 
#nx-osv-2 
#csr1000v-1
Ansible PlayBooks .yml files for demo:
Download the Ansible playbooks .yml files from the Demo: https://github.com/andubiel/ansiblenexusbeginner/archive/master.zip
  • gather_data.yml
  • vlan-provisioning.yml
  • vlan-unprovisioning.yml
  • examples-static_routes.yml
Examining gather_data.yml:
---
- name: Gather Data
  hosts: leaf
  connection: local
  gather_facts: no

  tasks:

  - name:  get neighbors   
   nxos_get_neighbors: type=cdp host="{{ inventory_hostname }}"
    register: my_neighbors
  - name:  get routing table for mgmt VRF
    nxos_command:
      type: show
      host: "{{ inventory_hostname }}"
      command: "show ip route vrf management"
    register: my_routes
  - name: store to file 
    template: src=templates/data.j2 dest=data/{{ inventory_hostname }}_gather_data.json
Run an Ansible 2.2 playbook:
root@virl:/home/virl/nxos-ansible# ansible-playbook -i hosts gather_data.yml 

PLAY [Gather Data] *************************************************************
TASK [get neighbors] ***********************************************************
ok: [nx-osv-1]
TASK [get routing table for mgmt VRF] ******************************************
ok: [nx-osv-1]
TASK [store to file] ***********************************************************
changed: [nx-osv-1]
PLAY RECAP *********************************************************************
nx-osv-1                   : ok=3    changed=1    unreachable=0    failed=0   

root@virl:/home/virl/nxos-ansible/nxos-ansible# 
Examine .json Output from the Playbook
root@virl:/home/virl/nxos-ansible/nxos-ansible# cat data/nx-osv-1_gather_data.json 

CDP Info:

{
    "ansible_facts": {
        "neighbors": [
            {
                "local_interface": "mgmt0", 
                "neighbor": "csr1000v-1.virl.info", 
                "neighbor_interface": "GigabitEthernet1"
            }, 

            {
                "local_interface": "Ethernet2/1", 
                "neighbor": "csr1000v-1.virl.info", 
                "neighbor_interface": "GigabitEthernet2"
            }
        ]
    }, 
    "changed": false
}

Route Info:
{
    "changed": false, 
    "commands": "show ip route vrf management", 
    "proposed": {
        "cmd_type": "show", 
        "commands": "show ip route vrf management", 
        "text": null
    }, 
    "response": [
        {
            "body": {
                "TABLE_vrf": {
                    "ROW_vrf": {
                        "TABLE_addrf": {
                            "ROW_addrf": {
                                "TABLE_prefix": {
                                    "ROW_prefix": [
                                        {
                                            "TABLE_path": {
                                                "ROW_path": {
                                                    "clientname": "direct", 
                                                    "hidden": "false", 
                                                    "ifname": "mgmt0", 
                                                    "ipnexthop": "https://www.linkedin.com/redir/invalid-link-page?url=172%2e16%2e1%2e65", 
                                                    "metric": "0", 
                                                    "pref": "0", 
                                                    "stale": "false", 
                                                    "stale-label": "false", 
                                                    "ubest": "true", 
                                                    "unres": "false", 
                                                    "uptime": "P4DT20H26M3S"
                                                }
                                            }, 
                                            "attached": "true", 
                                            "ipprefix": "https://www.linkedin.com/redir/invalid-link-page?url=172%2e16%2e1%2e0%2F24", 
                                            "mcast-nhops": "0", 
                                            "ucast-nhops": "1"
                                        }, 
                                        {
                                            "TABLE_path": {
                                                "ROW_path": {
                                                    "clientname": "local", 
                                                    "hidden": "false", 
                                                    "ifname": "mgmt0", 
                                                    "ipnexthop": "https://www.linkedin.com/redir/invalid-link-page?url=172%2e16%2e1%2e65", 
                                                    "metric": "0", 
                                                    "pref": "0", 
                                                    "stale": "false", 
                                                    "stale-label": "false", 
                                                    "ubest": "true", 
                                                    "unres": "false", 
                                                    "uptime": "P4DT20H26M3S"
                                                }
                                            }, 
                                            "attached": "true", 
                                            "ipprefix": "https://www.linkedin.com/redir/invalid-link-page?url=172%2e16%2e1%2e65%2F32", 
                                            "mcast-nhops": "0", 
                                            "ucast-nhops": "1"
                                        }
                                    ]
                                }, 
                                "addrf": "ipv4"
                            }
                        }, 
                        "vrf-name-out": "management"
                    }
                }
            }, 
            "code": "200", 
            "input": "show ip route vrf management", 
            "msg": "Success"
        }
    ]
}
root@virl:/home/virl/nxos-ansible/nxos-ansible
Please see above video for additional examples. https://youtu.be/wt4o9ebLGSQ
Thank you and stay tuned for more demos @ http://bettaclowd.blogspot.com/