Найти в Дзене
Infra as Code по-русски

Ansible.cfg: как использовать ansible-config init и не сломать проект

Аннотация. Ansible.cfg — центральный файл настроек Ansible. В статье разберём, зачем он нужен, где хранить его в реальных проектах, как сгенерировать рабочий конфиг через ansible-config init и какие параметры действительно помогают джунам и продовой команде. Отдельно покажем, какие настройки в ansible.cfg могут быть опасны и как избежать скрытых рисков. 📦 Исходники: весь код и примеры из этой и следующих статей — в репозитории — 🐙 GitHub: https://github.com/IaC-in-Russian/infra-as-code-ru ansible.cfg отвечает за поведение Ansible по умолчанию: Без него вы постоянно дописываете флаги руками.
С ним — проект ведёт себя одинаково у всех: у джуна, мидла, в CI. Ansible всегда ищет подходящий конфиг в строгом порядке и использует первый найденный: У нас по серии статей: ansible.cfg лежит в корне репозитория рядом с: Так мы явно говорим: «Запускаешь из корня — получаешь правильные пути и поведение». Важно. Если вы случайно запускаете Ansible из другого каталога, он может подхватить чужой ans
Оглавление

Аннотация. Ansible.cfg — центральный файл настроек Ansible. В статье разберём, зачем он нужен, где хранить его в реальных проектах, как сгенерировать рабочий конфиг через ansible-config init и какие параметры действительно помогают джунам и продовой команде. Отдельно покажем, какие настройки в ansible.cfg могут быть опасны и как избежать скрытых рисков.

📦 Исходники: весь код и примеры из этой и следующих статей — в репозитории — 🐙 GitHub: https://github.com/IaC-in-Russian/infra-as-code-ru

Для чего нужен ansible.cfg

ansible.cfg отвечает за поведение Ansible по умолчанию:

  • откуда брать inventory;
  • где лежат роли, плагины, коллекции;
  • как подключаться по SSH;
  • как выводить результат (формат, diff, логи);
  • что делать по умолчанию (forks, сбор фактов, поведение hash’ей, Vault и т.п.).

Без него вы постоянно дописываете флаги руками.
С ним — проект ведёт себя одинаково у всех: у джуна, мидла, в CI.

Где может лежать ansible.cfg (и где он лежит у нас)

Ansible всегда ищет подходящий конфиг в строгом порядке и использует первый найденный:

  1. Путь из переменной окружения ANSIBLE_CONFIG.
  2. ansible.cfg в текущей директории.
  3. ~/.ansible.cfg в домашнем каталоге пользователя.
  4. /etc/ansible/ansible.cfg.

У нас по серии статей: ansible.cfg лежит в корне репозитория рядом с:

  • inventories/
  • playbooks/
  • roles/
  • и прочим проектным добром.

Так мы явно говорим: «Запускаешь из корня — получаешь правильные пути и поведение».

Важно. Если вы случайно запускаете Ansible из другого каталога, он может подхватить чужой ansible.cfg или системный. Симптомы: «вчера работало, сегодня Ansible не видит inventory».

ansible-config init: быстрый способ родить ansible.cfg

Вместо того чтобы писать конфиг с нуля, используем встроенный инструмент.

Базовый шаблон

ansible-config init --disabled > ansible.cfg

