Network Configuration Backup with Ansible and Git

The typical way you would perform Network Configuration Backup is by using NCM software such as Solarwinds NCM, Rancid, Oxidized etc. However, you can also utilise Ansible and Git to perform the backups. I know it sounds silly, why would anyone do it? But believe me, it requires very little time and effort to deploy and manage.

In this blog post, I will show you how to perform scheduled configuration backups using Ansible and Git. Ansible will backup the config and Git will perform version control.

I highly recommend you to check out my previous Ansible introduction posts below:

Ansible with Cisco - Part 1 Installation and basic set up
InstallationI’m going to install Ansible on my Raspberry Pi for this examle. You can use anyother OS including Ubuntu, MacOS etc. Our end goal is to manage both of therouters via Ansible. In this example, we will get the ‘show version | inclVersion’ output on both routers using a very basic Ansi…
Ansible with Cisco - Part 2 ios_config module
Cisco IOS configurations use a simple block indent file syntax for segmentingconfiguration into sections. Ansible ios_config module provides animplementation for working with IOS configuration sections in a deterministicway. This post continues my previous post Anisble with Cisco Part 1. Ansibl…

Setting up the environment

Diagram

I have a very basic set up with:

  • 1 x ASA
  • 1 x IOS Router
  • 1 x Ansible Control Machine

and GitLab hosted locally.


Ansible

Ansible copies the running configuration from each device daily and saves it into a directory /home/ubuntu/cisco-backups in the same machine.

Please note that If there are no changes to the running-config then Ansible will not replace the existing file.

Ansible also runs Git commands into that directory so, the changes are committed and pushed to the GitLab repository every day.

Git

Git is a distributed version control system for tracking changes in any set of files. I'm going to use GitLab to manage the repositories in this example.  You can also use GitHub or BitBucket.

  • Create a new project on GitLab
  • Clone the repository to the local host
Create New Project
Project Description
Git Clone
ubuntu@ubuntu:~$ git clone git@gitlab.packet.lan:root/cisco-backups.git
Cloning into 'cisco-backups'...
remote: Enumerating objects: 3, done.
remote: Counting objects: 100% (3/3), done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
Receiving objects: 100% (3/3), done.

You can install GitLab using this guide: Download and install GitLab | GitLab

File structure

ubuntu@ubuntu:~/config_backup$ tree      <<< Ansible playbook
.
├── inventory
│   ├── group_vars
│   │   ├── firewall.yml
│   │   └── ios.yml
│   └── hosts
├── playbooks
│   ├── ansible.cfg
│   ├── config_backup.yml
│   └── show_command.yml
└── README.md
Ansible
ubuntu@ubuntu:~/cisco-backups$ tree      <<< Backups
Backups
ubuntu@ubuntu:~/config_backup/inventory$ cat hosts 
[firewall]
asa ansible_host=192.168.1.62

[ios]
router-1 ansible_host=192.168.1.63
host file
ubuntu@ubuntu:~/config_backup/inventory/group_vars$ cat firewall.yml 
---

ansible_network_os: asa
ansible_user: ansible
ansible_password: Cisco123
ansible_become: yes
ansible_become_password: Cisco123

ubuntu@ubuntu:~/config_backup/inventory/group_vars$ cat ios.yml 
---

ansible_network_os: ios
ansible_user: ansible
ansible_password: Cisco123
ansible_become: yes
ansible_become_password: Cisco123
group_vars
Please note that in a production environment you shouldn't save the credentials in plain text. Please check out my previous Ansible articles to find out how to use Ansible Vault to encrypt sensitive information.

ubuntu@ubuntu:~/config_backup/playbooks$ cat config_backup.yml 
---

- name: FIREWALLS
  hosts: firewall
  gather_facts: false
  connection: network_cli

  tasks:
    - name: ASA CONFIG
      asa_command:
        commands: show run
      register: output

    - name: SAVE ASA CONFIG
      copy:
        content: "{{ output.stdout[0] }}"
        dest: "/home/ubuntu/cisco-backups/show_run_{{ inventory_hostname }}.txt"

- name: IOS ROUTERS
  hosts: ios
  gather_facts: false
  connection: network_cli

  tasks:
    - name: IOS CONFIG
      ios_command:
        commands: show run
      register: output_router

    - name: SAVE IOS CONFIG
      copy:
        content: "{{ output_router.stdout[0] }}"
        dest: "/home/ubuntu/cisco-backups/show_run_{{ inventory_hostname }}.txt"

