5.0 KiB
pfSense Ansible Upgrade Playbook
Upgrades pfSense CE (and pfSense Plus) systems safely via Ansible.
Features
- Version detection — reads
/etc/version, parses branch, patch level, and release type - In-branch update check — runs
pfSense-upgrade -cto detect available patch releases within your running branch (e.g. 2.7.2 → 2.7.3) - New stable branch detection — queries upstream GitHub for the latest stable version and warns if a newer branch (e.g. 2.8.x) has been released
- Safety gates — upgrade is a no-op unless
perform_upgrade=trueis explicitly passed - Branch-crossing protection — requires
allow_major_upgrade=trueto upgrade across major/minor branches - Pre-upgrade config backup — triggers pfSense's own PHP backup function before touching anything
- Serial execution —
serial: 1ensures HA pairs are never upgraded simultaneously - Post-upgrade verification — confirms version changed, services are listening, and the system is up-to-date
Requirements
- Ansible ≥ 2.12
- SSH enabled on pfSense (
System → Advanced → Admin Access → Enable Secure Shell) - Admin user with shell access
- The
rawmodule is used throughout — Python is not required on pfSense
Quick Start
1. Configure inventory
Edit inventory/hosts.yml with your pfSense host IPs and SSH user:
fw-site-a:
ansible_host: 192.168.1.1
ansible_user: admin
2. Configure SSH auth
Either set a private key in inventory/group_vars/pfsense.yml:
ansible_ssh_private_key_file: ~/.ssh/pfsense_rsa
Or use password auth (add ansible_password: yourpassword per host in host_vars/).
3. Check for available upgrades (safe, no changes made)
ansible-playbook upgrade.yml
Or with explicit tag:
ansible-playbook upgrade.yml --tags check
4. Apply in-branch upgrades
ansible-playbook upgrade.yml -e "perform_upgrade=true"
5. Apply upgrade and allow branch crossing (e.g. 2.7 → 2.8)
ansible-playbook upgrade.yml -e "perform_upgrade=true allow_major_upgrade=true"
6. Target a single host
ansible-playbook upgrade.yml -l fw-site-a -e "perform_upgrade=true"
Variables Reference
| Variable | Default | Description |
|---|---|---|
perform_upgrade |
false |
Safety gate — must be true to apply upgrades |
allow_major_upgrade |
false |
Permit upgrades across branch boundaries |
auto_reboot |
true |
Reboot automatically after upgrade |
reboot_timeout |
300 |
Seconds to wait for host after reboot |
upgrade_check_timeout |
120 |
Timeout for pfSense-upgrade check |
pkg_repo_update |
true |
Run pkg update -f before checking |
skip_backup_check |
false |
Skip pre-upgrade config backup step |
notify_webhook_url |
"" |
Optional Slack/Teams webhook for results |
pfsense_release_url |
GitHub raw URL | Where to fetch upstream latest version |
How Update Detection Works
In-branch updates
pfSense-upgrade -d -c is run on the host. It checks the configured pfSense pkg repository (same branch as running system) and returns non-zero if a newer package set is available. The playbook parses the exit code and output to determine availability.
New stable branch detection
The playbook fetches the version file from the pfSense CE GitHub repository (master branch) using FreeBSD fetch. The major.minor of the upstream version is compared to the running system's branch. If they differ and upstream is newer, a warning is displayed regardless of perform_upgrade.
Note: The GitHub master branch reflects the latest stable CE release. Adjust
pfsense_release_urlif you track a specific branch or use an internal mirror.
HA / CARP Considerations
serial: 1in the playbook ensures only one host upgrades at a time- For CARP HA pairs, upgrade the secondary first so the primary continues to pass traffic
- Group your HA pairs in the inventory and order hosts accordingly
- Consider adding a task to demote the primary before upgrading if you need zero-downtime
File Structure
pfsense-upgrade/
├── ansible.cfg
├── upgrade.yml # Main playbook entry point
├── inventory/
│ ├── hosts.yml # Your pfSense hosts
│ └── group_vars/
│ └── pfsense.yml # Shared SSH + default vars
└── roles/
└── pfsense_upgrade/
├── defaults/
│ └── main.yml # All default variable values
└── tasks/
├── main.yml # Task orchestration
├── preflight.yml # SSH check, disk space, binary check
├── version_detect.yml # Read and parse current version
├── update_check.yml # pfSense-upgrade check + upstream compare
├── upgrade.yml # Backup + execute upgrade
└── verify.yml # Post-reboot version + service check