如何从多个主机在 Ansible 中创建组合变量

How create combined variable in Ansible from multiple hosts

场景示例:

inventory.ini 文件:

[web-servers]
web1.local ansible_host=10.10.10.11
web2.local ansible_host=10.10.10.12
web3.local ansible_host=10.10.10.13

...

另外,假设我有一个 playbook.yml 准备好执行

- hosts: web-servers
  become: true
  role: 
    - xxx
    - yyy

想要的结果是 JSON 变量 var_a = [{'hostname':'web1.local', 'ip_address':'10.10.10.11' }, {'hostname':'web2.local', 'ip_address':'10.10.10.12' },{'hostname':'web3.local', 'ip_address':'10.10.10.13'}] 这个变量应该在 roles

中可见

问题:这是否可能,如果是如何实现?

这样做的目的是在所有网络服务器中附加/etc/hosts(有关组中所有网络服务器的信息)。执行剧本时,变量将用于填充主机条目和其他目的。

也许ansible还有其他方法可以做到这一点

我使用了下面的主机文件

[default]
localhost

[web-server]
w1 ansible_host=192.168.5.100
w2 ansible_host=192.168.5.101
w3 ansible_host=192.168.5.102

实现JSON的任务如下所示,

- name: asdasd
  set_fact:
    hosts_dict : "{{ hosts_dict|default([]) + [ {'hostname': item, 'ip_address': hostvars[item]['ansible_host'] } ] }}"
  with_items: " {{ groups['web-server'] }}"

输出如下所示[使用调试模块显示了hosts_dict的值],

TASK [debug] ************************************************************************
ok: [localhost] => {
    "msg": [
        {
            "hostname": "w1",
            "ip_address": "192.168.5.100"
        },
        {
            "hostname": "w2",
            "ip_address": "192.168.5.101"
        },
        {
            "hostname": "w3",
            "ip_address": "192.168.5.102"
        }
    ]
}

字典可能更有用。例如

- hosts: all
  gather_facts: false
  tasks:
    - set_fact:
        hosts_dict: "{{ dict(names|zip(ips)) }}"
      vars:
        names: "{{ groups.web_servers }}"
        ips: "{{ groups.web_servers|map('extract',hostvars,'ansible_host')|list }}"
      run_once: true
    - debug:
        var: hosts_dict
      run_once: true

给予

  hosts_dict:
    web1.local: 10.10.10.11
    web2.local: 10.10.10.12
    web3.local: 10.10.10.13