如何在没有冗余代码的情况下在一个地方为所有后续主机设置变量?



TL/DR:我有"src_host"和"dest_host"变量,我想用它来设置戏剧中的"- hosts:"对象。但是,我必须在每个"- hosts:"部分的"vars:"下为每个播放再次设置它们,例如 src_host="{{ hostvars['localhost']['src_host'] }}" 如何在开始时设置这两个变量而不必重置它们?

我的主机文件如下所示

[wordpress]
localhost ansible_user=user ansible_port=22 ansible_ssh_private_key_file=/home/user/.ssh/id_rsa
root_localhost ansible_user=root ansible_port=22 ansible_ssh_private_key_file=/home/user/.ssh/id_rsa
---snip---
server2.net ansible_host="server2.net" ansible_user=user ansible_port=22 ansible_ssh_private_key_file=/home/user/.ssh/id_rsa
root_server2.net ansible_host="server2.net" ansible_user=root ansible_port=22  ansible_ssh_private_key_file=/home/user/.ssh/id_rsa

我的剧本的开头是这样的:

- hosts: localhost, server2.net, root_server2.net #always include "localhost" in this list because it is needed to store the variables for the src_host and dest_host
vars:
src_host: localhost #modify these and the host will be changed for all subsequent plays/tasks
dest_host: server2.net #modify these and the host will be changed for all subsequent plays/tasks
src_dump_path: /home/user/cvrt9_dump.sql #set vars for copying file
roles:  
- set_facts_for_db_copy
- hosts: "{{ src_host }}" 
vars: 
src_host: "{{ hostvars['localhost']['src_host'] }}"
dest_host: "{{ hostvars['localhost']['dest_host'] }}"
---snip---
roles:
- dump_db
- copy_file

等。。。

对于"- set_facts_for_db_copy",我有"main.yml",我在其中设置了"src_host"和"dest_host"变量:

---
# tasks file for set_facts_for_db_copy
- name: create variables that equal src_dump_path and set src_host/dest_host
set_fact:
---snip---
src_host: "{{ src_host }}"
dest_host: "{{ dest_host }}"

因此,我需要为所有后续的"-hosts:"设置"src_host"和"dest_host",这些"-hosts:"通过从"set_fact_for_db_copy"设置的主机变量之一获取值来使用它们。我随机选择了"本地主机",您可能已经注意到:

src_host: "{{ hostvars['localhost']['src_host'] }}"
dest_host: "{{ hostvars['localhost']['dest_host'] }}"

如果我那里没有那行,我会得到:

user@localhost:/home/maintainer/ansible-play$ ansible-playbook -i hosts_tat-kay playbook.yml 
PLAY [localhost, server2.net, root_server2.net] **************
TASK [setup] *******************************************************************
ok: [server2.net]
ok: [root_server2.net]
ok: [localhost]
TASK [set_facts_for_db_copy : create variables that equal src_dump_path] *******
ok: [localhost]
ok: [server2.net]
ok: [root_server2.net]
ERROR! the field 'hosts' has an invalid value, which appears to include a variable that is undefined. The error was: 'src_host' is undefined
The error appears to have been in '/home/maintainer/ansible-play/playbook.yml': line 14, column 3, but may
be elsewhere in the file depending on the exact syntax problem.
The offending line appears to be:

- hosts: "{{ src_host }}" 
^ here

现在我可以在我的主机文件中设置这些变量:

[wordpress:vars]
src_host=localhost
dest_host=server2.net

但是,我仍然必须从我的剧本中的子"-hosts:"对象中引用它们,带有"{{ hostvars['localhost']['src_host'] }}"等。所以我的问题是,如何在所有后续的"-hosts:"对象(如下所示(中摆脱这个冗余代码,同时仍然让我在开始时更改一次"src_host"和"dest_host"变量,并让这些更改影响其余的播放?谢谢。

src_host: "{{ hostvars['localhost']['src_host'] }}"
dest_host: "{{ hostvars['localhost']['dest_host'] }}"

为此,请使用您的清单文件,创建您需要变量的主机的父组,如下所示。

[desireenv:children]
wordpress
otherhost
etc

然后将 var 值分配给创建的新父组

[desireenv:vars]
src_host: "{{ hostvars['localhost']['src_host'] }}"
dest_host: "{{ hostvars['localhost']['dest_host'] }}"

我在 https://stackoverflow.com/users/4716639/bryan-calvo-benoit 的帮助下找到的一个解决方案是将其放在我的主机文件(库存文件(中

[wordpress] 
localhost 
server2.net 
[testenv:children] 
wordpress 
[testenv:vars] 
src_host=localhost 
dest_host=server2.net 

然后在 ansible 剧本和它调用的角色中,我不得不替换

"{{ src_host }}" 

"{{ hostvars['localhost']['src_host'] }}"

同样对于"{{ dest_host }}">

但是,我可以在我的 ansible 剧本中删除此冗余代码:

src_host: "{{ hostvars['localhost']['src_host'] }}"
dest_host: "{{ hostvars['localhost']['dest_host'] }}"

如果我不必将src_host和dest_host更改为 hostvars['localhost'],那就太好了......因为使用 localhost 似乎是任意的,而且如果我想用不同的src_host和dest_host一个接一个地运行多个 ansible 脚本怎么办?使用库存文件会将其锁定,因此这并不理想。如果没有其他人回答,我会接受这个答案,因为它是唯一有效的答案,而且从技术上讲,它完成了我的问题。

最新更新