Роли
- Структура каталога ролей
- Использование ролей
- Дублирование и выполнение ролей
- Переменные по умолчанию для ролей
- Зависимости ролей
- Встраивание модулей и плагинов в роли
- Путь поиска ролей
- Ansible Galaxy
Новое в версии 1.2.
Роли — это способы автоматической загрузки определенных файлов vars_files, задач и обработчиков на основе известной структуры файлов. Группировка содержимого по ролям также позволяет легко делиться ролями с другими пользователями.
Структура каталога ролей
Пример структуры проекта:
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_os_platform|lower == 'redhat'
- import_tasks: debian.yml
when: ansible_os_platform|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_os_family == 'RedHat'"
Наконец, вы можете назначить теги задачам внутри указанных ролей. Вы можете сделать это:
---
- hosts: webservers
roles:
- role: bar
tags: ["foo"]
# 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
Примечание
Зависимости ролей должны использовать классический стиль определения роли.
Зависимости ролей всегда выполняются перед ролью, которая их включает, и могут быть рекурсивными. Зависимости также следуют правилам дублирования, указанным выше. Если другая роль также указывает её в качестве зависимости, она не будет выполняться снова на основе тех же правил, что и выше.
Примечание
Помните, что при использовании 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 для колес будет содержать следующее:
--- 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 могут измениться в основных компонентах, и это не всегда гарантирует работу. Тем не менее, это может быть полезным способом внедрения исправления в основной модуль, если у вас есть веская причина для этого. Естественно, проект предпочитает, чтобы вносить свои изменения в 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 для поиска ролей. Используйте его, чтобы выкладывать все свои общие роли в одно место и легко делиться ими между несколькими проектами playbooks. Подробности о настройке этого в файле ansible.cfg см. в разделе Настройка Ansible.
Ansible Galaxy
Ansible Galaxy — это бесплатный сайт для поиска, скачивания, оценки и обзора ролей Ansible, разработанных сообществом, и может быть отличным способом начать свои проекты автоматизации.
Клиент ansible-galaxy включен в Ansible. Клиент Galaxy позволяет загружать роли из Ansible Galaxy и также предоставляет отличную базу для создания собственных ролей.
Дополнительную информацию см. на странице документации Ansible Galaxy https://galaxy.ansible.com/docs/
См. также
- Ansible Galaxy
- Как создать новые роли, поделиться ролями в Galaxy, управление ролями
- Синтаксис YAML
- Узнайте о синтаксисе YAML
- Работа с playbooks
- Обзор основных возможностей языка Playbook
- Рекомендации по разработке
- Различные советы по управлению playbooks в реальных условиях
- Переменные
- Все о переменных в playbooks
- Условные операторы
- Условные операторы в playbooks
- Циклы
- Циклы в playbooks
- Все модули
- Узнайте о доступных модулях
- Разработка модулей
- Узнайте, как расширить 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.6/user_guide/playbooks_reuse_roles.html