I've been searching for an answer to this and can't seem to find the exact answer. I am running a task which prompts a y
or n
selection for each elements of an installer_type
list.
The issues seems to be that when I run this it is only registering the variable in the first host that it is run it.
How can I have this user input registered for all of the hosts that the playbook is being run against?
- name: AppLauncher Installation
gather_facts: false
hosts: all
tasks:
- pause:
prompt: "Select Installer {{ item|basename }} [y/n]"
register: selected_installers
loop: "{{ installer_types }}"
loop_control:
label: "{{ item|basename }}"
- name: Run Install roles
include_role:
name: "{{ item.item|lower }}"
loop: "{{ selected_installers.results }}"
loop_control:
label: "{{ item.item|basename }}"
when: item.user_input == 'y' and
item.item == ( item.item|basename)
When the Run Install roles
task is run it throws an error for all hosts except the first host, saying that the selected_installers
variable is not defined for those other hosts.
Indeed, I can reproduce this behaviour outside of a role context:
- pause:
prompt: "`pause_var` definition"
register: pause_var
- command: "echo {{ pause_var.user_input }}"
Would fail on two out of my three hosts. So, the fact is not propagated on all hosts.
This said, there is one playbook keyword designed to propagate results and fact on all hosts, it is run_once
.
run_once
Boolean that will bypass the host loop, forcing the task to attempt to execute on the first host available and afterwards apply any results and facts to all active hosts in the same batch.
Source: https://docs.ansible.com/ansible/latest/reference_appendices/playbooks_keywords.html#task
So, your fix would be to add that run_once: true
in your pause task:
- pause:
prompt: "Select Installer {{ item|basename }} [y/n]"
register: selected_installers
run_once: true
loop: "{{ installer_types }}"
loop_control:
label: "{{ item|basename }}"
Given the two tasks:
- pause:
prompt: "`pause_var` definition"
register: pause_var
run_once: true
- command: "echo {{ pause_var.user_input }}"
no_log: true # added to make the fatal error less verbose
A run would yield:
TASK [pause] ******************************************************
[pause]
`pause_var` definition:
foo^Mok: [ansible-node-1]
TASK [command] ****************************************************
changed: [ansible-node-3]
changed: [ansible-node-2]
changed: [ansible-node-1]
Demonstration of the failing behaviour:
- pause:
prompt: "`pause_var` definition"
register: pause_var
- command: "echo {{ pause_var.user_input }}"
no_log: true # added to make the fatal error less verbose
Running those two tasks:
TASK [pause] ******************************************************
[pause]
`pause_var` definition:
foo^Mok: [ansible-node-1]
TASK [command] ****************************************************
fatal: [ansible-node-2]: FAILED! =>
censored: 'the output has been hidden due to
the fact that ''no_log: true'' was specified for this result'
fatal: [ansible-node-3]: FAILED! =>
censored: 'the output has been hidden due to
the fact that ''no_log: true'' was specified for this result'
changed: [ansible-node-1]