如何为所有播放/主机设置Ansible变量



此问题未得到回答。有人提到了环境变量。你能详细说明一下吗

这似乎是一个简单的问题,但并不容易解决。它不断出现。尤其是在出现错误的情况下。我需要一个全局变量。一个我可以在处理一个主机播放时设置的,然后在稍后与另一个主机进行检查。简而言之,这样我就可以稍后根据变量在剧本中进行分支。

我们无法控制自定义软件的安装,但如果安装了,我们必须在其他机器上安装不同的软件。最重要的是,安装方式各不相同,具体取决于VM文件夹。我的王国为全球变种

变量的作用域仅与当前ansible_hostname相关。是的,我们有group_vars/all.yml作为全局变量,但我们不能在剧中设置它们。如果我设置了一个变量,其他主机的play/task都看不到。我理解变量的范围,但我想设置一个全局变量,它可以在所有playbook play中读取。实际实现并不重要,但变量访问是(重要的)。

我的问题:有没有办法设置在另一台主机上运行不同任务时可以检查的变量?类似于setGlobalSpaceVar(myvar,true)?我知道没有这样的方法,但我正在找一个变通办法。重新表述:在一个任务中为一个主机设置一个变量,然后在另一个任务的另一个主机中读取该变量。

我能想到的唯一方法是更改控制器上的文件,但这似乎是假的。

示例

以下内容与oracle备份和我们的本地可执行文件有关,但我保留它的通用性。下面-是的,我可以运行一次,但这不能回答我的问题这种可变访问问题在不同的环境中不断出现。

我有4台xyz服务器。我有两个程序需要执行,但只能在两台不同的机器上执行。我不知道是哪一个。可以针对不同的VM环境更改设置。

我们的程序One在有驱动器E的服务器上运行。我可以使用ansible找到哪个服务器有驱动器E,并在设置变量(driveE_machine)时进行相应的播放。它只适用于该主机。为此,其他3台机器将不会设置driveE_machine。在稍后的游戏中,我只需要在其他3台机器中的一台上执行另一个程序。这意味着我需要设置一个变量,该变量可以被其他两个没有运行第二个程序的主机读取。我不知道该怎么做。

库存文件:

[xyz]
serverxyz[1:4].private.mystuff

行动手册示例:

---
- name: stackoverflow variable question
hosts: xyz
gather_facts: no
serial: 1
tasks:
- name: find out who has drive E
win_shell: dir e:
register: adminPage
ignore_errors: true
# This sets a variable that can only be read for that host
- name: set fact driveE_machine when rc is 0
set_fact:
driveE_machine: "{{inventory_hostname}}"
when: adminPage.rc == 0
- name: run program 1
include: tasks/program1.yml
when: driveE_machine is defined
# program2.yml executes program2 and needs to set some kind of variable
# so this include can only be executed once for the other 3 machines 
# (not one that has driveE_machine defined and ???
- name: run program 2
include: tasks/program2.yml
when: driveE_machine is undefined and ???
# please don't say run_once: true - that won't solve my variable access question

有没有办法设置在另一台主机上运行任务时可以检查的变量?

不确定你实际想要什么,但你可以用一个循环任务(模拟全局变量)为剧中的每个主机设置一个事实:

playbook.yml

---
- hosts: mytest
gather_facts: no
vars:
tasks:
# Set myvar fact for every host in a play
- set_fact:
myvar: "{{ inventory_hostname }}"
delegate_to: "{{ item }}"
with_items: "{{ play_hosts }}"
run_once: yes
# Ensure that myvar is a name of the first host
- debug:
msg: "{{ myvar }}"

主机

[mytest]
aaa ansible_connection=local
bbb ansible_connection=local
ccc ansible_connection=local

结果

PLAY [mytest] ******************
META: ran handlers
TASK [set_fact] ******************
ok: [aaa -> aaa] => (item=aaa) => {"ansible_facts": {"myvar": "aaa"}, "ansible_facts_cacheable": false, "changed": false, "failed": false, "item": "aaa"}
ok: [aaa -> bbb] => (item=bbb) => {"ansible_facts": {"myvar": "aaa"}, "ansible_facts_cacheable": false, "changed": false, "failed": false, "item": "bbb"}
ok: [aaa -> ccc] => (item=ccc) => {"ansible_facts": {"myvar": "aaa"}, "ansible_facts_cacheable": false, "changed": false, "failed": false, "item": "ccc"}
TASK [debug] ******************
ok: [aaa] => {
"msg": "aaa"
}
ok: [bbb] => {
"msg": "aaa"
}
ok: [ccc] => {
"msg": "aaa"
}

