Out of the box Netscaler VPX has backup solution, which can be used for most recovery situations. As long as the backup file is stored external to the system.
But for situations where you want to audit any changes to the configuration and have the configuration under version control the solution does not work. This is where Git comes into the picture. With Git it can provide virtual control, a way of backing up the configuration file external to the device. If you want you could also make the configuration file become part of CI/CD pipeline.
Diagram
Steps
- Git Check
- Check directory to copy files to exists
- Fetch ns.conf from the Netscalers
- Save result to the config directory
- Decode Base64 File
- Delete Base64 File as its no longer needed.
- Hash out sensitive details local username and passwords. (Optional)
- Hash out RPC password. (Optional)
- Git add config files.
- Git Commit
- Git Push
Hosts Inventory File
[prod_vpx]
ns1-int-prd
ns2-int-prd
ns1-dmz-prd
ns2-dmz-prd
[dev_vpx]
ns1-int-dev
ns2-int-dev
ns1-dmz-dev
ns2-dmz-dev
[ns_vpx:children]
prod_vpx
dev_vpx
Vault Var File
To keep things secure we utilise ansible vault to encrypt the login credentials in a var. Note nsroot is used as an example, it’s always recommended to use something other then nsroot.
---
ns_user: nsroot
ns_pass: IAmAPassword$$
Playbook netscaler-backup.yml
---
- name: start
hosts: all
connection: local
gather_facts: false
pre_tasks:
- name: Include Vault var file
include_vars: ns-cred.yml
no_log: true
tasks:
- name: Git Check
delegate_to: localhost
git:
repo: git@gitlab.com:tas_msp/networking/configuration_backups/netscaler-config-backups.git
dest: ./configs
version: master
key_file: /home/jrasnier/.ssh/id_ed25519
accept_hostkey: true
force: true
- name: Ensure a directory exists
file:
path: ./configs/{{inventory_hostname}}
state: directory
- name: Fetch ns.conf
uri:
url: "https://{{ansible_host}}/nitro/v1/config/systemfile/ns.conf?args=filelocation:%2Fnsconfig%2F"
method: GET
status_code: 200
validate_certs: no
return_content: yes
headers:
X-NITRO-USER: "{{ns_user}}"
X-NITRO-PASS: "{{ns_pass}}"
no_log: true
register: result
- name: Save result to config directory
copy:
content: "{{ result.json.systemfile[0].filecontent }}"
dest: "./configs/{{inventory_hostname}}/b64encode-file"
- name: base64 decode
shell: cat "./configs/{{inventory_hostname}}/b64encode-file" | base64 -d > "./config/{{inventory_hostname}}/ns.conf"
- name: cleanup base64encode file
shell: rm "./configs/{{inventory_hostname}}/b64encode-file"
- name: clear local user passwords
delegate_to: localhost
replace:
path: "./configs/{{inventory_hostname}}/ns.conf"
regexp: '(set|add)\s(system user\W.*)'
replace: "#Encyrpted username and password OMITTED"
- name: clear rpcNode passwords
delegate_to: localhost
replace:
path: "./configs/{{inventory_hostname}}/ns.conf"
regexp: '(set)\s(ns rpcNode.*)'
replace: "#rpcNode passwords OMITTED"
- name: Git up to date
hosts: localhost
pre_tasks:
- name: Include Vault var file
include_vars: ns-cred.yml
tasks:
- name: Git Add
shell: "git add *"
args:
chdir: ./config
register: gitadd
- debug:
msg: "{{gitadd.cmd}}"
- name: Git Commit
shell: git commit -m "Ansible Backup"
args:
chdir: ./config
register: gitcommit
#when: git.msg is defined
- debug:
msg: "{{gitcommit}}"
- name: Git Push
shell: git push -u origin master
args:
chdir: ./config
register: gitpush
#when: git.msg is defined
- debug:
msg: "{{gitpush}}"
To run the playbook.
$ ansible-playbook playbook.yml
Here is the tree showing the file structure, noting that lots of these tasks could be redone into roles.
.
├── config
├── group_vars
│ ├── all
│ ├── dev_vpx_test
│ └── ns_vpx
├── hosts
├── netscaler-backup.yml
└── vars
└── ns-cred.yml