I have the following file structure:
$ tree roles/os
roles/os
├── handlers
│ └── main.yaml
└── tasks
└── main.yaml
tasks/main.yaml
:
---
- name: Upgrade all packages
ansible.builtin.apt:
update_cache: true
upgrade: dist
- name: Update bootloader firmware
ansible.builtin.command: rpi-eeprom-update -ad
changed_when: eeprom_update.stdout.find('updates pending') != -1
notify: Perform reboot
register: eeprom_update
- name: Check reboot status
ansible.builtin.stat:
path: /var/run/reboot-required
get_checksum: false
changed_when: reboot.stat.exists
notify: Perform reboot
register: reboot
handlers/main.yaml
:
---
- name: Perform reboot
ansible.builtin.reboot:
post_reboot_delay: 30
when: >
eeprom_update.stdout.find('updates pending') != -1 or
reboot.stat.exists
With the above configuration, a reboot is performed, only if a change occurs.
Is that the correct way to perform a conditional reboot with a handler?
You don't have to repeat the conditions in the handler. The conditions were used to notify the handler in the tasks.
when: >
eeprom_update.stdout.find('updates pending') != -1 or
reboot.stat.exists
Remove the condition from the handler
- name: Perform reboot
ansible.builtin.reboot:
post_reboot_delay: 30
Notes:
- name: Test the syntax of the condition
block:
- name: Wrong. The result of the expression is string.
debug:
msg: >
eeprom_update.stdout.find('updates pending') != -1 or
reboot.stat.exists
- name: Correct. The result of the expression is boolean.
debug:
msg: "{{ eeprom_update.stdout.find('updates pending') != -1 or
reboot.stat.exists }}"
- name: Do not use braces "{{ '{{' }}" in the conditions. Variables are
expanded automatically in a condition.
debug:
msg: Correct. The result of the expression is boolean
when: eeprom_update.stdout.find('updates pending') != -1 or
reboot.stat.exists
gives
TASK [Wrong. The result of the expression is string.] ****************************************
ok: [localhost] =>
msg: |-
eeprom_update.stdout.find('updates pending') != -1 or reboot.stat.exists
TASK [Correct. The result of the expression is boolean.] *************************************
ok: [localhost] =>
msg: true
TASK [Do not use braces "{{" in the conditions. Variables are expanded automatically in a condition.] ***
ok: [localhost] =>
msg: Correct. The result of the expression is boolean
shell> tree .
.
├── ansible.cfg
├── hosts
└── pb.yml
0 directories, 3 files
shell> cat ansible.cfg
[defaults]
gathering = explicit
inventory = $PWD/hosts
roles_path = $PWD/roles
remote_tmp = ~/.ansible/tmp
retry_files_enabled = false
stdout_callback = yaml
shell> cat hosts
localhost
The reboot file exists
shell> ls -1 /tmp/reboot-required
/tmp/reboot-required
The playbook
shell> cat pb.yml
- hosts: localhost
tasks:
- name: Update bootloader firmware
ansible.builtin.command: echo 'updates pending'
register: eeprom_update
changed_when: eeprom_update.stdout.find('updates pending') != -1
notify: Perform reboot
- debug:
var: eeprom_update.stdout
- name: Check reboot status
ansible.builtin.stat:
path: /tmp/reboot-required
get_checksum: false
register: reboot
changed_when: reboot.stat.exists
notify: Perform reboot
- debug:
var: reboot.stat.exists
- name: Test the syntax of the condition
block:
- name: Wrong. The result of the expression is string.
debug:
msg: >
eeprom_update.stdout.find('updates pending') != -1 or
reboot.stat.exists
- name: Correct. The result of the expression is boolean.
debug:
msg: "{{ eeprom_update.stdout.find('updates pending') != -1 or
reboot.stat.exists }}"
- name: Do not use braces '{{' '}}' in the conditions. Variables are
expanded automatically in a condition.
debug:
msg: Correct. The result of the expression is boolean
when: eeprom_update.stdout.find('updates pending') != -1 or
reboot.stat.exists
handlers:
- name: Perform reboot
debug:
msg: Perform reboot
gives
shell> ansible-playbook pb.yml
PLAY [localhost] *****************************************************************************
TASK [Update bootloader firmware] ************************************************************
changed: [localhost]
TASK [debug] *********************************************************************************
ok: [localhost] =>
eeprom_update.stdout: updates pending
TASK [Check reboot status] *******************************************************************
changed: [localhost]
TASK [debug] *********************************************************************************
ok: [localhost] =>
reboot.stat.exists: true
TASK [Wrong. The result of the expression is string.] ****************************************
ok: [localhost] =>
msg: |-
eeprom_update.stdout.find('updates pending') != -1 or reboot.stat.exists
TASK [Correct. The result of the expression is boolean.] *************************************
ok: [localhost] =>
msg: true
TASK [Do not use braces "{{" in the conditions. Variables are expanded automatically in a condition.] ***
ok: [localhost] =>
msg: Correct. The result of the expression is boolean
RUNNING HANDLER [Perform reboot] *************************************************************
ok: [localhost] =>
msg: Perform reboot
PLAY RECAP ***********************************************************************************
localhost: ok=8 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0