Роли
Роли позволяют автоматически загружать связанные переменные, файлы, задачи, обработчики и другие артефакты Ansible на основе известной структуры файлов. После группировки содержимого в роли их можно легко повторно использовать и делиться ими с другими пользователями.
- Структура каталога роли
- Хранение и поиск ролей
- Встраивание модулей и плагинов в роли
- Обмен ролями: Ansible Galaxy
Структура каталога роли
Роль Ansible имеет определенную структуру каталога с семью основными стандартными каталогами. Вы должны включить по крайней мере один из этих каталогов в каждой роли. Вы можете опустить любые каталоги, которые роль не использует. Например:
# playbooks
site.yml
webservers.yml
fooservers.yml
roles/
common/
tasks/
handlers/
library/
files/
templates/
vars/
defaults/
meta/
webservers/
tasks/
defaults/
meta/
По умолчанию Ansible будет искать в каждом каталоге внутри роли файл main.yml для соответствующего содержимого (также main.yaml и main)
-
tasks/main.yml— основной список задач, выполняемых ролью. -
handlers/main.yml— обработчики, которые могут использоваться внутри или вне этой роли. -
library/my_module.py— модули, которые могут использоваться внутри этой роли (см. Встраивание модулей и плагинов в роли для получения дополнительной информации). -
defaults/main.yml— переменные по умолчанию для роли (см. Использование переменных для получения дополнительной информации). Эти переменные имеют наименьший приоритет из всех доступных переменных и легко переопределяются любыми другими переменными, включая переменные инвентаризации. -
vars/main.yml— другие переменные для роли (см. Использование переменных для получения дополнительной информации). -
files/main.yml— файлы, которые развёртывает роль. -
templates/main.yml— шаблоны, которые развёртывает роль. -
meta/main.yml— метаданные для роли, включая зависимости роли.
Вы можете добавлять другие файлы YAML в некоторые каталоги. Например, вы можете размещать задачи, специфичные для платформы, в отдельных файлах и ссылаться на них в файле tasks/main.yml:
# roles/example/tasks/main.yml
- name: Install the correct web server for RHEL
import_tasks: redhat.yml
when: ansible_facts['os_family']|lower == 'redhat'
- name: Install the correct web server for Debian
import_tasks: debian.yml
when: ansible_facts['os_family']|lower == 'debian'
# roles/example/tasks/redhat.yml
- name: Install web server
ansible.builtin.yum:
name: "httpd"
state: present
# roles/example/tasks/debian.yml
- name: Install web server
ansible.builtin.apt:
name: "apache2"
state: present
Роли также могут включать модули и другие типы плагинов в каталоге library. Для получения дополнительной информации, пожалуйста, обратитесь к разделу Встраивание модулей и плагинов в роли ниже.
Хранение и поиск ролей
По умолчанию Ansible ищет роли в двух местах:
- в каталоге
roles/, относительно файла книги воспроизведения - в
/etc/ansible/roles
Если вы храните свои роли в другом месте, установите параметр конфигурации roles_path, чтобы Ansible мог найти ваши роли. Размещение общих ролей в одном месте упрощает их использование в нескольких книгах воспроизведения. Подробнее о настройке параметров в ansible.cfg см. в разделе Настройка Ansible.
В качестве альтернативы вы можете вызвать роль с полным путем:
---
- hosts: webservers
roles:
- role: '/path/to/my/roles/common'
Использование ролей
Роли можно использовать тремя способами:
- на уровне воспроизведения с опцией
roles: Это классический способ использования ролей в воспроизведении. - на уровне задач с
include_role: Вы можете динамически повторно использовать роли в любом месте разделаtasksвоспроизведения, используяinclude_role - на уровне задач с
import_role: Вы можете статически повторно использовать роли в любом месте разделаtasksвоспроизведения, используяimport_role
Использование ролей на уровне воспроизведения
Классический (исходный) способ использования ролей — с опцией roles для данного воспроизведения:
---
- hosts: webservers
roles:
- common
- webservers
При использовании опции roles на уровне воспроизведения для каждой роли 'x':
- Если существует roles/x/tasks/main.yml, Ansible добавляет задачи из этого файла в воспроизведение.
- Если существует roles/x/handlers/main.yml, Ansible добавляет обработчики из этого файла в воспроизведение.
- Если существует roles/x/vars/main.yml, Ansible добавляет переменные из этого файла в воспроизведение.
- Если существует roles/x/defaults/main.yml, Ansible добавляет переменные из этого файла в воспроизведение.
- Если существует roles/x/meta/main.yml, Ansible добавляет любые зависимости роли в список ролей.
- Любые задачи копирования, сценариев, шаблонов или включения (в роли) могут ссылаться на файлы в roles/x/{files,templates,tasks}/ (каталог зависит от задачи) без необходимости указания пути относительно или абсолютно.
При использовании опции roles на уровне воспроизведения Ansible обрабатывает роли как статические импорты и обрабатывает их во время разбора книги воспроизведения. Ansible выполняет вашу книгу воспроизведения в таком порядке:
- Любые
pre_tasksопределённые в воспроизведении. - Любые обработчики, запущенные pre_tasks.
- Каждая роль, указанная в
roles:, в указанном порядке. Любые зависимости роли, определённые вmeta/main.ymlроли, выполняются первыми, применительно к фильтрации тегов и условным операторам. Подробнее см. Использование зависимостей роли. - Любые
tasksопределённые в воспроизведении. - Любые обработчики, запущенные ролями или задачами.
- Любые
post_tasksопределённые в воспроизведении. - Любые обработчики, запущенные post_tasks.
Примечание
Если вы используете теги с задачами в роли, убедитесь, что вы также помещаете теги в pre_tasks, post_tasks и зависимости роли и передаёте их, особенно если pre/post-задачи и зависимости роли используются для мониторинга управления окном простоя или балансировки нагрузки. Подробнее см. в разделе Теги по добавлению и использованию тегов.
Вы можете передать другие ключевые слова к опции roles:
---
- hosts: webservers
roles:
- common
- role: foo_app_instance
vars:
dir: '/opt/a'
app_port: 5000
tags: typeA
- role: foo_app_instance
vars:
dir: '/opt/b'
app_port: 5001
tags: typeB
При добавлении тега к опции role, Ansible применяет тег ко ВСЕМ задачам внутри роли.
При использовании vars: в разделе roles: книги воспроизведения переменные добавляются к переменным воспроизведения, делая их доступными для всех задач воспроизведения до и после роли. Это поведение можно изменить с помощью DEFAULT_PRIVATE_ROLE_VARS.
Включение ролей: динамическое повторное использование
Вы можете динамически повторно использовать роли в любом месте раздела tasks воспроизведения, используя include_role. В то время как роли, добавленные в раздел roles, выполняются до любых других задач в книге воспроизведения, включённые роли выполняются в порядке их определения. Если перед задачей include_role есть другие задачи, эти другие задачи будут выполнены первыми.
Для включения роли:
---
- hosts: webservers
tasks:
- name: Print a message
ansible.builtin.debug:
msg: "this task runs before the example role"
- name: Include the example role
include_role:
name: example
- name: Print a message
ansible.builtin.debug:
msg: "this task runs after the example role"
Вы можете передавать другие ключевые слова, включая переменные и теги, при включении ролей:
---
- hosts: webservers
tasks:
- name: Include the foo_app_instance role
include_role:
name: foo_app_instance
vars:
dir: '/opt/a'
app_port: 5000
tags: typeA
...
Когда вы добавляете тег к задаче include_role, Ansible применяет тег only к самому включению. Это означает, что вы можете передать --tags для запуска только выбранных задач из роли, если эти задачи сами имеют тот же тег, что и оператор include. Подробнее см. Выборочное выполнение помеченных задач в повторно используемых файлах.
Вы можете условно включить роль:
---
- hosts: webservers
tasks:
- name: Include the some_role role
include_role:
name: some_role
when: "ansible_facts['os_family'] == 'RedHat'"
Импортирование ролей: статическое повторное использование
Вы можете статически повторно использовать роли в любом месте раздела tasks воспроизведения, используя import_role. Поведение такое же, как при использовании ключевого слова roles. Например:
---
- hosts: webservers
tasks:
- name: Print a message
ansible.builtin.debug:
msg: "before we run our role"
- name: Import the example role
import_role:
name: example
- name: Print a message
ansible.builtin.debug:
msg: "after we ran our role"
Вы можете передавать другие ключевые слова, включая переменные и теги, при импортировании ролей:
---
- hosts: webservers
tasks:
- name: Import the foo_app_instance role
import_role:
name: foo_app_instance
vars:
dir: '/opt/a'
app_port: 5000
...
При добавлении тега к оператору import_role, Ansible применяет тег к all задачам внутри роли. Подробнее см. Наследование тегов: добавление тегов к нескольким задачам.
Проверка аргументов роли
Начиная с версии 2.11, вы можете выбрать включение проверки аргументов роли на основе спецификации аргумента, определённой в файле роли meta/main.yml. При определении этой спецификации аргумента в начале выполнения роли вставляется новая задача, которая будет проверять параметры, предоставленные для роли, по этой спецификации. Если проверка параметров не пройдёт, выполнение роли завершится ошибкой.
Примечание
При использовании проверки аргументов роли для роли, имеющей определённые зависимости, валидация этих зависимостей будет выполнена до выполнения зависимой роли, даже если проверка аргументов для зависимой роли завершится ошибкой.
Формат спецификации
Спецификация аргументов роли должна быть определена в блоке верхнего уровня argument_specs внутри файла роли meta/main.yml. Все поля должны быть в нижнем регистре.
- entry-point-name
-
- Имя точки входа роли.
- Должно быть
mainв случае неопределенной точки входа. - Это будет базовое имя файла задач для выполнения, без расширений
.ymlили.yaml.
- short_description
-
- Краткое, однострочное описание точки входа.
- Описание
short_descriptionотображаетсяansible-doc -t role -l.
- description
-
- Более подробное описание, которое может содержать несколько строк.
- author
-
- Имя авторов точки входа.
- Используйте многострочный список, если авторов более одного.
- options
-
- Параметры часто называют «параметрами» или «аргументами». Этот раздел определяет эти параметры.
- Для каждого параметра роли (аргумента) можно включить:
- option-name
-
- Имя параметра/аргумента.
- description
-
- Подробное объяснение того, что делает этот параметр. Оно должно быть написано полными предложениями.
- type
-
- Тип данных параметра. По умолчанию
str. - Если параметр типа
list, необходимо указатьelements.
- Тип данных параметра. По умолчанию
- required
-
- Требуется только если
true. - Если отсутствует, параметр не обязателен.
- Требуется только если
- default
-
- Если
requiredложно/отсутствует, можно указатьdefault(по умолчанию «null», если отсутствует). - Убедитесь, что значение по умолчанию в документации соответствует значению по умолчанию в коде. Фактическое значение по умолчанию для переменной роли всегда берётся из
defaults/main.yml. - Поле значения по умолчанию не должно быть указано как часть описания, если только не требуется дополнительная информация или условия.
- Если параметр представляет собой булево значение, можно использовать любое из булевых значений, распознаваемых Ansible: (например, true/false или yes/no). Выберите тот вариант, который лучше читается в контексте параметра.
- Если
- choices
-
- Список возможных значений параметра.
- Должен отсутствовать, если список пустой.
- elements
-
- Определяет тип данных для элементов списка, когда тип —
list.
- Определяет тип данных для элементов списка, когда тип —
- suboptions
-
- Если этот параметр принимает словарь или список словарей, вы можете определить его структуру здесь.
Пример спецификации
# roles/myapp/meta/main.yml
---
argument_specs:
# roles/myapp/tasks/main.yml entry point
main:
short_description: The main entry point for the myapp role.
options:
myapp_int:
type: "int"
required: false
default: 42
description: "The integer value, defaulting to 42."
myapp_str:
type: "str"
required: true
description: "The string value"
# roles/maypp/tasks/alternate.yml entry point
alternate:
short_description: The alternate entry point for the myapp role.
options:
myapp_int:
type: "int"
required: false
default: 1024
description: "The integer value, defaulting to 1024."
Запуск роли несколько раз в одном playbook
Ansible выполняет каждую роль только один раз, даже если она определена несколько раз, если параметры роли не отличаются для каждого определения. Например, Ansible выполняет роль foo только один раз в таком play:
---
- hosts: webservers
roles:
- foo
- bar
- foo
У вас есть два варианта, чтобы заставить Ansible запустить роль более одного раза.
Передача различных параметров
Вы можете передавать различные параметры в каждом определении роли следующим образом:
---
- hosts: webservers
roles:
- { role: foo, vars: { message: "first" } }
- { role: foo, vars: { message: "second" } }
или
---
- hosts: webservers
roles:
- role: foo
vars:
message: "first"
- role: foo
vars:
message: "second"
В этом примере, так как каждое определение роли имеет разные параметры, Ansible запускает foo дважды.
Использование allow_duplicates: true
Добавьте allow_duplicates: true в файл meta/main.yml для роли:
# playbook.yml
---
- hosts: webservers
roles:
- foo
- foo
# roles/foo/meta/main.yml
---
allow_duplicates: true
В этом примере Ansible запускает foo дважды, поскольку мы явно разрешили это.
Использование зависимостей ролей
Зависимости ролей позволяют автоматически подключать другие роли при использовании роли. Ansible не выполняет зависимости ролей при включении или импорте роли. Необходимо использовать ключевое слово roles , если вы хотите, чтобы Ansible выполнял зависимости ролей.
Зависимости ролей хранятся в файле 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
Ansible всегда выполняет зависимости ролей перед ролью, которая их включает. Ansible также выполняет рекурсивные зависимости ролей. Если одна роль зависит от второй роли, а вторая роль зависит от третьей, Ansible выполняет третью роль, затем вторую, затем первую.
Запуск зависимостей ролей несколько раз в одном playbook
Ansible обрабатывает дублирующиеся зависимости ролей как дублирующиеся роли, перечисленные в roles:: Ansible выполняет зависимости ролей только один раз, даже если они определены несколько раз, если параметры, теги или условие, определённые для роли, не различаются для каждого определения. Если две роли в playbook содержат третью роль в качестве зависимости, Ansible выполняет эту зависимость только один раз, если вы не передаёте различные параметры, теги, условия или не используете allow_duplicates: true в зависимой (третьей) роли. Подробнее см. Зависимости ролей Galaxy.
Примечание
Дедупликация ролей не учитывает сигнатуру вызова родительских ролей. Кроме того, при использовании vars: вместо параметров роли есть побочный эффект изменения области действия переменных. Использование vars: приводит к тому, что эти переменные имеют область действия на уровне play. В примере ниже, использование vars: приведёт к тому, что n будет определено как 4 на протяжении всего play, включая роли, вызываемые до него.
В дополнение к вышесказанному, пользователи должны знать, что дедупликация ролей происходит до вычисления переменных. Это означает, что Ленивое вычисление может сделать, на первый взгляд, разные вызовы ролей эквивалентными, предотвращая запуск роли более одного раза.
Например, роль с именем 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 с зависимостями ролей, необходимо указать его для зависимой роли, а не для родительской. В приведённом примере allow_duplicates: true появляется в meta/main.yml ролей tire и brake . Роль wheel не требует allow_duplicates: true, потому что каждый экземпляр, определённый car, использует разные значения параметров.
Примечание
См. Использование переменных для получения подробностей о том, как Ansible выбирает между значениями переменных, определёнными в разных местах (наследование и область действия переменных).
Встраивание модулей и плагинов в роли
Если вы создаёте пользовательский модуль (см. Разработка модулей) или плагин (см. Разработка плагинов), вы можете захотеть распространить его как часть роли. Например, если вы создаёте модуль, который помогает настроить внутреннее программное обеспечение вашей компании, и вы хотите, чтобы другие пользователи вашей организации использовали этот модуль, но не хотите рассказывать всем, как настроить путь к вашей библиотеке Ansible, вы можете включить модуль в роль internal_config.
Чтобы добавить модуль или плагин в роль: наряду со структурой «tasks» и «handlers» роли, добавьте каталог с именем «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 могут меняться в основных компонентах, и это решение не гарантировано.
Такой же механизм может быть использован для встраивания и распространения плагинов в роли, используя ту же схему. Например, для плагина фильтра:
roles/
my_custom_filter/
filter_plugins
filter1
filter2
Эти фильтры затем можно использовать в шаблоне Jinja в любой роли, вызываемой после «my_custom_filter».
Распространение ролей: Ansible Galaxy
Ansible Galaxy — бесплатный сайт для поиска, скачивания, оценки и обзора ролей Ansible, созданных сообществом, и может быть отличным способом начать ваши проекты по автоматизации.
Клиент ansible-galaxy включён в Ansible. Клиент Galaxy позволяет загружать роли из Ansible Galaxy и также предоставляет отличную базу для создания собственных ролей.
Подробнее см. страницу документации Ansible Galaxy
END_OF_DOCUMENT_MARKERСм. также
- Руководство пользователя Galaxy
-
Как создавать новые роли, делиться ролями в Galaxy, управление ролями
- Синтаксис YAML
-
Узнайте о синтаксисе YAML
- Работа с playbook
-
Ознакомьтесь с основными функциями языка Playbook
- Советы и рекомендации
-
Советы и рекомендации по playbook
- Использование переменных
-
Переменные в playbook
- Условные операторы
-
Условные операторы в playbook
- Циклы
-
Циклы в playbook
- Теги
-
Использование тегов для выбора или пропуска ролей/задач в длинных playbook
- Индекс коллекций
-
Просмотрите существующие коллекции, модули и плагины
- Нужно ли разрабатывать модуль?
-
Расширение Ansible путем написания собственных модулей
- Примеры Ansible на GitHub
-
Полные файлы playbook из исходного кода проекта GitHub
- Список рассылки
-
Вопросы? Помощь? Идеи? Загляните на список на Google Groups
© 2012–2018 Michael DeHaan
© 2018–2021 Red Hat, Inc.
Licensed under the GNU General Public License version 3.
https://docs.ansible.com/ansible/2.11/user_guide/playbooks_reuse_roles.html