Какой шаблонизатор используется в Ansible?

Ответ

Ansible по умолчанию использует шаблонизатор Jinja2. Он позволяет динамически генерировать файлы конфигурации на основе переменных, фактов и логики.

Основные возможности Jinja2 в Ansible:

  • Подстановка переменных: {{ nginx_port }}
  • Условные операторы: {% if enable_ssl %} ... {% endif %}
  • Циклы: {% for host in backend_hosts %} ... {% endfor %}
  • Фильтры: Для преобразования данных, например {{ variable | upper }} или {{ list | join(",") }}.
  • Макросы и наследование шаблонов: Для создания переиспользуемых компонентов.

Практический пример: Шаблон для конфигурации Nginx (templates/nginx.conf.j2).

# nginx.conf.j2
server {
    listen {{ nginx_listen_port }} default_server;
    server_name {{ server_name }};
    root {{ web_root }};

    {% if enable_ssl %}
    listen 443 ssl;
    ssl_certificate /etc/ssl/certs/{{ ssl_cert_name }}.crt;
    ssl_certificate_key /etc/ssl/private/{{ ssl_cert_name }}.key;
    {% endif %}

    location / {
        proxy_pass http://backend/;
        proxy_set_header Host $host;
    }

    # Динамическое добавление бэкендов
    upstream backend {
        {% for host in backend_servers %}
        server {{ host.ip }}:{{ host.port }};
        {% endfor %}
    }
}

Задача в плейбуке для применения шаблона:

- name: Generate Nginx configuration from template
  ansible.builtin.template:
    src: nginx.conf.j2
    dest: /etc/nginx/sites-available/default
    owner: root
    group: root
    mode: '0644'
  notify: restart nginx

Ответ 18+ 🔞

А, ну вот, смотри, опять про эти шаблоны заговорили. Jinja2, блядь. Ну, в общем, представь себе такую хуйню: тебе надо на сто серверов один и тот же конфиг натянуть, но на каждом какой-то параметр свой — порт там, или имя сервера. Так вот, Ansible для этого и юзает Jinja2, ёпта. Это такой шаблонизатор, который позволяет из одного файла-заготовки наделать кучу разных конфигов, подставляя туда переменные на лету. Удобно, блядь, как швейцарский нож.

Что он, сука, умеет, этот Jinja2:

  • Вставить переменную: Просто пишешь {{ nginx_port }}, и на месте этой хуйни появится значение. Элементарно, Ватсон.
  • Сделать по условию: {% if enable_ssl %} ... {% endif %}. Если переменная enable_ssl равна true, то между этими тегами весь текст в конфиг попадёт. Если нет — нихуя не попадёт. Логика, мать её.
  • Наделать циклов: {% for host in backend_hosts %} ... {% endfor %}. Это когда у тебя список бэкендов, и тебе лень их руками прописывать. Цикл сам нагенерит строчек, овердохуища.
  • Применить фильтры: Это чтобы данные подрихтовать. Например, {{ variable | upper }} сделает все буквы большими, а {{ list | join(",") }} склеит список через запятую. Красота.
  • Макросы и наследование: Ну это уже для совсем извращенцев, которые хотят переиспользовать куски кода. Как лего, только для конфигов.

Смотри, как это выглядит на практике. Допустим, шаблон для Nginx (templates/nginx.conf.j2). Выглядит почти как обычный конфиг, но с дырками для переменных.

# nginx.conf.j2
server {
    listen {{ nginx_listen_port }} default_server;
    server_name {{ server_name }};
    root {{ web_root }};

    {% if enable_ssl %}
    listen 443 ssl;
    ssl_certificate /etc/ssl/certs/{{ ssl_cert_name }}.crt;
    ssl_certificate_key /etc/ssl/private/{{ ssl_cert_name }}.key;
    {% endif %}

    location / {
        proxy_pass http://backend/;
        proxy_set_header Host $host;
    }

    # Динамическое добавление бэкендов
    upstream backend {
        {% for host in backend_servers %}
        server {{ host.ip }}:{{ host.port }};
        {% endfor %}
    }
}

А в плейбуке задача будет проще некуда, ядрёна вошь:

- name: Generate Nginx configuration from template
  ansible.builtin.template:
    src: nginx.conf.j2
    dest: /etc/nginx/sites-available/default
    owner: root
    group: root
    mode: '0644'
  notify: restart nginx

Запускаешь плейбук — и Ansible возьмёт этот шаблон, подставит туда все значения переменных, которые ты ему задал (в инвентаре или где ещё), и запишет готовый, уникальный для каждого сервера конфиг прямо по указанному пути. И если enable_ssl был true, то и SSL-директивы подтянутся. А цикл for нагенерит столько строчек с server, сколько у тебя бэкендов в списке. Всё, блядь, автоматизировано, можно чай пить.