How to handle upgrading of High Availability pair instances

I’m writing ansible-playbook to upgrade NetScaler High Availability pair.

Basically, there are two instances primary and secondary.
The process to upgrade manually is:

  • First we upgrade the secondary instance and than it reboots (as part of upgrade command),
  • Secondly, we upgrade the secondary instance and reboots

Currently, I’m using Ansible’s async option to run the upgrade command on secondary and waiting for it to come up, after upgrade(and reboot), later I’m repeating the same for the other node (or instance).

But another thing is that, the python gets removed during the upgrade and gets reinstalled, so in that case the async task(upgrade task) exits without further continuing.

Here is the link to the ansible-playbook: automation-toolkit/golden_templates/upgrade-netscaler/high-availability/normal-mode/ha_upgrade.yaml at main · netscaler/automation-toolkit · GitHub

Is there a better way I can handle this scenerio.

Any help would be appreciated.

---
- hosts: netscaler_ha_pair
  gather_facts: no
  tasks:
  - name: Upgrade secondary node
    block:
    - name: Upgrade secondary node
      delegate_to: localhost
      netscaler_adc_nitro:
        nsip: "{{ item.nsip }}"
        nitro_user: "{{ nitro_user }}"
        nitro_pass: "{{ nitro_pass }}"
        operation: upgrade
        file: "{{ upgrade_image }}"
      loop: "{{ groups['netscaler_ha_secondary'] | map('extract', hostvars, ['ansible_host']) | list }}"
      register: upgrade_result

    - name: Wait for secondary node to reboot
      wait_for_connection:
        connect_timeout: 30
        sleep: 5
        delay: 10
        timeout: 600
      loop: "{{ groups['netscaler_ha_secondary'] | map('extract', hostvars, ['ansible_host']) | list }}"
      when: upgrade_result.changed

    - name: Ensure Python is installed after upgrade
      raw: "/usr/bin/apt-get update && /usr/bin/apt-get install -y python3"
      loop: "{{ groups['netscaler_ha_secondary'] | map('extract', hostvars, ['ansible_host']) | list }}"
      when: upgrade_result.changed

  - name: Upgrade primary node
    block:
    - name: Upgrade primary node
      delegate_to: localhost
      netscaler_adc_nitro:
        nsip: "{{ item.nsip }}"
        nitro_user: "{{ nitro_user }}"
        nitro_pass: "{{ nitro_pass }}"
        operation: upgrade
        file: "{{ upgrade_image }}"
      loop: "{{ groups['netscaler_ha_primary'] | map('extract', hostvars, ['ansible_host']) | list }}"
      register: upgrade_result

    - name: Wait for primary node to reboot
      wait_for_connection:
        connect_timeout: 30
        sleep: 5
        delay: 10
        timeout: 600
      loop: "{{ groups['netscaler_ha_primary'] | map('extract', hostvars, ['ansible_host']) | list }}"
      when: upgrade_result.changed

    - name: Ensure Python is installed after upgrade on primary
      raw: "/usr/bin/apt-get update && /usr/bin/apt-get install -y python3"
      loop: "{{ groups['netscaler_ha_primary'] | map('extract', hostvars, ['ansible_host']) | list }}"
      when: upgrade_result.changed

  vars:
    nitro_user: "admin"
    nitro_pass: "your_password"
    upgrade_image: "/path/to/upgrade_image.tgz"