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
...
In Ansible, a handler refers to a particular task that executes when triggered by the notify module. Handlers perform an action defined in the task when a change occurs in the remote host.
In a nutshell, handlers are special tasks that only get executed when triggered via the notify directive. Handlers are executed at the end of the play, once all tasks are finished. In Ansible, handlers are typically used to start, reload, restart, and stop services.
Notifying handlers In the above example the handlers are executed on task change in the following order: Restart memcached , Restart apache . Handlers are executed in the order they are defined in the handlers section, not in the order listed in the notify statement.
The easiest way to run only one task in Ansible Playbook is using the tags statement parameter of the “ansible-playbook” command. The default behavior is to execute all the tags in your Playbook with --tags all .
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With