Skip to main content

Configuration Tasks

With this playbook, you will create items in a PAN-OS next-generation firewall, in order to perform configuration of PAN-OS "as-code". This is one of the most common use case for Ansible in relation to PAN-OS.

Assumptions

This tutorial/guide assumes:

  • you have a working installation of Ansible with the PAN-OS collection installed (see example instructions here)
  • you have working connectivity to the firewall and/or Panorama
  • you have administrative credentials capable of performing the relevant operations on the firewall and/or Panorama

Important - Work in a Lab Environment First

With all of the tutorials and guides presented on this website, please ensure that you attempt the tasks in a lab or a similar safe and non-production environment first. In public cloud scenarios, this should be a non-production cloud account which contains no production assets or data. Confirm the tasks behave as expected and perform the operations you require, before using them in production or other live environments.

Security policies and address objects

In this tutorial, you will create a number of items related to security policies (firewall rules). This will include address objects, service objects, and the rules themselves. Then you will commit the configuration to make the changes live.

Create address objects

  1. Create a file called create-address-objects.yml and paste in the following content:
---
- name: Create address objects
hosts: "firewall"
connection: local

vars:
device:
ip_address: "{{ ip_address }}"
username: "{{ username }}"
password: "{{ password }}"

collections:
- paloaltonetworks.panos

tasks:
- name: Create source address object
paloaltonetworks.panos.panos_address_object:
provider: "{{ device }}"
name: "source-server"
value: "192.168.120.8/32"
description: "Address object 1 from Ansible"

- name: Create destination address object
paloaltonetworks.panos.panos_address_object:
provider: "{{ device }}"
name: "destination-server"
value: "192.168.80.5/32"
description: "Address object 2 from Ansible"
  1. Execute the playbook with the following command:
ansible-playbook -i inventory.txt --ask-vault-pass create-address-objects.yml
  1. The output should be something similar to this:
PLAY [Create address objects] ****************************************************************************************************************************

TASK [Gathering Facts] ***********************************************************************************************************************************
ok: [firewall]

TASK [Create source address object] **********************************************************************************************************************
changed: [firewall]

TASK [Create destination address object] *****************************************************************************************************************
changed: [firewall]

PLAY RECAP ***********************************************************************************************************************************************
firewall : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
  1. Login to the PAN-OS GUI and confirm that the two new address objects source-server and destination-server have been created.

image of PAN-OS GUI with address objects

Create service objects

  1. Create a file called create-service-objects.yml and paste in the following content:
---
- name: Create service objects
hosts: "firewall"
connection: local

vars:
device:
ip_address: "{{ ip_address }}"
username: "{{ username }}"
password: "{{ password }}"

collections:
- paloaltonetworks.panos

tasks:
- name: Create service object 'tcp-12345'
paloaltonetworks.panos.panos_service_object:
provider: "{{ device }}"
name: "tcp-12345"
protocol: "tcp"
destination_port: "12345"
description: "Service object 1 from Ansible"

- name: Create service object 'tcp-9876'
paloaltonetworks.panos.panos_service_object:
provider: "{{ device }}"
name: "tcp-9876"
protocol: "tcp"
destination_port: "9876"
description: "Service object 2 from Ansible"
  1. Execute the playbook with the following command:
ansible-playbook -i inventory.txt --ask-vault-pass create-service-objects.yml
  1. The output should be something similar to this:
PLAY [Create service objects] ****************************************************************************************************************************

TASK [Gathering Facts] ***********************************************************************************************************************************
ok: [firewall]

TASK [Create service object 'tcp-12345'] *****************************************************************************************************************
changed: [firewall]

TASK [Create service object 'tcp-9876'] ******************************************************************************************************************
changed: [firewall]

PLAY RECAP ***********************************************************************************************************************************************
firewall : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
  1. Login to the PAN-OS GUI and confirm that the two new address objects tcp-12345 and tcp-9876 have been created.

image of PAN-OS GUI with service objects

Create security policies

  1. Create a file called create-security-policies.yml and paste in the following content:
---
- name: Create security policies
hosts: "firewall"
connection: local

vars:
device:
ip_address: "{{ ip_address }}"
username: "{{ username }}"
password: "{{ password }}"

collections:
- paloaltonetworks.panos

tasks:
- name: Add example rule 1
paloaltonetworks.panos.panos_security_rule:
provider: "{{ device }}"
rule_name: "example rule 1"
source_zone: ["any"]
source_ip: ["source-server"]
destination_zone: ["any"]
destination_ip: ["destination-server"]
application: ["ssh"]
service: ["tcp-12345"]
action: "allow"

- name: Add example rule 2
paloaltonetworks.panos.panos_security_rule:
provider: "{{ device }}"
rule_name: "example rule 2"
source_zone: ["any"]
source_ip: ["source-server"]
destination_zone: ["any"]
destination_ip: ["destination-server"]
application: ["ssh"]
service: ["tcp-9876"]
action: "deny"
  1. Execute the playbook with the following command:
ansible-playbook -i inventory.txt --ask-vault-pass create-security-policies.yml
  1. The output should be something similar to this:
PLAY [Create security policies] ****************************************************************************************************************************************************

TASK [Gathering Facts] *************************************************************************************************************************************************************
ok: [firewall]

TASK [Add example rule 1] **********************************************************************************************************************************************************
changed: [firewall]

TASK [Add example rule 2] **********************************************************************************************************************************************************
changed: [firewall]

PLAY RECAP *************************************************************************************************************************************************************************
firewall : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
  1. Login to the PAN-OS GUI and confirm that the two new address objects example rule 1 and example rule 2 have been created.

image of PAN-OS GUI with security policy rules

Commit the configuration

  1. Create a file called commit-firewall.yml and paste in the following content:
---
- name: Commit firewall candidate configuration
hosts: "firewall"
connection: local

vars:
device:
ip_address: "{{ ip_address }}"
username: "{{ username }}"
password: "{{ password }}"

collections:
- paloaltonetworks.panos

tasks:
- name: Commit candidate configuration
paloaltonetworks.panos.panos_commit_firewall:
provider: "{{ device }}"
register: results
- debug:
msg: "Commit with Job ID: {{ results.jobid }} had output: {{ results.details }}"
  1. Execute the playbook with the following command:
ansible-playbook -i inventory.txt --ask-vault-pass commit-firewall.yml
  1. The output should be something similar to this:
PLAY [Commit firewall candidate configuration] *************************************************************************************************************************************

TASK [Gathering Facts] *************************************************************************************************************************************************************
ok: [firewall]

TASK [Commit candidate configuration] **********************************************************************************************************************************************
changed: [firewall]

TASK [debug] ***********************************************************************************************************************************************************************
ok: [firewall] => {
"msg": "Commit with Job ID: 5410 had output: ['Configuration committed successfully']"
}

PLAY RECAP *************************************************************************************************************************************************************************
firewall : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

Closing notes

  • Tasks do not have to be divided into playbook files as has been described in this tutorial. All the tasks could have been placed in a single playbook, or equally the tasks could have been divided into more playbooks than those used in the tutorial. The structure of your playbooks is something to consider as you operationalize Ansible within your organization.
  • If you used the setup instructions listed here, you were using a static inventory file, and local PAN-OS credentials encrypted on disk with ansible-vault. This is very suitable for a learning tutorial, but these approaches may not be suitable for production, and are also something to consider as you operationalize Ansible within your organization.
  • Almost all values for tasks were defined within the playbooks; names of configuration items, IP addresses, and more. This is very suitable for a learning tutorial, but this approach does not scale well in production, and using variables instead is something to consider as you operationalize Ansible within your organization.