In this series I plan on taking a look at how we can begin improving the reliability and re-useability of infrastructure as code.
Backups –
The old way of doing backups is pretty useless. It’s often a flat text file in a flat directory. With little version control other than time stamps. And we often backup a config whether it’s changed or not. This can cause a bit of head ache when trying to track down a specific change or even just auditing over time.
Backups 2.0 –
What you’ll need –
- Python Virtual Environment
- Ansible(Tower is optional)
- Git
- Your favorite text editor(I use Sublime)
- Git Repository(I use Gogs)
- Test Environment(I have ESXi with CSR1000v’s Running)
I’ll show to perform backups without Tower. They require two different approaches since Tower works in a sandbox and after a playbook is run the working directory is deleted.
Local Backup –
Step 1 – Clone Backups Repository
We will start off by cloning an empty repository. This will show how effective an initial backup commit and diff works in Git.
Before we run the playbook we check for the directory backups. There is none. This playbook connects to the git repository and clones the resources.
--- #This module runs to build git repository locally - name: Clone Git Backups Repository hosts: 127.0.0.1 connection: local gather_facts: no tasks: - name: “Clone Git Backups" git: repo: git@[your git repository here].git dest: ./backups update: yes version: master register: git ignore_errors: True - debug: var: git
Step 2 – Perform Device Backup
The next playbook to run is the device configuration backups. The repository initially is blank. All devices are in the state “changed” due to not having been run before. The playbook takes the backup and renames it according the device name and drops it in the backups folder. When navigating to backups you can see the conf files for the 10 routers and that the directory is a git repository.
--- #Device Backup - name: Backup hosts: cisco connection: network_cli gather_facts: no tasks: - name: Backup ios_config: backup: yes backup_options: dir_path: "./backups" filename: "{{inventory_hostname}}.config" register: config_output - debug: var: config_output
Step 3 – Git Add Commit Push
This playbook is more complicated as it’s stepping through all the git procedures to push to a repository. It adds all existing files in the directory. Then commits with ansible date time as the comment. Keep in mind to perform the date time function you will need get_facts enabled for the localhost.
--- #Push the config to the git add and push to repository - name: Add devices to Git and Push hosts: 127.0.0.1 connection: local gather_facts: yes tasks: - name: Add to Git shell: "git add ." args: chdir: ./backups register: gitadd - debug: var: gitadd - name: Commit shell: git commit -m "{{ ansible_date_time.iso8601 }}" args: chdir: ./backups register: gitcommit - debug: var: gitcommit.stdout - name: Push shell: git push args: chdir: ./backups register: gitpush - debug: var: gitpush
Step 4 – Ansible Idempotency at Play
At the start of the play I push an interface change to Router 1. I then run the config backup and git steps together. As the playbook runs through, you will notice that only R1 has changed. Buried within the wall of text there is also a summary of the amount of lines changed. This can be quite handy for report generation.
Looking at the Git repository, we can see that only R1 has been updated. Browsing the history of R1 Git will report the changes that have taken place.
As a final note. I did use local SSH keys to push to git. If you plan on using Tower. It’s going to be a different process that I’ll detail in a future post. But requires special credentials and roles to successfully run this playbook.