Подтвердить что ты не робот

Как назначить массив переменной в Ansible-Playbook

В playbook я получил следующий код:

---
- hosts: db
  vars:
    postgresql_ext_install_contrib: yes
    postgresql_pg_hba_passwd_hosts: ['10.129.181.241/32']
...

Я хотел бы заменить значение postgresql_pg_hba_passwd_hosts на всех моих веб-серверов private ips. Я понимаю, что я могу получить значения этого в шаблоне:

{% for host in groups['web'] %}
   {{ hostvars[host]['ansible_eth1']['ipv4']['address'] }}
{% endfor %}

Каков самый простой/простой способ присвоить результат этого цикла переменной в playbook? Или есть лучший способ собрать эту информацию в первую очередь? Должен ли я помещать этот цикл в шаблон?

Дополнительная проблема: мне нужно добавить /32 к каждой записи.

4b9b3361

Ответ 1

Вы можете назначить список переменной set_fact и возможно фильтра.

Поместите настраиваемый фильтр в каталог filter_plugins следующим образом:

(ansible top directory)
site.yml
hosts
filter_plugins/
    to_group_vars.py

to_group_vars.py конвертировать hostvars в список, выбранный группой.

from ansible import errors, runner
import json

def to_group_vars(host_vars, groups, target = 'all'):
    if type(host_vars) != runner.HostVars:
        raise errors.AnsibleFilterError("|failed expects a HostVars")

    if type(groups) != dict:
        raise errors.AnsibleFilterError("|failed expects a Dictionary")

    data = []
    for host in groups[target]:
        data.append(host_vars[host])
    return data

class FilterModule (object):
    def filters(self):
        return {"to_group_vars": to_group_vars}

Используйте это:

---
- hosts: all
  tasks:
  - set_fact:
      web_ips: "{{hostvars|to_group_vars(groups, 'web')|map(attribute='ansible_eth0.ipv4.address')|list }}"
  - debug:
      msg: "web ip is {{item}}/32"
    with_items: web_ips

Ответ 2

в playbook:

vars:
     - arrayname:
        - name: itemname
          value1: itemvalue1
          value2: itemvalue2
        - name: otheritem
          value1: itemvalue3
          value2: itemvalue4

в шаблоне: (пример имеет тип ini файла, с разделами, ключами и значениями):

{% for item in arrayname %}
[{{ item.name }}]
key1 = {{ item.value1 }}
key2 = {{ item.value2 }}
{% endfor %}

Это должно сделать шаблон следующим:

[itemname]
key1 = itemvalue1
key2 = itemvalue2
[otheritem]
key1 = itemvalue3
key2 = itemvalue4

Ответ 3

Вы можете использовать фильтры jinja2:

{{ groups['nodes']|map('extract', hostvars, ['ansible_eth1','ipv4', 'address']) |list }}

вернет список ip-адресов. то есть.

---
- hosts: db
  vars:
    postgresql_ext_install_contrib: yes
    postgresql_pg_hba_passwd_hosts: {{ groups['nodes']|map('extract', hostvars, ['ansible_eth1','ipv4', 'address']) |list }}
...

Не включает вызов (добавление /32). Но также должно быть возможно как-то с фильтрами jinja2.

Возвращает несущественную версию >= 2.1

Ответ 4

Переменные могут быть представлены как стандартные структуры YAML, поэтому вы можете присвоить значение списка ключу следующим образом:

---
- hosts: db
  vars:
    postgresql_ext_install_contrib: yes
    postgresql_pg_hba_passwd_hosts:
      - '10.129.181.241/32'
      - '1.2.3.0/8'