--- # roles/pfsense_upgrade/tasks/upgrade.yml # Applies the upgrade after safety checks pass. # Only runs when perform_upgrade=true. - name: Abort if no upgrade is available (nothing to do) ansible.builtin.debug: msg: > No in-branch upgrade is available for {{ inventory_hostname }}. Current version {{ pfsense_current_version }} is already the latest on branch {{ pfsense_major_minor }}. Skipping upgrade. when: - not (upgrade_available | bool) - not (new_major_release_available | bool and allow_major_upgrade | bool) - name: End play for this host if nothing to upgrade ansible.builtin.meta: end_host when: - not (upgrade_available | bool) - not (new_major_release_available | bool and allow_major_upgrade | bool) # --------------------------------------------------------------------------- # Branch-crossing guard # --------------------------------------------------------------------------- - name: Abort if major upgrade is available but not explicitly allowed ansible.builtin.fail: msg: > A new pfSense branch is available ({{ upstream_version }}) but allow_major_upgrade=false. Review the release notes for {{ upstream_version }} before upgrading across branches. Re-run with -e "allow_major_upgrade=true" when ready. when: - new_major_release_available | bool - not (allow_major_upgrade | bool) - not (upgrade_available | bool) # --------------------------------------------------------------------------- # Pre-upgrade config backup # --------------------------------------------------------------------------- - name: Trigger config backup via PHP (writes to /cf/conf/backup/) ansible.builtin.raw: > sudo php -r "require_once('/etc/inc/config.inc'); require_once('/etc/inc/util.inc'); backup_config();" register: _backup_result changed_when: false when: not (skip_backup_check | bool) - name: Confirm backup file was created ansible.builtin.raw: > ls -t {{ pfsense_config_backup_path }}/config-*.xml 2>/dev/null | head -1 register: _backup_file changed_when: false when: not (skip_backup_check | bool) - name: Display backup file path ansible.builtin.debug: msg: "Config backup written to: {{ _backup_file.stdout | trim }}" when: - not (skip_backup_check | bool) - _backup_file.stdout | trim | length > 0 - name: Warn if no backup file found ansible.builtin.debug: msg: > WARNING: Could not confirm config backup was written. Check {{ pfsense_config_backup_path }} manually before proceeding. when: - not (skip_backup_check | bool) - _backup_file.stdout | trim | length == 0 # --------------------------------------------------------------------------- # Execute the upgrade # --------------------------------------------------------------------------- - name: "UPGRADE — Running pfSense-upgrade on {{ inventory_hostname }}" ansible.builtin.raw: > sudo {{ pfsense_upgrade_bin }} -d -y 2>&1 register: _upgrade_result async: 600 # pfSense upgrades can take several minutes poll: 10 timeout: 620 # The upgrade reboots the host — the connection will drop. That is expected. failed_when: > _upgrade_result.rc is defined and _upgrade_result.rc != 0 and 'reboot' not in _upgrade_result.stdout | lower and 'Restarting' not in _upgrade_result.stdout - name: Display upgrade output ansible.builtin.debug: msg: "{{ _upgrade_result.stdout_lines | default(['(no output captured — likely rebooted mid-stream)']) }}" # --------------------------------------------------------------------------- # Wait for host to come back after reboot # --------------------------------------------------------------------------- - name: Wait for pfSense to reboot and become reachable ansible.builtin.wait_for_connection: delay: 30 timeout: "{{ reboot_timeout }}" sleep: 10 when: auto_reboot | bool