In this post, I cover the upgrade of a Palo Alto firewall using an Ansible playbook.
Even though this playbook covers the upgrade of a single firewall, the real benefit comes where you have tens or hundreds of firewalls to upgrade. With the same playbook, you can upgrade all the firewalls simply by ensuring that the IP addresses of all the required firewalls are in your variables file.
First, I had to install the Palo Alto Networks Ansible collection using the command:
ansible-galaxy collection install paloaltonetworks.panos
This Ansible collection also has a number of dependencies namely:
- pan-python
- pan-os-python
- xmltodict
To install these dependencies with pip, simply run the following commands:
pip install pan-python
pip install pan-os-python
pip install xmltodict
Further information about this Palo Alto Networks Ansible collection can be found in here.
With my Ansible collections and dependencies now installed, I got started with my playbook.
The first part of my playbook simply starts with defining my playbook name and specifying the variables file I want to call in the in playbook.
---
- name: Firewall upgrade
hosts: localhost
gather_facts: no
vars_files:
- upgrade_vars.yml
The sample content of my vars file is also shown below:
firewalls:
site_a: 172.17.30.10
credentials:
username: "user1"
password: "mysecurepassword"
panos_upgrade_version: "10.2.6"
Next, I move on to the actual tasks of the playbook.
My first task is to check the PAN-OS version running on the firewall.
tasks:
- name: Check current firewall version
paloaltonetworks.panos.panos_facts:
provider:
username: "{{ credentials.username }}"
password: "{{ credentials.password }}"
ip_address: "{{ firewalls.site_a }}"
gather_subset: ['system']
register: device_info
In the above snippet, I register the full output and “store” it as a variable called ‘device_info’
Let’s see what the value of ‘device_info’ is by updating the playbook to print its value.
- name: Print device info
ansible.builtin.debug:
msg: "{{device_info}}"
Now, when I run the playbook, I get the below:
The playbook runs successfully. However, I don’t need all details in the above output. I only need the value of ‘ansible_net_version’
So, I update the playbook as follows:
- name: Print device info
ansible.builtin.debug:
msg: "{{device_info.ansible_facts.ansible_net_version}}"
- name: Set fact for the current firewall PAN-OS version
set_fact:
current_software_version: "{{device_info.ansible_facts.ansible_net_version}}"
Now, when I run the playbook, I get the following:
Now I get just the value of the PAN-OS version, which in this case is 10.2.4.
The next portion of my playbook simply checks for the latest PAN-OS version on the firewall.
- name: Request system software check
paloaltonetworks.panos.panos_op:
provider:
username: '{{credentials.username}}'
password: '{{credentials.password}}'
ip_address: '{{firewalls.site_a}}'
cmd: "request system software check"
register: software_check_result
until: software_check_result is not failed
retries: 10
delay: 30
On the Palo Alto firewall GUI, this is the equivalent of navigating to Device > Software and clicking on ‘Check Now’.
Next, I update my playbook to upgrade the PAN-OS version of the firewall if the ‘current_software_version’ (defined earlier in the playbook) is not the same as the ‘panos_upgrade_version’ I have defined in my vars.yml file.
- name: Upgrade PAN-OS version to {{ panos_upgrade_version }} and restart
paloaltonetworks.panos.panos_software:
provider:
username: '{{credentials.username}}'
password: '{{credentials.password}}'
ip_address: '{{firewalls.site_a}}'
version: '{{ panos_upgrade_version }}'
download: true
install: true
restart: true
retries: 3
delay: 120
when: current_software_version != panos_upgrade_version
async: 600
poll: 0
I’ve used the async and poll parameters because of how long the firewall upgrade task may run for. Instead of having Ansible hold on to the connection until the firewall reboots, I’ve set the poll value to 0 so that Ansible starts the task and immediately moves on to the next task (even though in this case, there is no additional task to run)
After waiting a few minutes, the firewall was back up and running with the new PAN-OS version of 10.2.6.