英文:
Ansible prompt selection not setting variable for all hosts
问题
当运行Run Install roles
任务时,除了第一个主机外,对于所有其他主机,它会抛出错误,指出selected_installers
变量未定义。
英文:
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.
答案1
得分: 3
确实,我可以在角色上下文之外重现这种行为:
- 暂停:
提示: "定义`pause_var`"
寄存: pause_var
- 命令: "echo {{ pause_var.user_input }}"
会在我三个主机中的两个上失败。
因此,事实并未传播到所有主机。
话虽如此,有一个播放簧关键字旨在传播所有主机上的结果和事实,即 run_once
。
run_once
将绕过主机循环,强制任务尝试在第一个可用主机上执行,然后将结果和事实应用于同一批中的所有活动主机。
<sup>来源:https://docs.ansible.com/ansible/latest/reference_appendices/playbooks_keywords.html#task</sup>
因此,您的修复方法是在暂停任务中添加 run_once: true
:
- 暂停:
提示: "选择安装程序{{ item|basename }} [y/n]"
寄存: selected_installers
run_once: true
循环: "{{ installer_types }}"
循环控制:
标签: "{{ item|basename }}"
给定两个任务:
- 暂停:
提示: "定义`pause_var`"
寄存: pause_var
run_once: true
- 命令: "echo {{ pause_var.user_input }}"
不记录日志: true # 添加以使致命错误不那么冗长
运行结果如下:
TASK [pause] ******************************************************
[pause]
`pause_var` 定义:
foo^Mok: [ansible-node-1]
TASK [command] ****************************************************
已更改: [ansible-node-3]
已更改: [ansible-node-2]
已更改: [ansible-node-1]
演示失败行为:
- 暂停:
提示: "定义`pause_var`"
寄存: pause_var
- 命令: "echo {{ pause_var.user_input }}"
不记录日志: true # 添加以使致命错误不那么冗长
运行这两个任务:
TASK [pause] ******************************************************
[pause]
`pause_var` 定义:
foo^Mok: [ansible-node-1]
TASK [command] ****************************************************
致命: [ansible-node-2]: 失败! =>
已审查:'由于指定了 'no_log: true',已隐藏输出'
致命: [ansible-node-3]: 失败! =>
已审查:'由于指定了 'no_log: true',已隐藏输出'
已更改: [ansible-node-1]
英文:
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.
<sup>_Source: https://docs.ansible.com/ansible/latest/reference_appendices/playbooks_keywords.html#task_</sup>
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 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 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]
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论