Search code examples
ansibleansible-handlers

Wait for handler for every item in with_lines - Ansible


Ansible Version: ansible 2.4.2.0

I want to start VM sequentially depends on the role(master/backup). Multiple VM IDs are stored in 2 files master & backup. The controller flow should like below

  1. Iterate VM IDs one by one from a file
    • For every iteration, the handler should notified. i.e the iteration should WAIT for handler complete
    • Iteration should not move foreword if handler is failed(or in WAITING state).

For reference, you see the below playbook

- name: Performs Power Actions VMs
  hosts: localhost
  vars:
    - status: "{% if action=='stop' %}SHUTOFF{% else %}ACTIVE{% endif %}"   # For Checking VM status

  tasks:
  - name: Staring Master VM
    shell: |
      echo {{ item }} > /tmp/current
      echo "RUN nova start {{ item }} HERE!!!"
    when: action == "start"
    with_lines: cat ./master
    notify: "Poll VM power status"

  - name: Starting Backup VM
    shell: |
      echo {{ item }} > /tmp/current
      echo "RUN nova start {{ item }} HERE!!!"
    when: action == "start"
    with_lines: cat ./backup
    notify: "Poll VM power status"
 
  handlers:
  - name: Poll VM power status
    shell: openstack server show -c status --format value `cat /tmp/current`
    register: cmd_out
    until: cmd_out.stdout == status
    retries: 5
    delay: 10

For above playbook, what I see is the handlers is notified after entire iteration is complete.


PLAY [Performs Power Actions on ESC VMs] **********************************************************************************************

TASK [Stopping Backup VM] *********************************************************************************************************
skipping: [localhost] => (item=Test) 

TASK [Stopping Master VM] *********************************************************************************************************
skipping: [localhost] => (item=Test) 

TASK [Staring Master VM] **********************************************************************************************************
changed: [localhost] => (item=Test)

TASK [Starting Backup VM] *********************************************************************************************************
changed: [localhost] => (item=Test)

TASK [Removing tmp files] *************************************************************************************************************
changed: [localhost] => (item=./master)
changed: [localhost] => (item=./backup)

RUNNING HANDLER [Poll VM power status] ********************************************************************************************
FAILED - RETRYING: Poll ESC VM power status (5 retries left).
^C [ERROR]: User interrupted execution

Is there any better approach to solve this problem? or Any suggestion how to fit block in this playbook to solve?

PS: The dummy command in tasks RUN nova start {{ item }} HERE!!! doesn't wait. That's why I have to check the status manually.


Solution

  • By default, handlers are run at the end of a play.

    However, you can force the already notified handlers to run at a given time in your play by using the meta module.

    - name: force running of all notified handlers now
      meta: flush_handlers
    

    In your case, you just have to add it in between your two vm start tasks

    Edit: This will actually work in between your two tasks but not for each iteration in a single task so it is not really answering your full requirement.

    An other approach (to be developed) would be to include your check command directly in your task that should not return until conditions are met.

    Have you considered exploring the galaxy of openstack related modules? They might solve your current problems as well.