Taking regular snapshots of device configuration is something everyone hopefully does, but having them in a version control system as text files provides all the benefits of a full revision history. Depending on the front-end you might even get good looking diffs, and all that for very little effort!
For many of us git
is the tool of choice these days, but as you will see below, due to the lack of any built in module that does this in ansible, you can just substitute the commands for whatever version control system you have in house.
First of all we need to pull the configuration in some way. The example in this playbook uses the nxos_facts
module to pull the config and then saves it to disk using the copy
module. While we could use the nxos_config
module's backup
option, it currently (as of 2.7
) does not allow for customization of the path or the filename under which the backup is made. It saves the file with a timestamp in its name in a backup
folder where the playbook is run. This is unfortunately no good for our purposes, as we need a constant filename (so git can track changes) and a configurable folder where the git repo is located.
- name: FETCH CONFIGURATION FROM N9K DEVICES
hosts: n9k
tags: fetch
tasks:
- name: get nxos facts via ssh
nxos_facts:
gather_subset:
- config
- name: save running-config to file
local_action: copy content={{ ansible_net_config }} dest={{ local_git_repo_path }}/{{ ansible_net_hostname }}.txt
NOTE: Ensure that the path exists and is an actual git
repo beforehand - the playbook's goal is to make backups, so it assumes the necessary repository is already in place (you could write another playbook to set things up in the beginning). In our case /tmp/git/
is the repository and it's defined as a variable in the ansible inventory.
Now that we have all the configs, we run a second play locally (only once, for localhost!), in order to get the files ready and commit them to the repository:
- we need to remove the timestamp added at the beginning of the running-config file which causes every config pull to count as a change (don't want to pollute the repository when nothing really has changed)
- then we just add all the files (identify them as you wish) in the n9k folder and commit them with a timestamped message (not really needed as git already has timestamps, so it's up to you)
- if there's no changed file, the commit command will fail as there's nothing to actually commit, but that's fine (it's handled in the shell commands)
- name: COMMIT CONFIGURATION CHANGES TO GIT
hosts: localhost
connection: local
tags: git
tasks:
- name: remove commented lines with timestamps
# Cisco/NXOS specific - avoid timestamp from always marking config as changed
shell: |
sed -i -e '/^!Time/d' {{ local_git_repo_path }}/*.txt
args:
warn: no
- name: commit changes to git
shell: |
git add .
git commit -m "Config snapshot taken $(date +"%Y-%m-%d %H:%M:%S")"
# Needed as git commit will fail if there are no changed files
exit 0
args:
chdir: "{{ local_git_repo_path }}"
The output is from running cfg_backup.yml against the lab set up in the NX-OSv 9000 Automation (3) post. After the first run, on an empty repo:
> cd /tmp/git/
> tree
.
└── n9k
├── n9k1.txt
├── n9k2.txt
└── n9k3.txt
> git log
* 78d31a4 (HEAD -> master) Config snapshot taken 2019-02-15 18:31:51
Make some changes, run the playbook again.
> ansible-playbook config_backup.yml -l n9k1,localhost
PLAY [FETCH CONFIGURATION FROM N9K DEVICES] *******************************
TASK [get nxos facts via ssh] *********************************************
ok: [n9k1]
TASK [save running-config to file] ****************************************
changed: [n9k1 -> localhost]
PLAY [COMMIT CONFIGURATION CHANGES TO GIT] ********************************
TASK [remove commented lines with timestamps] *****************************
changed: [localhost]
TASK [commit changes to git] **********************************************
changed: [localhost]
PLAY RECAP ****************************************************************
localhost : ok=2 changed=2 unreachable=0 failed=0
n9k1 : ok=2 changed=1 unreachable=0 failed=0
> git log
* e2aa243 (HEAD -> master) Config snapshot taken 2019-02-15 18:34:19
* 78d31a4 Config snapshot taken 2019-02-15 18:31:51
Once a few changes are in, we can diff the various revisions and see what/when changed. I'm showing the CLI git diff
command here, but there are plenty of nice GUI/Web git clients out there for a better diffing experience.
> git diff 78d31a4
diff --git a/n9k/n9k1.txt b/n9k/n9k1.txt
index dda82b4..9674a47 100644
--- a/n9k/n9k1.txt
+++ b/n9k/n9k1.txt
@@ -12,6 +12,7 @@ vdc n9k1 id 1
limit-resource m6route-mem minimum 8 maximum 8
feature nxapi
+feature lldp
no password strength-check
You can find all the code in my NXOS9000v Automation GitHub under Part 3.
NOTE: there's no one right way of doing this, and here's a quick example why: I've had this post in my drafts for about a year and now that I decided to finally publish it, I had two rewrite part of the playbook to adapt for changes in Ansible. Tools evolve all the time!
And, as always, thanks for reading.