Ansible – export Palo Alto config

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
FW01 ansible_host=
FW02 ansible_host=
# ~/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.

Configure Admin Role

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

Configure API user

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
    - PA5520
  connection: local
  gather_facts: no
  strategy: linear

    - name: Get REST API Key
        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
        content: 'text'
        xmlstring: '{{ response_api_key.content }}'
        xpath: '/response/result/key'
      register: api_key 

    - name: Gather config
        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
        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

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

Blog at

Up ↑

%d bloggers like this: