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

时间:2018-08-29 14:01:32

标签: ansible ansible-inventory ansible-facts

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 }}"

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

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'] }}"

2 个答案:

答案 0 :(得分:1)

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

[desireenv:children]
wordpress
otherhost
etc

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

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

答案 1 :(得分:0)

我在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}}”同样如此

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

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

如果我不必将src_host和dest_host更改为hostvars ['localhost'] ...会很好,因为使用localhost似乎是任意的,而且如果我想立即运行多个ansible脚本该怎么办?其他具有不同的src_host和dest_host?使用清单文件会将其锁定,因此这不是理想的选择。如果没有其他答案,我将接受此答案,因为它是唯一可行的方法,并且从技术上讲,它可以完成我所提出的问题。