How to automate your Cisco legacy network with Ansible

In the previous article , we introduce ansible with NXOS devices. We can also use ansible for Catalyst, NXOS, NXOS-ACI, etc.

Ansible can be very useful to search something or to backup your configuration.

Example to save your configuration :

---

  - name: Configure IOS
    hosts: routers
    connection: local
    gather_facts: False
    any_errors_fatal: true

    tasks:

      - name: show running
        ios_command:
          commands:
            - 'show run'
        register: running_config
        tags:
        - backup

      - name: save output
        copy: content="{{running_config.stdout[0]}}" dest="./output/{{inventory_hostname}}-show_run.txt"
        tags:
        - backup

In the last part, I use the save my output with register: running_config and then I use the module copy to create a new file with the content save in running_config.

You need to create first the directory named here output. After Ansible will create a file with the device name as prefix and concatenate -show_run.txt

copy: content="{{running_config.stdout[0]}}" dest="./output/{{inventory_hostname}}-show_run.txt"

root@09cf326cc275:/ansible/NXOS#  tree output/
output/
|-- R7-show_run.txt
`-- R7.txt

Inside the file you will have your running configuration.

Playbooks are now mandatory, you can also use ad hoc command to search something on your device.

Example with show ip arp or show version

ansible R7 -i inventory-home -m ios_command -a "commands='show ip arp'"                            
 R7 | SUCCESS => {
     "changed": false, 
     "stdout": [
         "Protocol  Address          Age (min)  Hardware Addr   Type   Interface\nInternet  10.0.100.1              0   000c.2935.812f  ARPA   Ethernet0/0\nInternet  10.0.100.67             -   aabb.cc00.7000  ARPA   Ethernet0/0\nInternet  10.0.100.150            1   a483.e7bf.9979  ARPA   Ethernet0/0"
     ], 
     "stdout_lines": [
         [
             "Protocol  Address          Age (min)  Hardware Addr   Type   Interface", 
             "Internet  10.0.100.1              0   000c.2935.812f  ARPA   Ethernet0/0", 
             "Internet  10.0.100.67             -   aabb.cc00.7000  ARPA   Ethernet0/0", 
             "Internet  10.0.100.150            1   a483.e7bf.9979  ARPA   Ethernet0/0"
         ]
     ]
 }

root@09cf326cc275:/ansible/NXOS# ansible R7 -i inventory-home -m ios_command -a "commands='show version'"

Currently we use only show command, but you can also configure your catalyst devices. The following task will enable ospf on all interfaces. I added a tag named OSPF to be able to play only OSPF task within my playbook.

---

  - name: Configure IOS
    hosts: routers
    connection: local
    gather_facts: False
    any_errors_fatal: true

    tasks:
      - name: Enable ospf
        ios_config:
          lines:
            - network 0.0.0.0 255.255.255.255 ar 0
          parents: router ospf 1
        register: ospf
        tags:
        - OSPF

      - debug: var=ospf
        tags:
        - OSPF
root@09cf326cc275:/ansible/NXOS# ansible-playbook -i inventory-home playbook-ios.yaml --tags OSPF
 PLAY [Configure IOS] *
 TASK [Enable ospf] ***
 changed: [R7]
 TASK [debug] *
 ok: [R7] => {
     "ospf": {
         "banners": {}, 
         "changed": true, 
         "commands": [
             "router ospf 1", 
             "network 0.0.0.0 255.255.255.255 ar 0"
         ], 
         "failed": false, 
         "updates": [
             "router ospf 1", 
             "network 0.0.0.0 255.255.255.255 ar 0"
         ]
     }
 }
 PLAY RECAP ***
 R7                         : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

Other example to search an Endpoint on your network with ad hoc command. Here I want to search one server with the @MAC : ecbd.1d44.b6c1.

root@09cf326cc275:/ansible/NXOS# ansible SW1 -i inventory-home -m ios_command -a "commands='show mac address'"  | egrep -v "\n"       
SW1 | SUCCESS => {
    "stdout": [
    ], 
        [
            "Mac Address Table", 
            "-------------------------------------------", 
            "", 
            "----    -----------       --------    -----", 
            "   1    0050.2935.812f    DYNAMIC     Gi0/0", 
            "   1    0050.8824.7718    DYNAMIC     Gi0/0", 
            "   1    0050.bdf0.b6ad    DYNAMIC     Gi0/0", 
            "   1    0050.1878.2797    DYNAMIC     Gi0/0", 
            "   1    0050.9110.af2c    DYNAMIC     Gi0/0", 
            "   1    0050.e7bf.9979    DYNAMIC     Gi0/0", 
            "   1    0050.cc00.2011    DYNAMIC     Gi0/0", 
            "   1    0050.cc00.7000    DYNAMIC     Gi0/0", 
            "   1    0050.eba6.c667    DYNAMIC     Gi0/0", 
            "   1    0050.8b57.d81b    DYNAMIC     Gi0/0", 
            "   1    0050.817a.ce2e    DYNAMIC     Gi0/0", 
            "   1    ecbd.1d44.b6c1    DYNAMIC     Gi0/0", 
            "   1    0050.754a.a8ee    DYNAMIC     Gi0/0", 
        ]
    ]
}

root@09cf326cc275:/ansible/NXOS# ansible catalyst -i inventory-home -m ios_command -a "commands='show mac address'"  | egrep -v "\n" | grep "SUCCESS \|ecbd.1d44.b6c1"
SW1 | SUCCESS => {
            "   1    ecbd.1d44.b6c1    DYNAMIC     Gi0/0",

Here I have found the server on switch SW1 port Gi0/0, which is an uplink port. If I added other switch in my group named catalyst, I’ll be able to found on all switches where is learned this @MAC.

In your inventory file, you need to use groups to organize properly your network. It can be very useful to run one command to only one part of your network or to all.

In the following example we have on DC named DC1 with two different rooms. Each room contains two switches. Now, you can run command only to switches in the Room1 or Room2 or all inside DC1.

[DC1:children]
Room1
Room2

[Room1]
DC1-SW1
DC1-SW2

[Room2]
DC1-SW10
DC1-SW11