Ответ
Преимущества:
- Гибкость и динамичность: Использование Jinja2 позволяет встраивать логику (условия, циклы, фильтры) прямо в конфигурационные файлы. Это незаменимо для генерации конфигов, которые зависят от переменных инвентаря (например, настройки для dev/stage/prod).
- Идемпотентность и безопасность: Модуль
templateвычисляет хэш итогового файла и применяет изменения только если содержимое изменилось, что предотвращает ненужные перезапуски служб. Также он корректно обрабатывает права доступа (mode). - Интеграция с Vault: Позволяет безопасно использовать секреты из Ansible Vault прямо в шаблонах, что критично для хранения паролей, ключей и токенов.
- Централизация управления: Все настройки для разных окружений хранятся в одном шаблоне и управляются через переменные, а не через множество копий конфигов.
Недостатки и сложности:
- Сложность отладки: Ошибки синтаксиса Jinja2 или обращения к необъявленным переменным могут быть неочевидны, особенно в сложных шаблонах. Приходится использовать
ansible-playbook --checkи--diffили выводить промежуточный результат через модульdebug. - Отсутствие строгой валидации: Шаблон может сгенерировать синтаксически неверный конфигурационный файл для целевой системы (например, invalid YAML или JSON), и это обнаружится только при попытке её запуска.
- Производительность на больших файлах: Обработка очень больших шаблонов или их большое количество может замедлить выполнение плейбука.
Пример из практики — шаблон конфига Prometheus для динамического обнаружения сервисов в Kubernetes:
# prometheus.yml.j2
global:
scrape_interval: {{ prometheus_scrape_interval }}
scrape_configs:
- job_name: 'kubernetes-pods'
kubernetes_sd_configs:
- role: pod
relabel_configs:
# Аннотации pod'а становятся метками
- source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
action: keep
regex: true
- source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path]
target_label: __metrics_path__
regex: (.+)
{% if enable_blackbox_exporter %}
- job_name: 'blackbox'
metrics_path: /probe
params:
module: [http_2xx]
static_configs:
- targets:
{% for endpoint in blackbox_targets %}
- {{ endpoint }}
{% endfor %}
{% endif %}
И задача для его применения:
- name: Deploy Prometheus configuration
ansible.builtin.template:
src: templates/prometheus.yml.j2
dest: /etc/prometheus/prometheus.yml
owner: prometheus
group: prometheus
mode: '0644'
notify: restart prometheus