--- # ============================================================================= # proxmox_upgrade.yml # Rolling Proxmox upgrade orchestrator. # # Workflow per node (cluster mode): # 1. Backup config # 2. Set CEPH noout (if CEPH enabled) # 3. Enable HA maintenance mode # 4. Drain guests to best available node # 5. apt dist-upgrade # 6. Reboot if required, wait for rejoin # 7. Clear CEPH noout # 8. Disable HA maintenance mode # 9. Restore guests (if migration_restore=true) # # Standalone mode skips all cluster/HA/CEPH/drain steps. # # Variables (set in inventory or pass with -e): # upgrade_order — ordered list of nodes to upgrade (cluster only) # migration_restore — return VMs to origin node after upgrade (default: false) # drain_target_strategy — resources | explicit (default: resources) # backup_destination — local | sftp (default: local) # ============================================================================= - name: "Proxmox Rolling Upgrade" hosts: proxmox_cluster gather_facts: true run_once: true # Play runs once — loops over nodes internally serial: 1 # Safety: only one Ansible host processes at a time vars: migration_restore: false upgrade_order: "{{ groups['proxmox_cluster'] | sort }}" pre_tasks: - name: "Upgrade | Confirm upgrade_order is defined" ansible.builtin.fail: msg: "upgrade_order must be defined in inventory or passed with -e" when: upgrade_order is not defined or upgrade_order | length == 0 - name: "Upgrade | Log targets" ansible.builtin.debug: msg: >- Proxmox upgrade starting for {{ client_name | default('Unknown') }} ({{ client_id | default('?') }}) Nodes: {{ upgrade_order | join(', ') }} API: https://{{ api_host }}:{{ api_port }} roles: - role: proxmox_preflight tasks: # ── Cluster: loop through each node ──────────────────────────────────────── - name: "Upgrade | Rolling upgrade — cluster mode" ansible.builtin.include_tasks: tasks/proxmox_upgrade_node_loop.yml loop: "{{ upgrade_order }}" loop_control: loop_var: current_node label: "{{ current_node }}" when: proxmox_is_cluster # ── Standalone: upgrade this host directly ──────────────────────────────── - name: "Upgrade | Standalone | Backup config" ansible.builtin.include_role: name: proxmox_config_backup vars: current_node: "{{ inventory_hostname }}" when: not proxmox_is_cluster - name: "Upgrade | Standalone | Run upgrade" ansible.builtin.include_role: name: proxmox_upgrade_node vars: current_node: "{{ inventory_hostname }}" when: not proxmox_is_cluster - name: "Upgrade | Complete" ansible.builtin.debug: msg: >- ✓ Proxmox upgrade complete for {{ client_name | default('Unknown') }} — {{ upgrade_order | length }} node(s) upgraded.