Переменные Ansible: типы, объявление и приоритет

Рейтинг: 62.1% · 15 голосов
Подробный курс по Ansible с прицелом на экзамен RHCE EX294: установка и инвентарь, плейбуки, переменные и факты, Vault, циклы и условия, шаблоны Jinja2, роли и коллекции, Execution Environments и ansible-navigator, управление системами (диски, LVM, cron, SELinux, firewalld). Примеры на RHEL/Fedora. Актуально на 2026.
Ответить
Аватара пользователя
Maksim_DevOps
Сообщения: 47
Зарегистрирован: 11 май 2026, 05:31

Переменные Ansible: типы, объявление и приоритет

Сообщение Maksim_DevOps »

Оглавление курса (47)
  1. Что такое Ansible и зачем он нужен: автоматизация без агентов
  2. Сертификация RHCE и экзамен EX294: что внутри и как готовиться
  3. Архитектура Ansible: control node, узлы, модули и плагины
  4. Установка Ansible на control node: dnf, pip и версии ansible-core
  5. Подготовка управляемых узлов: SSH, пользователь и sudo
  6. Инвентарь Ansible: hosts, группы и переменные
  7. Настройка Ansible: файл ansible.cfg и приоритеты конфигурации
  8. Host patterns и инструменты командной строки Ansible
  9. Ad hoc команды Ansible: быстрые задачи без плейбука
  10. Ansible playbook: что это такое и как устроен
  11. Структура плейбука: play, task, модули и переменные
  12. Запуск плейбуков: проверка, теги, ограничения и отладка
  13. Параллелизм и порядок выполнения: forks, serial, strategy
  14. Факты Ansible: сбор информации об узлах
  15. Переменные Ansible: типы, объявление и приоритет (вы здесь)
  16. Регистрация результатов и специальные переменные
  17. Ansible Vault: шифрование паролей и секретов
  18. Организация инвентаря: group_vars, host_vars и вложенные группы
  19. Динамический инвентарь и инвентарные плагины
  20. Циклы в Ansible: loop, списки и словари
  21. Повтор задачи до условия: until, retries и delay
  22. Условия в Ansible: директива when и логика
  23. Jinja2 в Ansible: выражения, фильтры и подстановки
  24. Обработчики Ansible: handlers, notify и flush_handlers
  25. Обработка ошибок: failed_when, changed_when и ignore_errors
  26. Блоки в Ansible: block, rescue и always
  27. Управление файлами: модули file, copy, fetch и stat
  28. Архивы и сборка файлов: archive, unarchive, assemble
  29. Точечное редактирование файлов: lineinfile и blockinfile
  30. Шаблоны Jinja2: модуль template и динамические конфиги
  31. Jinja2 продвинуто: фильтры, циклы, макросы и lookup
  32. Модули Ansible: ansible-doc и поиск нужного модуля
  33. Разработка собственного модуля Ansible на Python
  34. Роли Ansible и Ansible Galaxy: переиспользование
  35. Разработка роли Ansible: создание с нуля
  36. Зависимости ролей и requirements.yml
  37. Коллекции Ansible: ansible.posix, community и своя коллекция
  38. Execution Environments: контейнеры для запуска Ansible
  39. Сборка Execution Environment с ansible-builder
  40. ansible-navigator: запуск плейбуков в Execution Environment
  41. Управление SSH-ключами через Ansible: authorized_key
  42. Управление дисками: filesystem, mount и parted
  43. LVM через Ansible: тома, группы и расширение
  44. Планировщик задач: cron и systemd timers через Ansible
  45. Безопасность: hardening SSH и репозитории dnf/yum
  46. SELinux через Ansible: булевы, контексты и порты
  47. Сквозной проект и подготовка к экзамену EX294
Рано или поздно у тебя в плейбуке окажется одна и та же переменная http_port, объявленная в трёх местах сразу: в group_vars, в роли и в командной строке. И сервер вдруг слушает не тот порт, который ты ожидал. Ты лезешь в код, всё перепроверяешь, а значение всё равно "неправильное". Знакомо? Это не баг Ansible. Это приоритет переменных, который ты пока не держишь в голове. На экзамене RHCE (EX294) на этом срезается куча народу: задание выглядит простым, а человек кладёт значение не в тот файл и получает не тот результат.

В этом уроке разберём всё про ansible переменные: какие бывают типы, где их объявлять и, самое важное, кто кого перебивает. Без этой картины ты будешь воевать с собственными плейбуками.

Типы значений: строки, списки, словари

Сами по себе ansible vars - это обычные значения YAML. Три формы, которые ты встретишь повсюду.

Простое (скаляр) - строка, число, булево:

Код: Выделить всё

app_name: nginx
http_port: 8080
enable_ssl: true
Список (массив) - упорядоченный набор:

Код: Выделить всё