- name: GIT SECTION
  hosts: localhost

  tasks:

    - name: print time
      command: date
      register: time
      changed_when: false
      delegate_to: localhost
      run_once: yes

    - name: git commands
      shell: |
        git add .
        git commit -m "Device Backup on {{time.stdout}} "
        git push
      args:
        chdir: /home/ubuntu/cisco-backups
      delegate_to: localhost
      run_once: yes
playbook

Few things to consider

  • command: date - Ansible prints out the current date and time and pass it as the Git commit message. So, we can easily find out when a config change was made.
  • delegate_to: localhost - We are telling Ansible to run the commands on the localhost
  • chdir: - Change the directory

Run the playbook

ubuntu@ubuntu:~/config_backup/playbooks$ ansible-playbook config_backup.yml 

PLAY [FIREWALLS] *********************************************************************************************************************************************************************************

TASK [ASA CONFIG] ********************************************************************************************************************************************************************************
ok: [asa]

TASK [SAVE ASA CONFIG] ***************************************************************************************************************************************************************************
changed: [asa]

PLAY [IOS ROUTERS] *******************************************************************************************************************************************************************************

TASK [IOS CONFIG] ********************************************************************************************************************************************************************************
ok: [router-1]

TASK [SAVE IOS CONFIG] ***************************************************************************************************************************************************************************
changed: [router-1]

PLAY [GIT SECTION] *******************************************************************************************************************************************************************************

TASK [Gathering Facts] ***************************************************************************************************************************************************************************
ok: [localhost]

TASK [print time] ********************************************************************************************************************************************************************************
ok: [localhost -> localhost]

TASK [git commands] ******************************************************************************************************************************************************************************
changed: [localhost -> localhost]

PLAY RECAP ***************************************************************************************************************************************************************************************
asa                        : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
localhost                  : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
router-1                   : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
Running the Playbook

Let's verify the config files

As you can see below Ansible copies the running config files into the Git Directory.

ubuntu@ubuntu:~$ ls -l cisco-backups/
total 20
-rw-rw-r-- 1 ubuntu ubuntu   17 Dec  7 15:34 README.md
-rw-rw-r-- 1 ubuntu ubuntu 7715 Dec  7 15:39 show_run_asa.txt
-rw-rw-r-- 1 ubuntu ubuntu 5138 Dec  7 15:39 show_run_router-1.txt


Check the GitLab repository

As you can see below the files are also pushed to GitLab.

Files

Let's make a small config change on both ASA and IOS router and see what happens.

CISCO-ASA# conf ter
CISCO-ASA(config)# interf
CISCO-ASA(config)# interface gi0/2
CISCO-ASA(config-if)# nameif
CISCO-ASA(config-if)# nameif SERVERS
INFO: Security level for "SERVERS" set to 0 by default.
CISCO-ASA(config-if)# ip add
CISCO-ASA(config-if)# ip address 172.16.1.1 255.255.255.0
CISCO-ASA(config-if)# exit
CISCO-ASA(config)# obj
CISCO-ASA(config)# object net
CISCO-ASA(config)# object network VMWARE
CISCO-ASA(config-network-object)# host 172.16.1.10
CISCO-ASA(config-network-object)# end


router-1(config)#access-list 25 permit any 
Making Config Changes

Let's run the Playbook again

ubuntu@ubuntu:~/config_backup/playbooks$ ansible-playbook config_backup.yml 
Run Playbook

As you can see below Git is showing what has been changed since the last commit.

ASA Diff
IOS Diff

Removing unwanted lines

As you can see above, Git is registering cryptochecksum:as a change. You can actually remove that line from the configuration file by using Ansible lineinfile module. Please make sure to add this task above the GIT SECTION.

    - name: Remove Lines from ASA
      lineinfile:
        path: /home/ubuntu/cisco-backups/show_run_{{ inventory_hostname }}.txt
        regexp: 'Cryptochecksum:*' 
        state: absent

You can set up a cron job to automatically run the playbook daily at specific time. The below will run the playbook each day 1 AM.

0 1 * * * /usr/bin/ansible-playbook /home/ubuntu/config_backup/playbooks/config_backup.yml
cron job
GitHub - vsurresh/ncm-with-ansible-git: Network Configuration Management with Ansible and Git
Network Configuration Management with Ansible and Git - GitHub - vsurresh/ncm-with-ansible-git: Network Configuration Management with Ansible and Git

Thanks for reading.

As always, your feedback and comments are more than welcome.