Роли
- Структура каталога ролей
- Использование ролей
- Дублирование и выполнение ролей
- Переменные по умолчанию для ролей
- Зависимости ролей
- Встраивание модулей и плагинов в роли
- Путь поиска ролей
- 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, previouslly 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, чтобы соответствовать использованию include (динамическое) против import (статическое). См. Динамический против статического для получения дополнительной информации.
Имя, используемое для роли, может быть простым именем (см. Путь поиска ролей ниже), или это может быть полный путь:
---
- hosts: webservers
roles:
- { role: '/path/to/my/roles/common' }
Роли могут принимать параметры:
---
- hosts: webservers
roles:
- common
- { role: foo_app_instance, dir: '/opt/a', app_port: 5000 }
- { role: foo_app_instance, dir: '/opt/b', app_port: 5001 }
Или, используя более новый синтаксис:
---
- hosts: webservers
tasks:
- include_role:
name: foo_app_instance
vars:
dir: '/opt/a'
app_port: 5000
...
Вы можете условно выполнить роль. Это не рекомендуется в классическом синтаксисе, но часто используется при использовании import_role или include_role:
---
- hosts: webservers
tasks:
- include_role:
name: some_role
when: "ansible_os_family == 'RedHat'"
Наконец, вы можете назначить теги ролям, которые вы определяете. Вы можете сделать это в строке:
---
- hosts: webservers
roles:
- { role: foo, tags: ["bar", "baz"] }
Или, снова, используя новый синтаксис:
---
- hosts: webservers
tasks:
- import_role:
name: foo
tags:
- bar
- baz
Примечание
Это помечает все задачи в этой роли указанными тегами, добавляя к любым тегам, которые указаны внутри роли. Теги в этом примере не будут добавлены к задачам внутри include_role. Пометьте задачу include_role напрямую, чтобы применить теги к задачам во включённых ролях. Если вы обнаруживаете, что создаёте роль с множеством тегов, и хотите вызывать подмножества роли в разное время, вы должны рассмотреть возможность разделения этой роли на несколько ролей.
Дублирование и выполнение ролей
Ansible позволит выполнить роль только один раз, даже если она определена несколько раз, если параметры, определённые для роли, не отличаются для каждого определения. Например:
--- - hosts: webservers roles: - foo - foo
Ввиду вышесказанного, роль foo будет выполнена только один раз.
Чтобы выполнить роли более одного раза, есть два варианта:
- Передайте разные параметры в каждом определении роли.
- Добавьте
allow_duplicates: trueв файлmeta/main.ymlдля роли.
Пример 1 — передача разных параметров:
---
- hosts: webservers
roles:
- { role: foo, message: "first" }
- { role: foo, 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, some_parameter: 3 }
- { role: apache, apache_port: 80 }
- { role: postgres, dbname: blarg, other_parameter: 12 }
Примечание
Зависимости ролей должны использовать классический стиль определения роли.
Зависимости ролей всегда выполняются перед ролью, которая их включает, и могут быть рекурсивными. Зависимости также следуют правилам дублирования, указанным выше. Если другая роль также указывает её как зависимость, она не будет запущена повторно в соответствии с теми же правилами, указанными выше.
Примечание
Помните всегда, что при использовании allow_duplicates: true, он должен быть в meta/main.yml зависимой роли, а не родительской.
Например, роль под названием car зависит от роли под названием wheel следующим образом:
---
dependencies:
- { role: wheel, n: 1 }
- { role: wheel, n: 2 }
- { role: wheel, n: 3 }
- { role: wheel, 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.
Вместе со структурой «tasks» и «handlers» роли добавьте директорию с именем «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 будет искать роли следующим образом:
- В директории, относящейся к файлу playbook.
- По умолчанию, в
/etc/ansible/roles
В Ansible 1.4 и более поздних версиях вы можете настроить дополнительный roles_path для поиска ролей. Используйте это, чтобы выкладывать все ваши общие роли в одном месте и легко использовать их в нескольких проектах playbook. Подробнее о настройке в ansible.cfg см. в Файле конфигурации.
Ansible Galaxy
Ansible Galaxy — это бесплатный сайт для поиска, загрузки, оценки и обзора ролей Ansible, разработанных сообществом, и он может быть отличным стартом для ваших проектов автоматизации.
Вы можете зарегистрироваться с помощью социальной аутентификации, а клиент загрузки «ansible-galaxy» включён в Ansible 1.4.2 и более поздние версии.
Дополнительную информацию можно найти на странице «О проекте» на сайте Galaxy.
См. также
- Ansible Galaxy
- Как делиться ролями в galaxy, управление ролями
- Синтаксис YAML
- Узнайте о синтаксисе YAML
- Playbooks
- Обзор основных функций языка Playbook
- Рекомендации по практическим работам
- Различные советы по управлению playbooks в реальной жизни
- Переменные
- Все о переменных в playbooks
- Условные операторы
- Условные операторы в playbooks
- Циклы
- Циклы в playbooks
- О модулях
- Узнайте о доступных модулях
- Разработка модулей
- Узнайте, как расширить Ansible, написав собственные модули
- Примеры Ansible на GitHub
- Полные файлы playbook из исходного кода проекта 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.4/playbooks_reuse_roles.html