https://docs.ansible.com/ansible/latest/user_guide/playbooks_variables.html#fact-缓存

如文档中其他地方所示,一个服务器可以引用另一个服务器的变量,如下所示:{{ hostvars['asdf.example.com']['ansible_os_family'] }}

这甚至适用于剧本中动态设置的变量。

这个答案没有预先假设您的主机名,也没有预先假设有多少主机有一个"驱动器E:";。它将选择第一个可到达的;驱动器E:";。我没有窗户盒子,所以我用随机抛硬币的方式来假装主人是否会这样做;你当然可以使用你原来的win_shell任务,我已经评论掉了。

---
- hosts: all
gather_facts: no
# serial: 1
tasks:
# - name: find out who has drive E
#   win_shell: dir e:
#   register: adminPage
#   ignore_errors: true
- name: "Fake finding hosts with drive E:."
# I don't have hosts with "drive E:", so fake it.
shell: |
if [ $RANDOM -gt 10000 ] ; then
exit 1
else
exit 0
fi
args:
executable: /bin/bash
register: adminPage
failed_when: false
ignore_errors: true

- name: "Dict of hosts with E: drives."
run_once: yes
set_fact:
driveE_status: "{{ dict(ansible_play_hosts_all |
zip(ansible_play_hosts_all |
map('extract', hostvars, ['adminPage', 'rc'] ) | list
))
}}"
- name: "List of hosts with E: drives."
run_once: yes
set_fact:
driveE_havers: "{%- set foo=[] -%}
{%- for dE_s in driveE_status -%}
{%- if driveE_status[dE_s] == 0 -%}
{%- set _ = foo.append( dE_s ) -%}
{%- endif -%}
{%- endfor -%}{{ foo|list }}"                                     
- name: "First host with an E: drive."
run_once: yes
set_fact:
driveE_first: "{%- set foo=[] -%}
{%- for dE_s in driveE_status -%}
{%- if driveE_status[dE_s] == 0 -%}
{%- set _ = foo.append( dE_s ) -%}
{%- endif -%}
{%- endfor -%}{{ foo|list|first }}"                                     
- name: Show me.
run_once: yes
debug:
msg:
- "driveE_status: {{ driveE_status }}"
- "driveE_havers: {{ driveE_havers }}"
- "driveE_first: {{ driveE_first }}"

对我来说很有效,你可以直接使用寄存器var,而无需使用set_fact。

---
- hosts: manager
tasks:
- name: dir name
shell: cd /tmp && pwd
register: homedir
when: "'manager' in group_names"
- hosts: all
tasks:
- name: create a test file
shell: touch "{{hostvars['manager.example.io'['homedir'].stdout}}/t1.txt"

我使用了"set_fact";ansible任务提示菜单中的模块,帮助将用户输入传递到所有库存主机。

#监控游戏-主机:全部gather_facts:yes变成:是的任务:-暂停:提示:"\n\n要执行哪个监视?\n\n--------------------------------------\n\n1。内存利用率:\n2。CPU利用率:\n3。文件系统实用程序ization:\n4.存在于行动手册:\n5。获取Nmon报告\n\n请选择选项:\n--------------------------------------\n"寄存器:菜单-设置行为(_F):选项:"{{menu.user_input}}"delegate_to:"{{item}}"with_items:"{{play_hosts}}"run_once:是#1内存监控-暂停:提示:"\n--------------------------------------\n输入监视事件编号="寄存器:incident_number_result当:option="1"-name:标准化偶发事件编号变量设置行为(_F):incident_number:"{{incident_number_result.user_input}}"当:option="1"delegate_to:"{{item}}"with_items:"{{play_hosts}}"run_once:是

可靠的剧本结果是

[ansibusr@ansiblemaster monitoring]$ ansible-playbook monitoring.yml
PLAY [all] **************************************************************************
TASK [Gathering Facts] **************************************************************************
ok: [node2]
ok: [node1]
[pause]

Which monitoring you want to perform?
--------------------------------------
1. Memory Utilization:
2. CPU Utilization:
3. Filesystem Utilization:
4. Exist from Playbook:
5. Fetch Nmon Report
Please select option:
--------------------------------------
:
TASK [pause] **************************************************************************
ok: [node1]
TASK [set_fact] **************************************************************************
ok: [node1 -> node1] => (item=node1)
ok: [node1 -> node2] => (item=node2)
[pause]
--------------------------------------
Enter monitoring Incident Number = :
INC123456
TASK [pause] **************************************************************************
ok: [node1]
TASK [Standardize incident_number variable] ****************************************************************************************************************************
ok: [node1 -> node1] => (item=node1)
ok: [node1 -> node2] => (item=node2)

最新更新