← Ansible
15 мин · средне · Урок 7 из 12

Роли и структура папок

tasks/handlers/templates/files/vars/defaults/meta, автозагрузка main.yml, ansible-galaxy init, defaults vs vars.

Зачем роли

Один playbook на 50 задач — уже больно читать. На 200 — невозможно. Когда логику нужно переиспользовать в другом проекте, хочется скопировать кусок, а не весь файл.

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

Дерево роли

roles/
  myrole/
    tasks/
      main.yml
    handlers/
      main.yml
    templates/
      nginx.conf.j2
    files/
      index.html
    vars/
      main.yml
    defaults/
      main.yml
    meta/
      main.yml
    tests/           # опционально
      test.yml
    library/         # опционально, кастомные модули

ansible-galaxy init myrole генерирует этот скелет одной командой.

myrole/ корень роли tasks/main.yml точка входа - задачи handlers/main.yml хендлеры (notify) templates/ Jinja2 .j2 - модуль template files/ статика - модуль copy vars/main.yml высокий приоритет defaults/main.yml низкий приоритет meta/main.yml зависимости, Galaxy main.yml - автозагрузка Ansible читает без include_tasks по соглашению (без main.yml)

Что лежит в каждой папке

tasks/main.yml — точка входа роли. Здесь основной список задач. Ansible загружает этот файл автоматически при подключении роли.

handlers/main.yml — хендлеры роли. Вызываются через notify из задач этой роли, срабатывают один раз в конце плея даже если их нотифицировали несколько раз.

templates/ — Jinja2-шаблоны с расширением .j2. Модуль template берёт файлы именно отсюда. Можно подставлять переменные, циклы, условия прямо в конфиг.

files/ — статические файлы без шаблонизации. Модуль copy берёт файлы отсюда. Бинарники, сертификаты, любые файлы, которые не надо рендерить.

vars/main.yml — переменные роли с высоким приоритетом. Их нельзя переопределить через group_vars/host_vars, но -e (extra vars) всё равно побеждает. Используй для внутренних констант роли, которые не должны меняться.

defaults/main.yml — переменные по умолчанию с самым низким приоритетом из всех. Их легко переопределить: через inventory, через group_vars, через -e, через vars: в плее. Это правильное место для всего, что пользователь роли должен иметь возможность настроить.

meta/main.yml — метаданные и зависимости. Поле dependencies здесь позволяет объявить другие роли, которые должны выполниться раньше этой. Также сюда идут поля для Galaxy: автор, лицензия, поддерживаемые ОС.

defaults vs vars — ключевая разница

Это частый вопрос на собеседованиях.

defaults/main.ymlvars/main.yml
ПриоритетСамый низкийВысокий
Переопределяется снаружиЛегкоТрудно
НазначениеНастраиваемые параметрыВнутренние константы

Правило простое: всё, что пользователь роли должен мочь изменить - в defaults. Внутренние константы, которые не должны уплыть — в vars.

Пример: порт приложения — в defaults (разные окружения, разные порты). Имя системного пользователя, которое роль создаёт и на которое опирается в нескольких задачах — в vars.

Автозагрузка

Ansible автоматически читает main.yml из каждой папки при подключении роли. Не нужно прописывать include_tasks: tasks/main.yml или что-то подобное. Создал файл по пути — он заработал.

Из tasks/main.yml можно включать дополнительные файлы:

# tasks/main.yml
- name: install packages
  import_tasks: install.yml

- name: configure service
  import_tasks: configure.yml

Подключение роли в playbook

Блок roles: в плее — основной способ:

- name: Configure web server
  hosts: webservers
  roles:
    - common
    - role: nginx
      vars:
        nginx_port: 8080
    - myrole

Роли из roles: выполняются после pre_tasks и до tasks:/post_tasks (полный порядок в плее: pre_tasks → роли → tasks → post_tasks).

Если нужно вставить роль в середину задач или передать переменные условно, используй include_role или import_role:

- name: Setup app
  hosts: all
  tasks:
    - name: prepare os
      import_tasks: prepare.yml

    - name: apply nginx role
      import_role:
        name: nginx
      vars:
        nginx_port: 443

    - name: post-setup checks
      import_tasks: checks.yml

import_role — статический импорт (разворачивается до запуска, как import_tasks). include_role — динамический (вычисляется во время выполнения, поддерживает when и loop). Нюанс: handlers роли, подключённой через include_role, видны только после её выполнения, тогда как import_role добавляет их сразу.

Где хранить роли

По умолчанию Ansible ищет роли в ./roles/ рядом с playbook и в пути из roles_path в ansible.cfg:

[defaults]
roles_path = ./roles:~/.ansible/roles

Ansible Galaxy — публичный реестр готовых ролей. Установить роль из Galaxy:

ansible-galaxy install geerlingguy.nginx

Роль попадёт в ~/.ansible/roles/ (или в первый путь из roles_path).

Зависимости проекта удобно фиксировать в requirements.yml:

roles:
  - name: geerlingguy.nginx
    version: "3.2.0"
  - name: geerlingguy.postgresql
    version: "3.4.3"

Установить всё сразу:

ansible-galaxy install -r requirements.yml

Что важно запомнить

Роль — это стандартная структура папок. Ansible сам знает, где что искать: задачи в tasks/main.yml, хендлеры в handlers/main.yml, шаблоны в templates/, статика в files/.

defaults/main.yml — переменные с самым низким приоритетом, их переопределяют снаружи. vars/main.yml — высокий приоритет, для внутренних констант роли.

ansible-galaxy init myrole создаёт скелет мгновенно. Не надо создавать папки вручную.

В следующем уроке — переменные, facts и приоритет их применения.

Дрилл · вопросы как на собесе

Проверь себя без подсказок

Сформулируй ответ вслух или письменно, потом раскрой и честно отметь: знал или нет.

01

Что такое роли (roles) и какова стандартная структура каталогов?

ANS-005

Прошли материал до конца? Отметьте урок пройденным.