packages:
  - httpd
  - mariadb-server
  - php-fpm
Словарь (хеш, маппинг) - пары ключ-значение:

Код: Выделить всё

db:
  host: 127.0.0.1
  port: 3306
  name: shop
Доступ к элементам. К списку - по индексу: packages[0] вернёт httpd. К словарю - по ключу, двумя способами: db.host или db['host']. Привыкай к скобочной форме db['host'] - она работает всегда, а точечная ломается, если ключ совпал с методом Python (например, ключ keys или count). В шаблонах и условиях это пишется в двойных фигурных скобках:

Код: Выделить всё

- name: Показать порт БД
  ansible.builtin.debug:
    msg: "БД слушает {{ db.host }}:{{ db['port'] }}"
Отдельно про кавычки и булевы значения - тут новички спотыкаются. Если значение начинается с {{, YAML считает строку началом словаря и падает. Поэтому такое всегда в кавычки:

Код: Выделить всё

greeting: "{{ user_name }}, привет"
Булево пиши как true/false (нижний регистр, по нормам YAML 1.2). Старые yes/no/on/off Ansible пока понимает, но это устаревает - не плоди разнобой. И помни: "true" в кавычках это строка, а true без кавычек - булево. В условии when: enable_ssl это разные вещи.

Изображение

Где объявлять ansible variables

Мест на удивление много, и каждое со своим смыслом.
  • В плейбуке через vars - локально для конкретной игры.
  • В отдельных файлах через vars_files - выносим длинные наборы.
  • В инвентаре - рядом с хостами и группами.
  • group_vars/ и host_vars/ - файлы для групп и отдельных хостов, самый чистый способ.
  • В ролях - defaults/main.yml (мягкие дефолты) и vars/main.yml (жёсткие).
  • register - результат выполнения задачи.
  • set_fact - вычисленная переменная на лету.
  • extra vars через -e - из командной строки, перебивает всё.
Пример с vars прямо в игре и с register:

Код: Выделить всё

- hosts: web
  vars:
    http_port: 8080
  tasks:
    - name: Проверить, открыт ли порт
      ansible.builtin.command: ss -ltn sport = :{{ http_port }}
      register: port_check
      changed_when: false

    - name: Запомнить факт на основе вывода
      ansible.builtin.set_fact:
        port_is_open: "{{ port_check.rc == 0 }}"
group_vars - это каталог рядом с плейбуком или инвентарём. Файл group_vars/web.yml применится ко всем хостам группы web, а group_vars/all.yml - вообще ко всем. Аналогично host_vars/server1.yml - только для одного хоста. Никаких vars в самом инвентаре руками вписывать не надо, это считается грязным стилем.

В роли defaults/main.yml - это значения "по умолчанию, легко переопределяемые". Туда кладут всё, что пользователь роли захочет настроить. А vars/main.yml - жёсткие константы роли, которые перебить намного сложнее. Разница между ними принципиальна, и она прямо вытекает из таблицы приоритета.

Приоритет переменных ansible - таблица, на которой срезаются

Вот сердце урока. Когда одно и то же имя объявлено в нескольких местах, Ansible выбирает значение по строгому порядку. Приоритет переменных ansible идёт от самого слабого к самому сильному:
  • 1. значения командной строки (-u, -c и т.п., НЕ -e)
  • 2. role defaults (defaults/main.yml)
  • 3. inventory file / script group vars
  • 4. inventory group_vars/all
  • 5. playbook group_vars/all
  • 6. inventory group_vars/*
  • 7. playbook group_vars/*
  • 8. inventory file / script host vars
  • 9. inventory host_vars/*
  • 10. playbook host_vars/*
  • 11. host facts и кешированные set_facts
  • 12. play vars
  • 13. play vars_prompt
  • 14. play vars_files
  • 15. role vars (vars/main.yml)
  • 16. block vars
  • 17. task vars
  • 18. include_vars
  • 19. set_fact / registered vars
  • 20. role (и include_role) params
  • 21. include params
  • 22. ansible extra vars (-e) - всегда побеждает
Запомни три якоря, и 90 процентов путаницы уйдёт.
role defaults - самый слабый. set_fact и register - очень сильные. ansible extra vars (-e) бьёт абсолютно всё.
Отсюда практические выводы. Дефолты роли (defaults) лежат почти на дне - их легко перекрыть из group_vars или play vars, и это правильно: роль задаёт разумное значение, а пользователь его подстраивает. А вот role vars (vars/main.yml) сидят высоко - их перебьёт только set_fact, include_vars, параметры роли и extra vars. Поэтому в defaults кладём настраиваемое, в vars - то, что менять не должны.

Проверим на живом примере. Объявим http_port разом в defaults роли и через -e:

Код: Выделить всё

# roles/web/defaults/main.yml
http_port: 80

Код: Выделить всё

ansible-playbook site.yml -e "http_port=9090"
Победит 9090. Хоть в defaults стоит 80, хоть в group_vars пропишут 8080 - extra vars сильнее всего. Это и удобно (быстрый разовый прогон), и опасно: забытый -e в истории команд потом долго ищут.

Типичные грабли
  • Переопределяю в group_vars, а работает старое значение. Скорее всего, то же имя сидит в play vars или vars_files - они выше по таблице. Или висит set_fact из прошлой задачи.
  • Два файла group_vars/all - в инвентаре и рядом с плейбуком. Playbook group_vars сильнее inventory group_vars (строки 4 и 5). Люди про второй файл забывают.
  • YAML падает на значении с {{. Оборачивай в кавычки: key: "{{ value }}".
  • when: var ведёт себя странно. Проверь, строка у тебя "false" или булево false. Строка "false" в условии истинна, потому что непустая.
  • Точечный доступ db.name возвращает не то. Если ключ называется как метод Python, бери db['name'].
  • Дефис в имени: my-var. Так нельзя. В именах переменных только буквы, цифры и подчёркивание, и начинаться с буквы. Naming - снейк_кейс: app_user, db_port.
Маленькая ремарка по дистрибутивам: всё выше не зависит от ОС, приоритет одинаков и на RHEL/Fedora с dnf, и на Ubuntu/Debian с apt, и на RED OS или Astra. Меняются лишь значения внутри переменных - имена пакетов, пути, сервисы systemd.

Мини-лаба: пощупать приоритет руками

Десять минут практики дадут больше, чем чтение таблицы.
  • Создай роль: ansible-galaxy init roles/demo. В roles/demo/defaults/main.yml впиши greeting: "из defaults".
  • Сделай group_vars/all.yml с тем же greeting: "из group_vars". Запусти плейбук с ansible.builtin.debug: msg="{{ greeting }}". Какое значение? Должно быть из group_vars.
  • Добавь vars: { greeting: "из play vars" } в саму игру. Перезапусти. Теперь play vars победили.
  • Запусти с -e 'greeting="из extra"'. Угадай результат до запуска, потом проверь. extra vars забирают всё.
  • Добавь задачу set_fact: greeting="из факта" перед debug и убери -e. Посмотри, как факт перебивает play vars.
  • Прогони ansible-inventory --list -y и ansible -m debug -a "var=greeting" all, чтобы увидеть, откуда хост берёт значение.
Цель - не запомнить 22 строки наизусть, а почувствовать движение значения снизу вверх по таблице.

Контрольные вопросы
  • Что перебьёт значение из roles/web/defaults/main.yml: group_vars, play vars или extra vars? А что НЕ перебьёт его?
  • Чем role defaults отличается от role vars и почему одно кладут в defaults, а другое в vars?
  • Как обратиться к ключу словаря, если он называется count, и почему точечная форма тут опасна?
  • Где в таблице приоритета стоят set_fact и register относительно play vars?
Итог

Переменные в Ansible - это просто строки, списки и словари, но вся боль не в них, а в том, где они объявлены. Запомни направление: defaults роли внизу, extra vars наверху, set_fact и register - высоко. Когда значение "не то", не лезь сразу в код - открой таблицу приоритета и пройди её сверху вниз, ища, кто перебил. На RHCE это сэкономит тебе и нервы, и баллы.
👍7 ❤️4 🔥 😄 🤔1
Аватара пользователя
torchadmin
Сообщения: 2
Зарегистрирован: 22 май 2026, 08:30

Re: Переменные Ansible: типы, объявление и приоритет

Сообщение torchadmin »

Спасибо, наконец дошло почему мой -e постоянно ломал прогоны на стейдже. Сидел и не понимал откуда 9090 берётся, а это была забытая extra var в истории bash.
👍1 ❤️ 🔥 😄 🤔
Аватара пользователя
hotmike3
Сообщения: 1
Зарегистрирован: 14 май 2026, 00:43

Re: Переменные Ansible: типы, объявление и приоритет

Сообщение hotmike3 »

А вопрос: если одна переменная и в inventory group_vars/all и в playbook group_vars/all - точно победит та что рядом с плейбуком? Всегда думал что инвентарь главнее, оказывается наоборот.
👍 ❤️ 🔥 😄 🤔
Ответить
← Предыдущая глава
Факты Ansible: сбор информации об узлах
Следующая глава →
Регистрация результатов и специальные переменные

Все главы курса «Ansible: автоматизация и подготовка к RHCE (EX294)»

Поделиться темой: ✈ Telegram VK
Похожие запросы: что такое ansible простыми словамиansible для начинающих с чего начатьустановка ansible на linuxansible inventory и hosts файлчто такое playbook в ansibleструктура ansible playbook из чего состоит

Вернуться в «Ansible: автоматизация и подготовка к RHCE (EX294)»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 1 гость