Перебор переменных инвентаризации с помощью Jinja2 в Ansible¶
Разберем как перебирать переменные или факты инвентаризации с помощью простого шаблона Jinja2.
Это может оказаться непростой задачей, а документация не самая лучшая для новичка, поэтому это будет очень короткий пост.
Проблематика¶
Одна из наиболее распространенных вещей, которые мы хотим сделать с Ansible, — это создать файл конфигурации для удаленного сервера. В идеале мы хотим делать это динамически на основе данных из нашего инвентаря, но доступ к инвентарю и его перебор может быть немного сложным для понимания.
В этом примере мы будем работать с инвентарем из 5 хостов с именами webserver01 – webserver05:
#--inventory.yaml
---
all:
hosts:
webserver[01:05]
children:
webservers:
webserver[01:05]
vars:
system_domain: truedev.ru
...
Для нашей демонстрации мы собираемся создать файл конфигурации haproxy, который в конечном итоге должен выглядеть следующим образом:
#--haproxy.cfg
defaults
mode http
timeout check 10s
frontend http
bind *:443
mode tcp
default_backend application
backend application
mode tcp
balance roundrobin
server webserver01.truedev.ru 10.0.1.10:8080 check fall 3 rise 2
server webserver02.truedev.ru 10.0.1.11:8080 check fall 3 rise 2
server webserver03.truedev.ru 10.0.1.12:8080 check fall 3 rise 2
server webserver04.truedev.ru 10.0.1.13:8080 check fall 3 rise 2
server webserver05.truedev.ru 10.0.1.14:8080 check fall 3 rise 2
Решение¶
Очевидно, мы можем найти имя хоста наших серверов, используя ansible host variable. Однако мы не можем просто использовать это в play. На первый взгляд это может выглядеть именно так, но если мы это сделаем, мы просто получим файл конфигурации с файлом, в котором одна и та же запись 5 раз, потому что мы ничего не зацикливаем, именно здесь на помощь приходит использование шаблона Jinja2. Мы также можем искать IP-адрес каждого узла, используя факты Ansible, что позволяет нам динамически искать IP-адрес каждого сервера во время выполнения.
Сначала нам нужно создать отдельный файл шаблона с именем haproxy.cfg.j2 (это просто имя файла, который вы пытаетесь создать, с дополнительным суффиксом .j2). Туда мы добавим некоторую шаблонную логику:
#--haproxy.cfg.j2
defaults
mode http
timeout check 10s
frontend http
bind *:443
mode tcp
default_backend application
backend application
mode tcp
balance roundrobin
{% for host in groups['webservers'] %}
server {{ host }}.{{ system_domain }} {{ hostvars[host].ansible_default_ipv4.address }}:8080 check fall 3 rise 2
{% endfor %}
---
- name: Build Config Files
hosts: webservers
gather_facts: true
any_errors_fatal:
tasks:
- name: Build haproxy.cfg
template:
src: haproxy.cfg.j2
dest: haproxy.cfg
...
Это создаст именно тот файл конфигурации, который мы ищем!