Короткий ответ
Зависимость оформляется в файле roles/webserver/meta/main.yml в секции dependencies, где указывается роль common (при необходимости с параметрами); Ansible автоматически выполнит зависимые роли перед основной, так что порядок гарантирован даже если кто-то в будущем подключит webserver в плейбуке без явного упоминания common, в отличие от простого перечисления ролей в roles:, которое легко случайно нарушить при рефакторинге плейбука.
Как это работает подробнее
при выполнении плейбука Ansible разворачивает список ролей в плоский список задач, и для каждой роли с объявленными dependencies сначала подставляет задачи зависимых ролей (в порядке их перечисления, с дедупликацией по умолчанию, если роль уже была выполнена с теми же параметрами); это обрабатывается до начала основного прогона плейбука, то есть зависимости выполняются раньше, а не «по требованию» посреди задач.
Пример кода
# roles/webserver/meta/main.yml
dependencies:
- role: common
vars:
timezone: "Europe/Moscow"
$ ansible-playbook -i inventory site.yml
PLAY [all] *************************************************
TASK [common : Set timezone] *******************************
changed: [web01]
TASK [webserver : Install nginx] ***************************
changed: [web01]Что использовать на практике
- Практика. зависимости в
meta/main.ymlудобны для ролей, которые переиспользуются в нескольких плейбуках и командах (в том числе подключаемых черезansible-galaxyиз общего каталога), потому что гарантируют инвариант независимо от того, кто и как вызывает роль; для более сложных случаев (например, нужно передать разные параметры зависимости в разных плейбуках) иногда предпочитают явныеinclude_role/import_roleс параметрами вместоmeta-зависимостей, чтобы логика была нагляднее.
Подводные камни
- Ошибка. частая ошибка — продублировать логику
commonвнутриwebserver, вместо того чтобы объявить зависимость, из-за чего при изменении базовой настройки нужно помнить про несколько мест; другая ошибка — не учитывать, что по умолчанию Ansible выполняет зависимую роль только один раз за прогон (если не указаноallow_duplicates: trueв еёmeta), и неожиданно получить пропущенное повторное применение при намеренной необходимости выполнить роль с другими параметрами.