Короткий ответ
gather_facts: true (по умолчанию) заставляет Ansible перед выполнением задач подключиться к каждому хосту и собрать факты через модуль setup (информация об ОС, сети, дисках и т.п.), что при сотнях хостов создаёт заметную задержку на каждый прогон; ускорить повторные запуски можно включив fact caching (например, backend jsonfile или redis в ansible.cfg) с разумным fact_caching_timeout, либо собирая факты один раз в отдельном playbook и переиспользуя кэш в последующих прогонах, не опрашивая все хосты заново при каждом плейбуке.
Как это работает подробнее
модуль setup выполняется на каждом целевом хосте при первом обращении к play, если gather_facts не выключен, и результат живёт в памяти текущего процесса ansible-playbook; при включённом fact caching Ansible дополнительно сохраняет собранные факты во внешнее хранилище (файл/Redis/Memcached) с TTL, и при следующих запусках (если TTL не истёк) не переопрашивает хост заново, а берёт факты из кэша, экономя время на сетевое подключение и выполнение модуля setup.
Пример кода
# ansible.cfg
[defaults]
gathering = smart
fact_caching = jsonfile
fact_caching_connection = /tmp/ansible_facts_cache
fact_caching_timeout = 3600
forks = 50
- hosts: all
gather_facts: false
tasks:
- name: Deploy config without needing OS facts
ansible.builtin.copy:
src: app.conf
dest: /etc/app/app.confЧто использовать на практике
- Практика. для больших инвентарей стоит явно выставлять
gather_facts: falseтам, где факты не нужны (например, playbook только вызывает один модуль без условий по ОС), и включатьgather_facts: trueтолько там, где это необходимо; также полезно увеличиватьforksвansible.cfgдля параллельного сбора фактов и использоватьgather_subsetдля сбора только нужных категорий фактов (например,!hardware,!facter), если полный набор не требуется.
Подводные камни
- Ошибка. частая ошибка — держать fact caching включённым с большим TTL (например, сутки) для динамической инфраструктуры, из-за чего playbook принимает решения (например, по IP-адресу) на основе устаревших фактов после пересоздания инстанса; другая ошибка — выключать
gather_factsглобально без проверки, что никакая задача ниже по плейбуку не зависит отansible_facts, из-за чего задачи сwhen: ansible_facts['os_family'] == ...молча не выполняются, потому что факт пуст.