Роли
Роли позволяют автоматически загружать связанные переменные, файлы, задачи, обработчики и другие артефакты Ansible на основе известной структуры файлов. После группировки контента в роли вы можете легко их повторно использовать и делиться ими с другими пользователями.
- Структура каталога роли
- Хранение и поиск ролей
- Встраивание модулей и плагинов в роли
- Распределение ролей: Ansible Galaxy
Структура каталога роли
Роль Ansible имеет определённую структуру каталогов с семью основными стандартными каталогами. Вы должны включить хотя бы один из этих каталогов в каждую роль. Вы можете опустить любые каталоги, которые роль не использует. Например:
# playbooks site.yml webservers.yml fooservers.yml
roles/
common/ # this hierarchy represents a "role"
tasks/ #
main.yml # <-- tasks file can include smaller files if warranted
handlers/ #
main.yml # <-- handlers file
templates/ # <-- files for use with the template resource
ntp.conf.j2 # <------- templates end in .j2
files/ #
bar.txt # <-- files for use with the copy resource
foo.sh # <-- script files for use with the script resource
vars/ #
main.yml # <-- variables associated with this role
defaults/ #
main.yml # <-- default lower priority variables for this role
meta/ #
main.yml # <-- role dependencies
library/ # roles can also include custom modules
module_utils/ # roles can also include custom module_utils
lookup_plugins/ # or other types of plugins, like lookup in this case
webtier/ # same kind of structure as "common" was above, done for the webtier role
monitoring/ # ""
fooapp/ # ""
По умолчанию Ansible будет искать в большинстве каталогов ролей файл main.yml для соответствующего контента (также main.yaml и main):
-
tasks/main.yml- Список задач, которые роль предоставляет для выполнения в выполнении. -
handlers/main.yml- обработчики, которые импортируются в родительское выполнение для использования ролью или другими ролями и задачами в выполнении. -
defaults/main.yml- переменные с очень низким приоритетом, предоставляемые ролью (см. Использование переменных для получения дополнительной информации). Собственные значения по умолчанию роли имеют приоритет над значениями по умолчанию других ролей, но все остальные источники переменных переопределят их. -
vars/main.yml- переменные с высоким приоритетом, предоставляемые ролью выполнению (см. Использование переменных для получения дополнительной информации). -
files/stuff.txt- один или несколько файлов, доступных для роли и её дочерних элементов. -
templates/something.j2- шаблоны для использования в роли или дочерних ролях. -
meta/main.yml- метаданные для роли, включая зависимости роли и необязательные метаданные Galaxy, такие как поддерживаемые платформы. Это требуется для загрузки в Galaxy в качестве отдельной роли, но не для использования роли в вашем выполнении.
Примечание
- Ни один из указанных выше файлов не является обязательным для роли. Например, вы можете предоставить только
files/something.txtилиvars/for_import.yml, и это всё равно будет валидной ролью. - В роли, которые являются самостоятельными, также можно включать пользовательские модули и/или плагины, например,
library/my_module.py, которые могут использоваться в этой роли (см. Встраивание модулей и плагинов в роли для получения дополнительной информации). - «Самостоятельная» роль относится к роли, которая не является частью коллекции, но как отдельный устанавливаемый контент.
- Переменные из
vars/иdefaults/импортируются в область видимости выполнения, если вы не отключите это с помощью параметраpublicвimport_role/include_role.
Вы можете добавить другие файлы YAML в некоторые каталоги, но они по умолчанию не будут использоваться. Их можно включать/импортировать непосредственно или указывать при использовании include_role/import_role. Например, вы можете разместить задачи, специфичные для платформы, в отдельных файлах и сослаться на них в файле 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
Или вызвать эти задачи напрямую при загрузке роли, что обойдёт файлы main.yml:
- name: include apt tasks
include_role:
name: package_manager_bootstrap
tasks_from: apt.yml
when: ansible_facts['os_family'] == 'Debian'
Каталоги defaults и vars также могут содержать вложенные каталоги. Если ваш файл переменных — каталог, Ansible считывает все файлы и каталоги переменных внутри в алфавитном порядке. Если вложенный каталог содержит как файлы переменных, так и каталоги, Ansible считывает каталоги сначала. Ниже приведён пример каталога vars/main:
roles/
common/ # this hierarchy represents a "role"
vars/
main/ # <-- variables associated with this role
first_nested_directory/
first_variables_file.yml
second_nested_directory/
second_variables_file.yml
third_variables_file.yml
Хранение и поиск ролей
По умолчанию Ansible ищет роли в следующих местах:
- в коллекциях, если вы их используете
- в каталоге, названном
roles/, относительно файла книги выполнения - в настроенном roles_path. Путь по умолчанию —
~/.ansible/roles:/usr/share/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. - в качестве зависимости другой роли (см. ключевое слово
dependenciesвmeta/main.ymlна этой же странице).
Использование ролей на уровне исполнения
Классический (исходный) способ использования ролей — с опцией roles для данного исполнения:
---
- hosts: webservers
roles:
- common
- webservers
При использовании опции roles на уровне исполнения каждая роль ‘x’ ищет main.yml (также main.yaml и main) в следующих каталогах:
roles/x/tasks/roles/x/handlers/roles/x/vars/roles/x/defaults/roles/x/meta/- Любые задачи копирования, скриптов, шаблонов или включения (в роли) могут ссылаться на файлы в roles/x/{files,templates,tasks}/ (каталог зависит от задачи), без необходимости указывать путь относительно или абсолютно.
Примечание
vars и defaults также могут соответствовать каталогу с таким же именем, и Ansible обработает все файлы, содержащиеся в этом каталоге. Подробнее см. Структуру каталога роли.
Примечание
Если вы используете include_role/import_role, вы можете указать пользовательское имя файла вместо main. Каталог meta является исключением, так как он не допускает настройки.
При использовании опции 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 применяет тег КО ВСЕМ задачам в роли.
Примечание
До версии ansible-core 2.15, vars: в разделе roles: книги задач добавляются в переменные исполнения, делая их доступными для всех задач в исполнении до и после роли. Это поведение можно изменить с помощью DEFAULT_PRIVATE_ROLE_VARS. В более новых версиях 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 применяет тег только к самому включению. Это означает, что вы можете передать --tags для запуска только выбранных задач из роли, если эти задачи сами имеют тот же тег, что и инструкция включения. Подробности см. в Выборочное выполнение задач с тегами в повторно используемых файлах.
Вы можете условно включить роль:
---
- 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 применяет тег ко всем задачам в роли. Дополнительную информацию см. в Наследование тегов: добавление тегов к нескольким задачам.
Проверка аргументов роли
Начиная с версии 2.11, вы можете включить проверку аргументов роли, основываясь на спецификации аргументов. Эта спецификация определена в файле meta/argument_specs.yml (или с расширением файла .yaml). При определении этой спецификации аргументов в начале выполнения роли вставляется новая задача, которая проверяет параметры роли по этой спецификации. Если параметры не пройдут проверку, выполнение роли будет прервано.
Примечание
Ansible также поддерживает спецификации ролей, определённые в файле роли meta/main.yml. Однако любая роль, которая определяет спецификации в этом файле, не будет работать в версиях ниже 2.11. По этой причине рекомендуется использовать файл meta/argument_specs.yml, чтобы сохранить обратную совместимость.
Примечание
Когда используется проверка аргументов роли для роли, которая имеет определённые зависимости, проверка этих зависимостей будет выполнена до выполнения зависимой роли, даже если проверка аргументов для зависимой роли завершится неудачей.
Примечание
Ansible помечает вставленную задачу проверки аргументов роли тегом всегда. Если роль статически импортирована, эта задача выполняется, если вы не используете флаг --skip-tags.
Формат спецификации
Спецификация аргументов роли должна быть определена в блоке верхнего уровня argument_specs внутри файла роли meta/argument_specs.yml. Все поля должны быть в нижнем регистре.
- entry-point-name:
-
- Название точки входа в роль.
- В случае неопределённой точки входа должно быть
main. - Это будет базовое имя файла задач для выполнения, без расширения
.ymlили.yaml.
- short_description:
-
- Краткое, однострочное описание точки входа. В идеале это фраза, а не предложение.
short_descriptionотображаетсяansible-doc -t role -l.- Это также становится частью заголовка страницы роли в документации.
- Короткое описание должно всегда быть строкой, а не списком, и не должно заканчиваться точкой.
- description:
-
- Более подробное описание, которое может содержать несколько строк.
-
- Это может быть одна строка или список строк. В случае списка строк каждый элемент списка
-
является новым абзацем.
- version_added:
-
- Версия роли, когда точка входа была добавлена.
- Это строка, а не число с плавающей запятой, например,
version_added: '2.1'. - В коллекциях это должна быть версия коллекции, к которой была добавлена точка входа. Например,
version_added: 1.0.0.
- author:
-
- Имя авторов точки входа.
- Это может быть одна строка или список строк. Используйте одну запись списка на автора. Если есть только один автор, используйте строку или список из одного элемента.
- options:
-
- Параметры часто называют «параметрами» или «аргументами». Этот раздел определяет эти параметры.
- Для каждого параметра роли (аргумента) вы можете включить:
- option-name:
-
- Имя параметра/аргумента.
- description:
-
- Подробное объяснение того, что делает этот параметр. Его следует писать полными предложениями.
- Это может быть одна строка или список строк. В случае списка строк каждый элемент списка является новым абзацем.
- version_added:
-
- Необходимо только если этот параметр был добавлен после первоначального выпуска роли/точки входа. Другими словами, он больше, чем поле верхнего уровня
version_added. - Это строка, а не число с плавающей запятой, например,
version_added: '2.1'. - В коллекциях это должна быть версия коллекции, к которой был добавлен параметр. Например,
version_added: 1.0.0.
- Необходимо только если этот параметр был добавлен после первоначального выпуска роли/точки входа. Другими словами, он больше, чем поле верхнего уровня
- type:
-
- Тип данных параметра. См. Спецификация аргумента для допустимых значений для
type. По умолчаниюstr. - Если параметр имеет тип
list, должен быть указанelements.
- Тип данных параметра. См. Спецификация аргумента для допустимых значений для
- required:
-
- Требуется только если
true. - Если отсутствует, параметр не обязателен.
- Требуется только если
- default:
-
- Если
requiredявляетсяfalse/отсутствует, может быть указано значениеdefault(по умолчаниюnullесли отсутствует). - Убедитесь, что значение по умолчанию в документации соответствует значению по умолчанию в коде. Фактическое значение по умолчанию для переменной роли всегда будет взято из значений по умолчанию роли (как определено в Структура каталога роли).
- Поле default не должно быть включено в описание, если не требуется дополнительная информация или условия.
- Если параметр является булевым значением, используйте
true/false, если вы хотите быть совместимым сansible-lint.
- Если
- choices:
-
- Список значений параметра.
- Должен отсутствовать, если пуст.
- elements:
-
- Указывает тип данных для элементов списка, когда тип —
list.
- Указывает тип данных для элементов списка, когда тип —
- options:
-
- Если этот параметр принимает словарь или список словарей, вы можете определить структуру здесь.
Пример спецификации
# roles/myapp/meta/argument_specs.yml
---
argument_specs:
# roles/myapp/tasks/main.yml entry point
main:
short_description: Main entry point for the myapp role
description:
- This is the main entrypoint for the C(myapp) role.
- Here we can describe what this entrypoint does in lengthy words.
- Every new list item is a new paragraph. You can have multiple sentences
per paragraph.
author:
- Daniel Ziegenberg
options:
myapp_int:
type: "int"
required: false
default: 42
description:
- "The integer value, defaulting to 42."
- "This is a second paragraph."
myapp_str:
type: "str"
required: true
description: "The string value"
myapp_list:
type: "list"
elements: "str"
required: true
description: "A list of string values."
version_added: 1.3.0
myapp_list_with_dicts:
type: "list"
elements: "dict"
required: false
default:
- myapp_food_kind: "meat"
myapp_food_boiling_required: true
myapp_food_preparation_time: 60
- myapp_food_kind: "fruits"
myapp_food_preparation_time: 5
description: "A list of dicts with a defined structure and with default a value."
options:
myapp_food_kind:
type: "str"
choices:
- "vegetables"
- "fruits"
- "grains"
- "meat"
required: false
description: "A string value with a limited list of allowed choices."
myapp_food_boiling_required:
type: "bool"
required: false
default: false
description: "Whether the kind of food requires boiling before consumption."
myapp_food_preparation_time:
type: int
required: true
description: "Time to prepare a dish in minutes."
myapp_dict_with_suboptions:
type: "dict"
required: false
default:
myapp_host: "bar.foo"
myapp_exclude_host: true
myapp_path: "/etc/myapp"
description: "A dict with a defined structure and default values."
options:
myapp_host:
type: "str"
choices:
- "foo.bar"
- "bar.foo"
- "ansible.foo.bar"
required: true
description: "A string value with a limited list of allowed choices."
myapp_exclude_host:
type: "bool"
required: true
description: "A boolean value."
myapp_path:
type: "path"
required: true
description: "A path value."
original_name:
type: list
elements: "str"
required: false
description: "An optional list of string values."
# roles/myapp/tasks/alternate.yml entry point
alternate:
short_description: Alternate entry point for the myapp role
description:
- This is the alternate entrypoint for the C(myapp) role.
version_added: 1.2.0
options:
myapp_int:
type: "int"
required: false
default: 1024
description: "The integer value, defaulting to 1024."
Запуск роли несколько раз в одном плейбуке
Ansible выполняет каждую роль только один раз в плейбуке, даже если вы её определяете несколько раз, если параметры, определённые для роли, не отличаются для каждого определения. Например, Ansible выполняет роль foo только один раз в таком плейбуке:
---
- hosts: webservers
roles:
- foo
- bar
- foo
У вас есть два варианта, чтобы заставить Ansible запускать роль более одного раза.
Передача разных параметров
Если вы передаёте разные параметры в каждом определении роли, Ansible запускает роль более одного раза. Предоставление разных значений переменных не то же самое, что передача разных параметров роли. Для этого поведения необходимо использовать ключевое слово roles, так как import_role и include_role не принимают параметры роли.
Этот плейбук запускает роль foo дважды:
---
- hosts: webservers
roles:
- { role: foo, message: "first" }
- { role: foo, message: "second" }
Этот синтаксис также запускает роль foo дважды;
---
- hosts: webservers
roles:
- role: foo
message: "first"
- role: foo
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 загружает все перечисленные роли, выполняет роли, перечисленные в dependencies в первую очередь, а затем выполняет роль, которая их перечисляет. Объект play является родителем всех ролей, включая роли, вызываемые с помощью dependencies списка.
Зависимости ролей хранятся в файле 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 всегда выполняет роли, перечисленные в dependencies перед ролью, которая их перечисляет. Ansible выполняет этот шаблон рекурсивно, когда вы используете ключевое слово roles. Например, если вы перечислите роль foo под roles:, роль foo перечисляет роль bar под dependencies в своём файле meta/main.yml, а роль bar перечисляет роль baz под dependencies в своём файле meta/main.yml, Ansible выполняет baz, затем bar, затем foo.
Выполнение зависимостей ролей несколько раз в одном play
Ansible обрабатывает дублированные зависимости ролей как дублированные роли, перечисленные под roles:: Ansible выполняет зависимости ролей только один раз, даже если они определены несколько раз, если параметры, теги или условие «когда» для роли не отличаются для каждого определения. Если две роли в play перечисляют третью роль в качестве зависимости, 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 для 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 с зависимостями ролей, вы должны указать его для роли, перечисленной под dependencies, а не для роли, которая её перечисляет. В приведенном выше примере allow_duplicates: true появляется в meta/main.yml ролей tire и brake. Роль wheel не требует allow_duplicates: true, так как каждый экземпляр, определенный car, использует разные значения параметров.
Примечание
См. Использование переменных, чтобы узнать, как Ansible выбирает значения переменных, определенных в разных местах (наследование переменных и область видимости). Также дедупликация происходит ТОЛЬКО на уровне play, поэтому несколько play в одном playbook могут повторно запускать роли.
Встраивание модулей и плагинов в роли
Примечание
Это относится только к автономным ролям. Роли в коллекциях не поддерживают встраивание плагинов; они должны использовать структуру plugins коллекции для распространения плагинов.
Если вы пишете пользовательский модуль (см. Разработка модулей) или плагин (см. Разработка плагинов), вы можете захотеть распространить его в составе роли. Например, если вы написали модуль, который помогает настроить внутреннее программное обеспечение вашей компании, и вы хотите, чтобы другие люди в вашей организации использовали этот модуль, но не хотите рассказывать всем, как настроить путь к библиотеке Ansible, вы можете включить модуль в свою роль internal_config.
Чтобы добавить модуль или плагин в роль: наряду со структурой «задачи» и «обработчики» роли добавьте каталог с именем «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».
© 2012–2018 Michael DeHaan
© 2018–2024 Red Hat, Inc.
Licensed under the GNU General Public License version 3.
https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_reuse_roles.html