Что делает:

  • создаётся файл ansible.cfg;
  • все параметры закомментированы (#), то есть Ansible продолжает жить на дефолтах;
  • вы точечно раскомментируете то, что хотите поменять.

Хороший вариант для проектов и обучения: видно, какие значения вы меняли, а какие — нет.

Шаблон с полным каталогом опций

ansible-config init --disabled -t all > ansible.cfg

Что это:

  • генерирует максимально полный список опций, включая плагины;
  • тоже всё закомментировано;
  • файл получается большим и тяжёлым.

Использовать удобно как справочник, но не тащить целиком в рабочий репозиторий:
джуна можно просто утопить в 500+ строках опций, которые ему не нужны.

Безопасность: ansible.cfg тоже может ломать жизнь

ansible.cfg — это не «невинный конфиг». Через него можно:

  • подменить library, callback_plugins, filter_plugins → можно незаметно подсунуть свой код;
  • выключить host_key_checking и радостно подключаться к поддельным хостам;
  • прописать vault_password_file, который лежит в репо → все видят пароль от Vault;
  • включить log_path, и в логах могут оказаться токены, пароли, содержимое шаблонов.

Риски и правила:

  1. Не коммитим чувствительное:
    никакого vault_password_file с реальным путём;
    никаких приватных ключей, путей до них, временных хаков.
  2. Проверяем ansible.cfg при ревью кода.
    Он влияет на всё поведение проекта, как requirements.txt или Dockerfile.
  3. Не доверяем чужим репам.
    Клонировали проект → перед запуском смотрим ansible.cfg, особенно пути к плагинам.
  4. Host key checking.
    host_key_checking = False удобно в тестах, но в проде это окно для MITM.

Относительные пути: почему всё ломается при смене директории

Ключевой момент, который стабильно ломает джунам голову:

Относительные пути считаются от директории, где лежит ansible.cfg.

Наш пример:

[defaults]
inventory = inventories
roles_path = ../galaxy-roles:../galaxy:./roles
collections_path = ../collections
library = ../collections/

Если ansible.cfg в корне:

  • inventories → ./inventories
  • ./roles → роли текущего проекта
  • ../galaxy-roles и ../collections → общие ресурсы вне репозитория

Если перенести ansible.cfg или запускать Ansible не из корня правильного проекта — пути поедут.

Типичная ошибка:
«У меня нет ролей / инвентори», хотя всё лежит на месте → ansible.cfg смотрит не туда.

Разбираем рабочий ansible.cfg по пунктам

[defaults]

[defaults]
inventory = inventories
inventory_plugins = inventory_plugins
forks = 20
interpreter_python = /usr/bin/python3
retry_files_enabled = False
gathering = smart
roles_path = ../galaxy-roles:../galaxy:./roles
library = ../collections/
collections_path = ../collections
ansible_managed = Ansible managed: {file} modified on %Y-%m-%d %H:%M:%S by {uid}
max_diff_size = 1048576

Коротко:

  • inventory — путь(и) к inventory по умолчанию.
  • inventory_plugins — если используете свои плагины инвентори.
  • forks = 20 — сколько хостов обрабатываем параллельно.
  • interpreter_python — фиксируем, какой Python использовать.
  • retry_files_enabled = False — Ansible не создаёт служебные *.retry-файлы при ошибках и не засоряет каталог проекта. Если что-то упало, мы сами решаем, какие хосты перезапускать (через --limit или повторный запуск плейбука).
  • gathering = smart — собираем факты оптимально.
  • roles_path / collections_path / library — где искать роли, коллекции, модули.
  • ansible_managed — автоматическая пометка в сгенерированных файл
    ах.

[ssh_connection]

[ssh_connection]
pipelining = True
transfer_method = piped
ssh_args = -o ControlMaster=auto -o ControlPersist=15m
timeout = 30

Коротко:

  • pipelining = True — меньше SSH-вызовов → быстрее.
  • transfer_method = piped — удобная передача без лишних временных файлов.
  • ssh_args — переиспользуем соединения.
  • timeout — ждать соединения не вечно.

[diff]

[diff]
diff_always = true

Всегда видно, что поменяли. Полезно, когда меняем конфиги.

[inventory]

[inventory]
ignore_patterns = templates

Не воспринимать шаблоны как inventory.

Параметры, которые часто добавляют в реальных проектах

Полный список огромный (официально см. https://docs.ansible.com/ansible/latest/reference_appendices/config.html). Мы возьмём только те, что реально встречаются.

[defaults]
remote_user = ansible # юзер по умолчанию
timeout = 30 # общий таймаут операций
log_path = ./ansible.log # лог в файле (осторожно с секретами)
stdout_callback = yaml # человекочитаемый вывод
bin_ansible_callbacks = True # включать callback'и даже без TTY
deprecation_warnings = True # не прятать важные предупреждения
force_color = True # цветной вывод в CI/tty
callbacks_enabled = profile_tasks # видеть, какие таски самые медленные
fact_caching = jsonfile
fact_caching_connection = ./.facts_cache
fact_caching_timeout = 86400

Зачем:

  • remote_user — меньше -u в командах.
  • stdout_callback = yaml — вывод проще читать джуну.
  • profile_tasks — помогает найти «тормозные» задачи.
  • fact_caching — ускоряет повторные запуски.
  • log_path — удобно для CI/отладки (но следим за секретами).

Пять параметров, которые решают реальные кейсы

Давай выделим 5 «звёзд», которые реально помогают.

1. stdout_callback = yaml + bin_ansible_callbacks = True

Кейс: джун смотрит на стандартный output и ничего не понимает.

[defaults]
stdout_callback = yaml
bin_ansible_callbacks = True

Что даёт:

  • вывод в более читаемом YAML-стиле;
  • все callback-плагины (включая profile_tasks) показывают свои сообщения стабильно.

2. callbacks_enabled = profile_tasks

Кейс: «Playbook тормозит, но непонятно где».

[defaults]
callbacks_enabled = profile_tasks

Плагин profile_tasks показывает, сколько каждая задача выполнялась.

Зачем: быстро находим узкие места: медленные шаблоны, тяжелые shell-скрипты, лишние gather facts.

3. fact_caching = jsonfile

Кейс: большой инвентори, каждый запуск 30–60 секунд собираем факты.

Что делаем:

[defaults]
fact_caching = jsonfile
fact_caching_connection = ./.facts_cache
fact_caching_timeout = 86400

Эффект: при повторных запусках Ansible берёт факты из кэша → быстрее, меньше нагрузки.

Подводный камень: на сильно меняющихся хостах не забываем про таймаут кэша.

4. strategy = free

Кейс: один медленный хост блокирует всех.

[defaults]
strategy = free

Что делает: хосты выполняют таски независимо; медленные не держат быстрых.

Когда полезно: в CI, в массовых обновлениях, когда важна скорость.

Подводный камень: лог становится менее «ровным», джуну сложнее следить пошагово.

5. any_errors_fatal = True

Кейс: инфраструктура критичная, нельзя, чтобы половина хостов обновилась, а половина нет.

[defaults]
any_errors_fatal = True

Что делает: при серьёзной ошибке на части хостов — валим весь запуск.

Идеально для: CI/CD, изменений, которые не должны применяться частично.

Почему это работает

Логика простая:

  • У Ansible есть три источника правды: командная строка, переменные окружения и ansible.cfg.
  • ansible.cfg — стабильный слой, который:
    выравнивает поведение между разработчиками и CI,
    фиксирует пути и стратегии,
    снижает количество «магии» в командах.
  • Когда конфиг лежит в корне проекта и живёт под ревью:
    проще онбордить джунов;
    меньше случайных различий «у меня так не работает»;
    все изменения явные и видны в git.

Что сделали

  • Объяснили, зачем нужен ansible.cfg и как он влияет на поведение Ansible.
  • Показали порядок поиска конфига и зафиксировали, что используем файл в корне проекта.
  • Разобрали ansible-config init в двух вариантах и когда какой использовать.
  • Прошлись по рабочему примеру ansible.cfg и добавили набор реально полезных опций.
  • Обсудили риски (Vault, плагины, host_key_checking) и показали 5 опций, которые решают живые кейсы.

Сделать прямо сейчас

  1. В корне своего проекта создай (или открой текущий) ansible.cfg.
  2. Сгенерируй базовый шаблон: ansible-config init --disabled > ansible.cfg
  3. Аккуратно раскомментируй:
    inventory,
    roles_path / collections_path,
    SSH-настройки,
    stdout_callback = yaml,
    разумное значение forks.
  4. Убедись, что:
    vault_password_file не лежит в репозитории,
    host_key_checking = False не используется в проде.
  5. Включи callbacks_enabled = profile_tasks, запусти любой playbook и посмотри, где тратится время.

CTA:
Продолжаем серию по Ansible. В следующем материале разберём первый hosts.yml и базовый ansible-playbook с практическими примерами. Пиши в комментариях, какие пункты в ansible.cfg вызывают вопросы — разберём на живых кейсах, без снобизма и магии.