I'm trying to set up an NFS share between two nodes using Ansible. I'm using the role nfs
, which is executed by both nodes, and I separated client and server tasks using the when
condition.
After templating the NFS /etc/exports
on the server node I want to restart the NFS server using a handler, but the notify
doesn't seem to work.
This is the task I'm using:
- name: Template NFS /etc/exports
ansible.builtin.template:
src: exports
dest: /etc/exports
notify:
- Restart NFS server
when: inventory_hostname == groups['nfs-servers'][0]
I tried to restart the nfs server using this handler:
- name: Restart NFS server
ansible.builtin.systemd:
name: nfs-kernel-server
state: restarted
However, the handler never executes, even when exports is actually templated.
I think that's because the task always results in changed = false
for the client node (node2), due to the when condition. This is the output of the task:
TASK [nfs : Template NFS /etc/exports]
skipping: [node2] => changed=false
skip_reason: Conditional result was False
changed: [node1] => changed=true
checksum: db864f9235e5afc0272896c4467e244d3b9c4147
dest: /etc/exports
gid: 0
group: root
md5sum: 447bf4f5557e3a020c40f4e729c90a62
mode: '0644'
owner: root
size: 94
src: /home/test/.ansible/tmp/ansible-tmp-1673949188.2970977-15410-64672518997352/source
state: file
uid: 0
Any suggestions on how to use when
and notify
together? Is there a way to make the notify
ignore the skipping result?
Everything works fine if I use two roles and I remove the when
condition.
This is the expected behaviour, handlers are running operations on change, if there is no change, there will be no handler run.
So, you will have to trigger the handlers in a separate task in order to have the handler react to a change on another host. In this way of doing it, you will have to register
the result of the template
task in order to inspect its change state with the help of the hostsvar
from other hosts.
This can be done with a changed state on any task you like, for example, a debug
task.
From the task you are providing I also see some other improvements possible:
when
in order to limit a task to a single host, prefer delegation and the use of run_once: true
, which also offer the advantages that facts collected with run_once: true
are propagated to all hosts, and avoid the need to use hostsvar
.[WARNING]: Invalid characters were found in group names but not replaced,
use -vvvv to see details
and in verbose mode:
Not replacing invalid character(s) "{'-'}" in group name (nfs-servers)
Use underscores instead of dashes.So, with all this:
- hosts: nfs_servers
gather_facts: no
tasks:
- name: Template NFS /etc/exports
ansible.builtin.template:
src: exports
dest: /etc/exports
delegate_to: "{{ groups.nfs_servers.0 }}"
run_once: true
register: templated_exports
- name: Propagation of the change to notify handler
ansible.builtin.debug:
msg: Notify all handlers on /etc/exports change
notify:
- Restart NFS server
changed_when: true
when: templated_exports is changed
handlers:
- name: Restart NFS server
ansible.builtin.debug:
msg: Restarting NFS server now
When run with a file change:
PLAY [nfs_servers] *******************************************************
TASK [Template NFS /etc/exports] *****************************************
changed: [node1]
TASK [Propagation of the change to notify handler] ***********************
changed: [node1] =>
msg: Notify all handlers on /etc/exports change
changed: [node2] =>
msg: Notify all handlers on /etc/exports change
RUNNING HANDLER [Restart NFS server] *************************************
ok: [node1] =>
msg: Restarting NFS server now
ok: [node2] =>
msg: Restarting NFS server now
When run with no change:
PLAY [nfs_servers] *******************************************************
TASK [Template NFS /etc/exports] *****************************************
ok: [node1]
TASK [Propagation of the change to notify handler] ***********************
skipping: [node1]
skipping: [node2]