Ansible提示选择未为所有主机设置变量。

huangapple go评论69阅读模式
英文:

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]: 失败! =&gt;
  已审查:'由于指定了 'no_log: true',已隐藏输出'
致命: [ansible-node-3]: 失败! =&gt;
  已审查:'由于指定了 'no_log: true',已隐藏输出'
已更改: [ansible-node-1]
英文:

Indeed, I can reproduce this behaviour outside of a role context:

- pause:
    prompt: &quot;`pause_var` definition&quot;
  register: pause_var

- command: &quot;echo {{ pause_var.user_input }}&quot;

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_&lt;/sup>

So, your fix would be to add that run_once: true in your pause task:

- pause:
    prompt: &quot;Select Installer {{ item|basename }} [y/n]&quot;
  register: selected_installers
  run_once: true
  loop: &quot;{{ installer_types }}&quot;
  loop_control:
    label: &quot;{{ item|basename }}&quot;

Given the two tasks:

- pause:
    prompt: &quot;`pause_var` definition&quot;
  register: pause_var
  run_once: true

- command: &quot;echo {{ pause_var.user_input }}&quot;
  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: &quot;`pause_var` definition&quot;
  register: pause_var

- command: &quot;echo {{ pause_var.user_input }}&quot;
  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! =&gt; 
  censored: &#39;the output has been hidden due to 
    the fact that &#39;&#39;no_log: true&#39;&#39; was specified for this result&#39;
fatal: [ansible-node-3]: FAILED! =&gt; 
  censored: &#39;the output has been hidden due to 
    the fact that &#39;&#39;no_log: true&#39;&#39; was specified for this result&#39;
changed: [ansible-node-1]

huangapple
  • 本文由 发表于 2023年4月20日 02:33:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/76057812.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定