Как создать объединенную переменную в Ansible с нескольких хостов

#ansible #ansible-2.x #ansible-facts

#ансибль #ansible-2.x #ansible-факты

Вопрос:

Пример сценария:

файл 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'}]
Эта переменная должна быть видна в ролях

Вопрос: Возможно ли это вообще, и если да, то как этого добиться?

Цель этого — добавить /etc/hosts на все веб-серверы (информацию обо всех веб-серверах в группе). Когда playbook будет выполнен, переменная будет использоваться для заполнения записей хоста и для других целей.

Возможно, у ansible есть другие методы для достижения этой цели

Комментарии:

1. Я ответил на вопрос, поскольку, я думаю, вы, возможно, новичок в ansible и stackoverflow. Но в будущем, пожалуйста, задавайте свои вопросы, а не прямые ответы, делясь своим подходом и конкретными следами ошибок.

Ответ №1:

Я использовал приведенный ниже файл хоста

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

Ответ №2:

Словарь может быть более полезным. Например

 - 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