From 0d10c9b4a637fbc7a2db1cd5a813f88d2c263fbb Mon Sep 17 00:00:00 2001 From: "Ben D." Date: Wed, 29 Apr 2026 10:04:38 -0700 Subject: [PATCH] Split out carp roles --- roles/pfsense_upgrade/tasks/carp_post.yml | 49 +++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 roles/pfsense_upgrade/tasks/carp_post.yml diff --git a/roles/pfsense_upgrade/tasks/carp_post.yml b/roles/pfsense_upgrade/tasks/carp_post.yml new file mode 100644 index 0000000..bffb8cc --- /dev/null +++ b/roles/pfsense_upgrade/tasks/carp_post.yml @@ -0,0 +1,49 @@ +# roles/pfsense_upgrade/tasks/carp_post.yml +# Handles CARP/HA post-upgrade logic: restore and verification. +# Only runs on primary after successful upgrade. + +# --------------------------------------------------------------------------- +# Post-upgrade: restore CARP on primary and verify state +# --------------------------------------------------------------------------- +- name: "[CARP/primary] Re-enable CARP (exit maintenance mode)" + ansible.builtin.raw: | + php -r 'require_once("/etc/inc/interfaces.inc"); interfaces_carp_set_maintenancemode(false);' + register: _carp_restore + changed_when: true + when: + - ha_role == 'primary' + - ha_peer is defined + +- name: "[CARP/primary] Wait for CARP state to stabilize after restore" + ansible.builtin.pause: + seconds: 20 + when: + - ha_role == 'primary' + - ha_peer is defined + +- name: "[CARP/primary] Verify primary has reclaimed MASTER for all VIPs" + ansible.builtin.raw: | + php -r 'require_once("/etc/inc/config.inc"); require_once("/etc/inc/interfaces.inc"); $all_master = true; foreach(config_get_path("virtualip/vip", []) as $vip) { if ($vip["mode"] != "carp") continue; if (get_carp_interface_status("_vip" . $vip["uniqid"]) != "MASTER") { $all_master = false; break; } } echo $all_master ? "ALL_MASTER" : "NOT_ALL_MASTER";' + register: _primary_carp_final + changed_when: false + when: + - ha_role == 'primary' + - ha_peer is defined + +- name: "[CARP/primary] Warn if primary did not reclaim MASTER" + ansible.builtin.debug: + msg: > + WARNING: Primary CARP state is '{{ _primary_carp_final.stdout }}' — expected ALL_MASTER. + This may resolve on its own. Check CARP status on both nodes manually. + when: + - ha_role == 'primary' + - ha_peer is defined + - _primary_carp_final.stdout != "ALL_MASTER" + +- name: "[CARP/primary] CARP state confirmed restored" + ansible.builtin.debug: + msg: "{{ inventory_hostname }} has reclaimed MASTER for all VIPs. HA pair is fully operational." + when: + - ha_role == 'primary' + - ha_peer is defined + - _primary_carp_final.stdout == "ALL_MASTER" \ No newline at end of file