Где в Ansible хранить переменные?

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

Ответ

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

Моя типичная структура и логика выбора:

  1. Значения по умолчанию для роли (roles/<role>/defaults/main.yml): Сюда помещаю переменные, которые пользователь роли с высокой вероятностью захочет переопределить (например, версия устанавливаемого ПО, порт по умолчанию). Имеют самый низкий приоритет.

  2. Факты (facts) и переменные инвентаря (inventory): Использую динамические данные о хостах (IP, hostname) или статические переменные, привязанные к конкретным серверам или группам в инвентаре.

  3. Групповые переменные (group_vars/): Основное место для хранения конфигурации, общей для группы хостов (например, group_vars/webservers.yml для настройки Nginx или group_vars/all.yml для глобальных настроек вроде ntp_server).

  4. Переменные хоста (host_vars/): Для уникальных параметров конкретного сервера, которые нельзя вынести в группу (например, host_vars/db-primary.yml с VIP-адресом).

  5. Переменные роли (roles/<role>/vars/main.yml): Использую редко, только для внутренних, фиксированных значений роли, которые не должны переопределяться извне (например, внутренние имена пакетов). Имеют высокий приоритет.

  6. Переменные в плейбуке (vars: в play) или внешние файлы (vars_files:): Применяю, когда логика задачи требует набора переменных, специфичного только для этого плейбука и не относящегося к инвентарю.

  7. Extra Variables (через -e в CLI): Самый высокий приоритет. Использую для одноразовых переопределений, передачи секретов (с осторожностью) или в CI/CD пайплайнах.

Пример структуры проекта:

inventory/
  production/
    hosts.yml
    group_vars/
      all.yml          # ntp_server: "time.google.com"
      webservers.yml   # http_port: 80
    host_vars/
      web01.yml        # server_id: 1
playbooks/
  site.yml
roles/
  nginx/
    defaults/main.yml  # nginx_version: "1.18"
    vars/main.yml      # pkg_name: "nginx"

Ключевое правило: Я стремлюсь к тому, чтобы основная конфигурация инфраструктуры была описана в group_vars/ и host_vars/, что делает ее прозрачной и легко изменяемой без правки самих плейбуков или ролей.