Neither the Anisble panos network modules or the official Palo Alto modules in Ansible galaxy offer the ability to export configuration. Import yes, but not export. This post will detail the steps to automate the extraction of config.
First a bit of basic setup; creating a credential vault file, host file and group_var file.
ansible-vault create ~/rest_creds.yml
# ~/rest_creds.yml
pa_rest_user: PA_SRV_USER
pa_rest_password: foobar
# ~/hosts.ini
[PA5520]
FW01 ansible_host=192.168.1.1
FW02 ansible_host=192.168.1.2
# ~/group_vars/PA5520.ini
ansible_network_os: panos
echo my vault password > vault_pass.key
chmod 600 vault_pass.key
Now we need to create a service account o the firewall for Ansible to use when accessing the device. First create the user role for the service account. Since we only need access to the ‘export’ URI of the XML API, that should be the only enable item. Everything else including the Web UI and Command Line should be disabled.

Next create the service account for use by Ansible. The username and password should match what was configure in the Ansible vault file earlier.

The playbook has the following tasks:
- Get REST API Key – Using the vault credentials, obtain the API key
- Read XML response – The API key is wrapped in an XML data structure. Using the Ansible XML module we specify the path to the value and save to the variable api_key
- Gather config – The API key is still wrapped in a dictionary contained in a single element list. This must be plucked out and passed as an argument to the URI module. The returned data is saved to the variable response_pa_config
- Save config – Again the data we are after is wrapped in a XML data structure which we do not need to retain for saving. We pipe this XML through two passed of regex_replace to remove the header and footer and save the result to the local ~/backup directory.
---
- name: Export PA configs
hosts:
- PA5520
connection: local
gather_facts: no
strategy: linear
tasks:
- name: Get REST API Key
uri:
validate_certs: no
url: 'https://{{ ansible_host }}/api/?type=keygen&user={{ pa_rest_user }}&password={{ pa_rest_password }}'
return_content: yes
method: GET
register: response_api_key
- name: Read XML response
xml:
content: 'text'
xmlstring: '{{ response_api_key.content }}'
xpath: '/response/result/key'
register: api_key
- name: Gather config
uri:
validate_certs: no
url: 'https://{{ ansible_host }}/api/?type=config&action=show&key={{ api_key.matches[0].key }}'
return_content: yes
register: response_pa_config
- name: Save config
copy:
content: '{{ response_pa_config.content | regex_replace("^<response.*<result>") | regex_replace("</response>/result>$") }}'
dest: 'backup/{{ inventory_hostname }}.txt'
...
ansible-playbook -i hosts.ini --vault-password-file vault_pass.key export_configs_pa.yml
PLAY [Export PA configs] ***************************************
TASK [Get REST API Key] ****************************************
ok: [FW01]
ok: [FW02]
TASK [Read XML response] ***************************************
ok: [FW01]
ok: [FW02]
TASK [Gather config] *******************************************
ok: [FW01]
ok: [FW02]
TASK [Save config] *********************************************
ok: [FW01]
ok: [FW02]
PLAY RECAP *****************************************************
FW01 : ok=4 changed=0 unreachable=0 failed=0
FW02 : ok=4 changed=0 unreachable=0 failed=0
Leave a Reply