Аннотация
Эта статья - простое объяснение для начинающих, как в Ansible аккуратно управлять конфигами и данными: править файлы без template, собирать и “чистить” переменные фильтрами Jinja2 и подтягивать значения извне через lookups/query (например, пароли и настройки). Если вы хотите быстро понять, “что делает команда и почему это надёжно” - вы по адресу.
Боль: «Мы меняем конфиги — и боимся сломать прод»
Обычно проблема такая:
- кто-то «чуть-чуть поправил» конфиг на сервере;
- через месяц никто не помнит, что именно меняли;
- при повторном запуске автоматизации всё может “поехать”.
Решение — делать изменения повторяемыми (один и тот же запуск даёт один и тот же результат) и безопасными (не затираем файл целиком, если это не нужно).
Ansible — это не «молоток по всему конфигу», а «аккуратная отвёртка: крутим только нужный винтик».
Контекст: когда это применять и где границы
Подход “шаблоны + фильтры + lookups” подходит, когда:
- конфиги уже существуют и их нужно патчить (менять кусочек);
- данные приходят “в разнобой” (строки, списки, словари) и их надо приводить к одному виду;
- секреты/настройки нельзя хранить прямо в репозитории.
Ограничения:
- если файл целиком ваш, проще и чище использовать template;
- если правок становится слишком много и они “расползаются”, лучше перейти на полноценный шаблон.
Шаг за шагом
Шаг 1. Точечные правки конфигов: lineinfile / blockinfile / replace
1) Точечно заменить или добавить строку: lineinfile
Пример: включим параметр в конфиге (если строки нет — добавим).
Что происходит:
- если строка logging=... уже есть — она будет заменена на нужную;
- если строки нет — она добавится;
- если файла нет — создастся.
Важно: это и есть “безопасная повторяемость”: второй запуск ничего не ломает.
2) blockinfile — вставить «кусок» текста как единый блок
Когда нужно добавить несколько строк разом.
Почему это удобно: Ansible помечает блок, и потом может обновить именно его, не трогая остальной файл.
3) replace — точная замена по шаблону
Подходит, когда нужно заменить фрагмент текста «как искать → на что менять».
Типичная ошибка: использовать replace “на всё подряд”.
Если шаблон поиска слишком общий — можно заменить лишнее. Делайте regexp максимально точным.
Мини-итог:
- 1 строка → lineinfile
- блок строк → blockinfile
- аккуратная “найти/заменить” → replace
Шаг 2. «Must-know» фильтры и тесты Jinja2: простая “алгебра” данных
Когда в переменных не одна строка, а список/словарь, фильтры помогают быстро собрать нужный результат.
Допустим, у нас есть сервисы:
Полезные фильтры (на практике)
1) selectattr - выбрать элементы по условию
Получим только включённые сервисы.
2) map - взять одно поле у всех
Получим список имён: ["api", "admin", "web"]
3) unique - убрать повторы
4) difference - “что есть в одном списке, но нет в другом”
Результат: [1,3]
5) ternary - “если… то… иначе…”
6) dict2items и items2dict - преобразовать словарь ↔ список
Это спасает, когда нужно фильтровать/перебирать ключи и значения.
Важно (перевод термина): “фильтр” - это функция для преобразования данных.
Важно: фильтры читаются слева направо:
данные | фильтр1 | фильтр2 | ...
Схема (как конвейер):
Шаг 3. Lookups и query-плагины: тянем данные извне (включая секреты)
Иногда переменных в playbook мало - значение лежит:
- в файле,
- в переменной окружения,
- в ini/конфиге,
- в менеджере секретов/плагинах сообщества.
Пример 1: прочитать переменную окружения
Пример 2: прочитать файл
Пример 3: сгенерировать пароль и использовать
Типичная ошибка: случайно “засветить” секрет в логах.
Для задач с секретами добавляйте no_log: true.
Почему всё это так работает
Ansible старается приводить систему к нужному состоянию, а не «делать действия ради действий».
Поэтому точечные модули проверяют: есть ли уже нужная строка/блок/значение — и только при необходимости меняют файл. Это снижает риск случайно стереть важное и делает результат предсказуемым.
Фильтры Jinja2 нужны, потому что реальная инфраструктура — это данные: списки серверов, параметры сервисов, наборы портов. Фильтры помогают быстро собрать из “сырого” списка именно то, что нужно.
Lookups/query позволяют хранить чувствительные и внешние данные там, где им место (окружение, файлы, хранилища), а в playbook лишь аккуратно их подтягивать.
Что сделали
- Научились править конфиги без полного шаблона, безопасно и повторяемо.
- Разобрали базовые фильтры Jinja2 для работы со списками и словарями.
- Подтянули значения извне через lookups и показали, как не светить секреты.
Сделать прямо сейчас
- Возьмите один конфиг и замените «ручные правки» на lineinfile или blockinfile.
- Добавьте проверку: что будет при повторном запуске (ничего не должно ломаться).
- Вынесите секреты из текста playbook: используйте lookup('env', ...) или lookup('password', ...).
- Для данных в списках попробуйте: selectattr, map, unique.
CTA
Если хотите — продолжу серию “Ansible для руководителя”: как читать playbook, как оценивать риски изменений и как устроить минимальный контроль качества (проверки перед выкладкой).
Подпишитесь и напишите в комментариях: какой конфиг у вас чаще всего «болит» — Nginx, systemd, Docker, базы или что-то ещё?