Why notify tasks aren't getting executed in ansible?

Ahsanul Haque picture Ahsanul Haque · May 18, 2016 · Viewed 7k times · Source

The problem I am facing is quite common, but the other solutions didn't work for me. As the question suggests, when I run my playbook, only the first notify handler gets executed. i.e. only firewalld is restarted, but updated bash profile isn't sourced.

Some people suggested notify chaining, but I wouldn't like to merge two tasks with completely different objectives. For example, one task could be adding ports to firewalld and then restarting it; another could be update my bash profile to display date with history command output.

N.B. the above snippet isn't my full .yml, only a part of it, so this may or may not work. But, the original file does work.

---
  tasks  
   - name: add port-80 to firewalld
     firewalld: zone=drop port=80/tcp permanent=true state=enabled

   - name: add port-443 to firewalld
     firewalld: zone=drop port=443/tcp permanent=true state=enabled

   - shell: firewall-cmd --reload
     notify:
      - Restart firewalld

   - name: Enabling time display in history
     blockinfile:
     dest: ~/.bash_profile
     block: |
         export HISTTIMEFORMAT="%d/%m/%y %T "
     notify:
      - Source the updated Bash profile


  handlers:
   - name: Restart firewalld
     service: name=firewalld state=restarted

   - name: Source the updated Bash profile
     shell: source ~/.bash_profile

...

Answer

Ahsanul Haque picture Ahsanul Haque · May 18, 2016

Finally, I have figured out the problem with the help of comments.

The notify handler will be executed if and only if state is changed as a result of the task.

The mistake I am doing is trying to install a package that is already installed. So, state wasn't getting changed.

Let's see it with an example,

---
- hosts: varnish
  remote_user: root

  tasks:    
   - name: Install tree
     yum: name=tree state=absent
     notify:
      - Do an echo

  handlers:
   - name: Do an echo
     debug: msg="This will be printed"    
...

We will run the play book two times.

After first run, we will get:

TASK [Install tree] ************************************************************
changed: [192.***.***.**]

RUNNING HANDLER [Do an echo] ***************************************************
ok: [192.***.***.**] => {
    "msg": "This will be printed"
}

PLAY RECAP *********************************************************************
192.***.***.**             : ok=1    changed=1    unreachable=0    failed=0   

As the state is changed ( Look at the changed=1 part ), debug message will be printed.

After second run, we will get:

TASK [Install tree] ************************************************************
ok: [192.***.***.**]

PLAY RECAP *********************************************************************
192.***.***.**             : ok=0    changed=0    unreachable=0    failed=0   

The thing to look at is handler isn't called unlike first run, because state isn't changed in the second run ( tree is already installed ).

I have posted it as an answer, it may help the fellow users.