Какая иерархия приоритета переменных в Ansible ролях?

«Какая иерархия приоритета переменных в Ansible ролях?» — вопрос из категории Ansible, который задают на 23% собеседований Devops Инженер. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

В Ansible переменные переопределяются согласно строгой иерархии приоритетов — от наименьшего к наибольшему. Знание этой иерархии критически важно для написания предсказуемых и поддерживаемых ролей и плейбуков.

Иерархия переменных (по возрастанию приоритета):

  1. Роли: defaults (defaults/main.yml) — Наименьший приоритет. Предназначены для задания безопасных значений по умолчанию, которые должны быть легко переопределены.
  2. Инвентарь: переменные группы (group_vars/)
  3. Инвентарь: переменные хоста (host_vars/)
  4. Плейбук: переменные (vars: в play)
  5. Роли: переменные (vars/main.yml) — Более высокий приоритет, чем defaults. Используются для значений, специфичных для данной роли.
  6. Блок: переменные (vars: внутри block:)
  7. Задача: переменные (vars: внутри task)
  8. Включенные переменные (include_vars или vars_files) — Выполняются во время работы плейбука.
  9. Факты (facts), включая set_fact — Динамически установленные факты.
  10. Extra Variables (-e в командной строке) — Наивысший приоритет. Всегда переопределяют всё.

Практический пример из моего опыта: Я создаю роль для настройки Nginx. В defaults/main.yml задаю порт 80, но в group_vars/production.yml переопределяю его на 443 для продакшена, а для конкретного хоста в host_vars/lb01.yml могу задать особые настройки таймаутов.

# defaults/main.yml
nginx_port: 80
nginx_worker_processes: auto

# group_vars/production.yml
nginx_port: 443
nginx_worker_connections: 4096

# playbook.yml
- hosts: webservers
  roles:
    - role: nginx
      vars: # Переменные роли (приоритет 5) переопределяют defaults и inventory vars для этого запуска
        nginx_worker_processes: 8

Чтобы избежать путаницы, я всегда явно документирую ключевые переменные в README.md роли, указывая их назначение и место в иерархии, где их логичнее всего переопределять.