Как назначить массив переменной в 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
к каждой записи.
Ответы
Ответ 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'
Ответ 5
Чтобы добавить '/32' к адресу, вы можете использовать фильтр Ansible ipaddr (преобразование в нотацию CIDR).
{{ ip_addresses|ipaddr('host') }}