Роли
- Структура каталога ролей
- Использование ролей
- Дублирование и выполнение ролей
- Переменные по умолчанию для ролей
- Зависимости ролей
- Встраивание модулей и плагинов в роли
- Путь поиска ролей
- Ansible Galaxy
Новое в версии 1.2.
Роли — это способ автоматической загрузки определённых файлов переменных, задач и обработчиков на основе известной структуры файлов. Группировка контента по ролям также позволяет легко обмениваться ролями с другими пользователями.
Структура каталога ролей
Пример структуры проекта:
site.yml
webservers.yml
fooservers.yml
roles/
common/
tasks/
handlers/
files/
templates/
vars/
defaults/
meta/
webservers/
tasks/
defaults/
meta/
Роли ожидают, что файлы будут находиться в определённых именах каталогов. Роли должны включать как минимум один из этих каталогов, однако допускается исключение тех, которые не используются. При использовании каждый каталог должен содержать файл main.yml, который содержит соответствующий контент:
-
tasks— содержит основной список задач, которые должны быть выполнены ролью. -
handlers— содержит обработчики, которые могут использоваться этой ролью или даже где-либо за пределами этой роли. -
defaults— переменные по умолчанию для роли (подробнее см. Использование переменных). -
vars— другие переменные для роли (подробнее см. Использование переменных). -
files— содержит файлы, которые могут быть развернуты посредством этой роли. -
templates— содержит шаблоны, которые могут быть развернуты посредством этой роли. -
meta— определяет некоторые метаданные для этой роли. Подробнее см. ниже.
В определённых каталогах могут быть включены другие файлы YAML. Например, обычной практикой является включение задач, специфичных для платформы, из файла tasks/main.yml:
# roles/example/tasks/main.yml
- name: added in 2.4, previously you used 'include'
import_tasks: redhat.yml
when: ansible_facts['os_family']|lower == 'redhat'
- import_tasks: debian.yml
when: ansible_facts['os_family']|lower == 'debian'
# roles/example/tasks/redhat.yml
- yum:
name: "httpd"
state: present
# roles/example/tasks/debian.yml
- apt:
name: "apache2"
state: present
Роли также могут включать модули и другие типы плагинов. Дополнительную информацию см. в разделе Встраивание модулей и плагинов в роли ниже.
Использование ролей
Классический (оригинальный) способ использования ролей — через параметр roles: для заданного плейбука:
---
- hosts: webservers
roles:
- common
- webservers
Это задаёт следующее поведение для каждой роли ‘x’:
- Если roles/x/tasks/main.yml существует, задачи, перечисленные в нём, будут добавлены в плейбук.
- Если roles/x/handlers/main.yml существует, обработчики, перечисленные в нём, будут добавлены в плейбук.
- Если roles/x/vars/main.yml существует, переменные, перечисленные в нём, будут добавлены в плейбук.
- Если roles/x/defaults/main.yml существует, переменные, перечисленные в нём, будут добавлены в плейбук.
- Если roles/x/meta/main.yml существует, любые зависимости ролей, перечисленные в нём, будут добавлены в список ролей (1.3 и более поздние версии).
- Любые задачи копирования, скриптов, шаблонов или включения (в роли) могут ссылаться на файлы в roles/x/{files,templates,tasks}/ (каталог зависит от задачи) без необходимости указывать пути относительно или абсолютно.
При использовании таким образом, порядок выполнения вашего плейбука следующий:
- Любые
pre_tasksзаданные в плейбуке. - Любые обработчики, запущенные до этого момента, будут выполнены.
- Каждая роль, указанная в
roles, будет выполнена по очереди. Любые зависимости ролей, определённые в ролиmeta/main.yml, будут выполнены первыми, в зависимости от фильтрации тегов и условных операторов. - Любые
tasksзаданные в плейбуке. - Любые обработчики, запущенные до этого момента, будут выполнены.
- Любые
post_tasksзаданные в плейбуке. - Любые обработчики, запущенные до этого момента, будут выполнены.
Примечание
См. ниже дополнительную информацию о зависимостях ролей.
Примечание
Если вы используете теги с задачами (описанные позже как способ выполнения только части плейбука), убедитесь, что вы также отметили свои задачи pre_tasks, post_tasks и зависимости ролей и передали их, особенно если pre/post задачи и зависимости ролей используются для мониторинга окна простоев или балансировки нагрузки.
Начиная с Ansible 2.4, вы можете использовать роли непосредственно со всеми другими задачами, используя import_role или include_role:
---
- hosts: webservers
tasks:
- debug:
msg: "before we run our role"
- import_role:
name: example
- include_role:
name: example
- debug:
msg: "after we ran our role"
Когда роли определены классическим способом, они рассматриваются как статические импорты и обрабатываются во время анализа плейбука.
Примечание
Параметр include_role был введён в Ansible 2.3. Использование немного изменилось с Ansible 2.4, чтобы соответствовать использованию включения (динамический) против импорта (статический). Подробнее см. Динамический против статического.
Имя, используемое для роли, может быть простым именем (см. Путь поиска ролей ниже), или полным путём:
---
- hosts: webservers
roles:
- role: '/path/to/my/roles/common'
Роли могут принимать другие ключевые слова:
---
- hosts: webservers
roles:
- common
- role: foo_app_instance
vars:
dir: '/opt/a'
app_port: 5000
- role: foo_app_instance
vars:
dir: '/opt/b'
app_port: 5001
Или, используя новый синтаксис:
---
- hosts: webservers
tasks:
- include_role:
name: foo_app_instance
vars:
dir: '/opt/a'
app_port: 5000
...
Вы можете условно импортировать роль и выполнить её задачи:
---
- hosts: webservers
tasks:
- include_role:
name: some_role
when: "ansible_facts['os_family'] == 'RedHat'"
Наконец, вы можете назначить теги задачам внутри указанных вами ролей. Вы можете сделать это так:
---
- hosts: webservers
roles:
- role: foo
tags:
- bar
- baz
# using YAML shorthand, this is equivalent to the above:
- { role: foo, tags: ["bar", "baz"] }
Или, ещё раз, используя новый синтаксис:
---
- hosts: webservers
tasks:
- import_role:
name: foo
tags:
- bar
- baz
Примечание
Это добавляет все задачи в этой роли к указанным тегам, добавляя к любым тегам, которые указаны внутри роли.
С другой стороны, вы можете просто добавить теги к самому импорту роли:
---
- hosts: webservers
tasks:
- include_role:
name: bar
tags:
- foo
Примечание
Теги в этом примере не будут добавлены к задачам внутри include_role, вы можете использовать директиву block для выполнения обоих действий.
Примечание
Нет возможности импортировать роль, одновременно указывая подмножество тегов для выполнения. Если вы создаёте роль с большим количеством тегов и хотите вызывать подмножества роли в разное время, следует рассмотреть возможность разделения этой роли на несколько ролей.
Дублирование и выполнение ролей
Ansible позволит выполнить роль только один раз, даже если она определена несколько раз, если параметры, заданные для роли, не отличаются для каждого определения. Например:
---
- hosts: webservers
roles:
- foo
- foo
Учитывая вышесказанное, роль foo будет выполнена только один раз.
Чтобы запустить роли более одного раза, есть два варианта:
- Передавайте разные параметры в каждом определении роли.
- Добавьте
allow_duplicates: trueв файлmeta/main.ymlдля роли.
Пример 1 — передача различных параметров:
---
- hosts: webservers
roles:
- role: foo
vars:
message: "first"
- { role: foo, vars: { message: "second" } }
В этом примере, поскольку каждое определение роли имеет разные параметры, foo будет выполнено дважды.
Пример 2 — использование allow_duplicates: true:
# playbook.yml
---
- hosts: webservers
roles:
- foo
- foo
# roles/foo/meta/main.yml
---
allow_duplicates: true
В этом примере foo будет выполнено дважды, потому что мы явно разрешили это сделать.
Переменные по умолчанию для ролей
Новое в версии 1.3.
Переменные по умолчанию для ролей позволяют задавать переменные по умолчанию для включённых или зависимых ролей (см. ниже). Для создания значений по умолчанию просто добавьте файл defaults/main.yml в свой каталог роли. Эти переменные будут иметь наименьший приоритет из всех доступных переменных и легко переопределяются любыми другими переменными, включая переменные инвентаризации.
Зависимости ролей
Новое в версии 1.3.
Зависимости ролей позволяют автоматически подключать другие роли при использовании роли. Зависимости ролей хранятся в файле meta/main.yml в каталоге роли, как указано выше. Этот файл должен содержать список ролей и параметров для вставки перед указанной ролью, например, следующее в примере roles/myapp/meta/main.yml:
---
dependencies:
- role: common
vars:
some_parameter: 3
- role: apache
vars:
apache_port: 80
- role: postgres
vars:
dbname: blarg
other_parameter: 12
Примечание
Зависимости ролей должны использовать классический стиль определения роли.
Зависимости ролей всегда выполняются перед ролью, которая их включает, и могут быть рекурсивными. Зависимости также следуют правилам дублирования, указанным выше. Если другая роль также указывает её в качестве зависимости, она не будет выполняться повторно, основываясь на тех же правилах, указанных выше. Подробнее см. Зависимости ролей Galaxy.
Примечание
Всегда помните, что при использовании allow_duplicates: true, он должен быть в meta/main.yml зависимой роли, а не родительской.
Например, роль с именем car зависит от роли с именем wheel следующим образом:
---
dependencies:
- role: wheel
vars:
n: 1
- role: wheel
vars:
n: 2
- role: wheel
vars:
n: 3
- role: wheel
vars:
n: 4
И роль wheel зависит от двух ролей: tire и brake. Файл meta/main.yml для wheel будет содержать следующее:
--- dependencies: - role: tire - role: brake
И файлы meta/main.yml для tire и brake будут содержать следующее:
--- allow_duplicates: true
Результирующий порядок выполнения будет следующим:
tire(n=1) brake(n=1) wheel(n=1) tire(n=2) brake(n=2) wheel(n=2) ... car
Обратите внимание, что нам не нужно было использовать allow_duplicates: true для wheel, потому что каждый экземпляр, определённый car, использует разные значения параметров.
Примечание
Наследование переменных и область действия подробно описаны в Использование переменных.
Встраивание модулей и плагинов в роли
Это продвинутая тема, которая не должна быть актуальна для большинства пользователей.
Если вы пишете пользовательский модуль (см. Разработка модулей?) или плагин (см. Разработка плагинов), вы можете захотеть распространить его в качестве части роли. В целом, проект Ansible очень заинтересован в интеграции высококачественных модулей в ядро Ansible, поэтому это не должно быть нормой, но это довольно легко сделать.
Хороший пример — если вы работаете в компании под названием AcmeWidgets и написали внутренний модуль, который помогает настроить ваше внутреннее программное обеспечение, и вы хотите, чтобы другие люди в вашей организации легко использовали этот модуль, но не хотите рассказывать всем, как настроить путь к вашей библиотеке Ansible.
В дополнение к структуре «задачи» и «обработчики» роли добавьте каталог с именем «library». В этом каталоге «library» разместите модуль непосредственно внутри него.
Предполагая, что у вас есть это:
roles/
my_custom_modules/
library/
module1
module2
Модуль будет доступен в самой роли, а также во всех ролях, которые вызываются после этой роли, следующим образом:
---
- hosts: webservers
roles:
- my_custom_modules
- some_other_role_using_my_custom_modules
- yet_another_role_using_my_custom_modules
Это также можно использовать, с некоторыми ограничениями, для изменения модулей в базовом распространении Ansible, например, для использования тестовых версий модулей до их выпуска в производственных релизах. Это не всегда рекомендуется, так как сигнатуры API могут изменяться в основных компонентах, и это не всегда гарантирует работу. Однако это может быть удобным способом внедрения исправления для основного модуля, если у вас есть веские причины для этого. Естественно, проект предпочитает, чтобы contributions направлялись обратно в github всякий раз, когда это возможно, через pull request.
Такой же механизм можно использовать для встраивания и распространения плагинов в роли, используя ту же схему. Например, для плагина фильтра:
roles/
my_custom_filter/
filter_plugins
filter1
filter2
Затем их можно использовать в шаблоне или шаблоне Jinja в любой роли, которая вызывается после «my_custom_filter»
Путь поиска ролей
Ansible будет искать роли следующим образом:
- В каталоге
roles/, относительно файла книги задач. - По умолчанию, в
/etc/ansible/roles
В Ansible 1.4 и более поздних версиях вы можете настроить дополнительный roles_path для поиска ролей. Используйте его, чтобы разместить все ваши общие роли в одном месте и легко делиться ими между несколькими проектами с книгами задач. Подробности о настройке этого параметра в файле ansible.cfg см. в разделе Настройка Ansible.
Ansible Galaxy
Ansible Galaxy — это бесплатный сайт для поиска, скачивания, оценки и обзора ролей Ansible, разработанных сообществом, и может быть отличным способом быстрого начала работы с автоматизацией.
Клиент ansible-galaxy включен в Ansible. Клиент Galaxy позволяет скачивать роли из Ansible Galaxy и также предоставляет отличную базу для создания собственных ролей.
Дополнительную информацию см. на странице документации Ansible Galaxy.
См. также
- Руководство пользователя Galaxy
- Как создавать новые роли, делиться ролями в Galaxy, управление ролями
- Синтаксис YAML
- Изучите синтаксис YAML
- Работа с Playbook
- Обзор основных функций языка Playbook
- Рекомендации по практическому применению
- Различные советы по управлению книгами задач в реальном мире
- Использование переменных
- Все о переменных в книгах задач
- Условные операторы
- Условные операторы в книгах задач
- Циклы
- Циклы в книгах задач
- Все модули
- Узнайте о доступных модулях
- Нужно ли разрабатывать модуль?
- Узнайте, как расширить Ansible, написав свои собственные модули
- Примеры Ansible на GitHub
- Полные файлы playbooks из исходного кода проекта GitHub
- Список рассылки
- Вопросы? Помощь? Идеи? Обратитесь к списку на Google Groups
© 2012–2018 Michael DeHaan
© 2018–2019 Red Hat, Inc.
Licensed under the GNU General Public License version 3.
https://docs.ansible.com/ansible/2.9/user_guide/playbooks_reuse_roles.html