Относится к Как сделать так, чтобы доступная роль не запускалась несколько раз, если она указана как зависимость?
Это длинный пост / вопрос. TL; DR - как правильно настроить теги для ролей и задач, чтобы зависимости работали правильно без многократного запуска ролей.
У меня возникли проблемы с тем, чтобы игровые книги хорошо работали с тегами и зависимостями. В общем, я хочу, чтобы сценарий с кучей ролей (каждая со своим набором зависимостей) «работал чисто». Сам по себе это довольно легко настроить, и он хорошо работает при использовании всех ролей во всей книге. Роли с зависимостями могут быть определены в любом порядке в playbook, и эти зависимости гарантируют, что они выполняются в правильном порядке. Конечно, роли без зависимостей будут выполняться в том порядке, в котором они указаны в разделе ролей playbook.
Но бывают случаи, когда кто-то хочет просто запустить подмножество ролей, а затем оно разваливается, и некоторые роли запускаются несколько раз и в странном порядке.
Итак, я построил тестовую установку с 4 ролями (А Б В Г) и учебник с несколькими используемыми методами тегов. Фактически, это 4 роли с голыми непомеченными задачами и 4 роли с помеченными задачами ... плюс роль с именем «z» без задач, просто зависимость для всех остальных ролей. Они выглядят так:
Role name Dependencies
---------- ------------
a_tagged none
b_tagged a_tagged
c_tagged b_tagged
d_tagged c_tagged b_tagged a_tagged
z_tagged a_tagged b_tagged c_tagged d_tagged
a_untagged none
b_untagged a_untagged
c_untagged b_untagged
d_untagged c_untagged b_untagged a_untagged
z_untagged a_untagged b_untagged c_untagged d_untagged
Я знаю, что это выглядит громоздко, но мы пытаемся протестировать в основном 4 комбинации:
Role config Tasks config
----------- ------------
Role IS tagged Tasks are NOT tagged
Role IS tagged Tasks ARE tagged
Role is NOT tagged Tasks are NOT tagged
Role is NOT tagged Tasks ARE tagged
Каждая роль задачи / main.yml выглядит так - в этом примере роль "b_tagged"есть только одна задача, и эта задача помечена"теги: b"
./roles/b_tagged/tasks/main.yml
---
- debug: msg="Role B tagged"
tags: b
и связанные мета / main.yml вот так, так роль b_tagged зависит от роли a_tagged :
./roles/b_tagged/meta/main.yml
---
dependencies:
- { role: a_tagged }
Соответствующие b_untagged задачи стиля идентичны, но без символа "теги:строка в задаче.
Желаемый результат - выполнение ролей в порядке А Б В Г и каждый запускается только один раз, например:
"msg": "Role A ..."
"msg": "Role B ..."
"msg": "Role C ..."
"msg": "Role D ..."
Чтобы обеспечить минимальный вывод, показывающий только сообщение отладки: вывод, сценарий "test.sh"просто запускает ansible-playbook следующим образом. Где бы вы ни увидели test.sh он просто выполняет эту команду.
ANSIBLE_STDOUT_CALLBACK=minimal ansible-playbook -i hosts test.yml $@ -- | egrep -v "{|}"
Есть 4 основных сценария проведения спектаклей ...
Выполняйте каждую роль в каждой игре, стандартное типичное использование ./test.sh
Выполняйте каждую роль в каждой игре, используя тег «z» для выбора каждой роли / задачи. Помните, что роль 'z' просто имеет все остальные роли как зависимости. ./test.sh --tags 'z'
Запускайте каждую игру только для ролей / задач с тегом 'c', это должно запускать только роли А Б В ./test.sh --tags 'c'
Запускайте каждую игру только для ролей / задач с тегами 'b' и 'c', это должно запускать только роли А Б В ./test.sh --tags 'b,c'
Каждая игра в файле playbook test.yml имеет такую форму: (это 1-й)
./test.yml
###########################################################################################
# roles with NO tags and tasks WITH tags, roles defined in reverse order from dependencies.
- hosts: localhost
gather_facts: false
become: no
pre_tasks:
- debug:
msg: "=============== untagged roles z d c b a tagged tasks reverse ========"
tags: always
roles:
- role: z_tagged
- role: d_tagged
- role: c_tagged
- role: b_tagged
- role: a_tagged
###########################################################################################
Поскольку для каждого сценария меняются только определения ролей (и сообщение: строка), это все, что указано здесь для других пьес в test.yml файл playbook
* roles with NO tags and tasks with NO tags, roles defined in reverse order from dependencies
- role: z_untagged
- role: d_untagged
- role: c_untagged
- role: b_untagged
- role: a_untagged
* roles WITH tags and tasks WITH tags, roles defined in correct order from dependencies
- { role: a_tagged, tags: a }
- { role: b_tagged, tags: b }
- { role: c_tagged, tags: c }
- { role: d_tagged, tags: d }
- { role: z_tagged, tags: z }
* roles WITH tags and tasks WITH tags, roles defined in reverse order from dependencies
- { role: z_tagged, tags: z }
- { role: d_tagged, tags: d }
- { role: c_tagged, tags: c }
- { role: b_tagged, tags: b }
- { role: a_tagged, tags: a }
* roles WITH tags and tasks with NO tags, roles defined in correct order from dependencies
- { role: a_untagged, tags: a }
- { role: b_untagged, tags: b }
- { role: c_untagged, tags: c }
- { role: d_untagged, tags: d }
- { role: z_untagged, tags: z }
* roles WITH tags and tasks with NO tags, roles defined in reverse order from dependencies
- { role: z_untagged, tags: z }
- { role: d_untagged, tags: d }
- { role: c_untagged, tags: c }
- { role: b_untagged, tags: b }
- { role: a_untagged, tags: a }
Выполнение 4 приведенных выше сценариев дает следующий результат.
./test.sh
Независимо от того, помечены ли отдельные задачи тегами или нет (если у ролей нет тегов), результат будет правильным (первые две игры). Если роли ДЕЛАТЬ имеют теги, то роли запускаются несколько раз (как показано в следующих 4 пьесах), порядок зависит от порядка, в котором они определены в пьесе.
Правильный пример - role: a_tagged
или - role: a_untagged
порядок ролей не имеет значения
"msg": "=============== untagged roles z d c b a tagged tasks reverse ========"
"msg": "Role A tagged"
"msg": "Role B tagged"
"msg": "Role C tagged"
"msg": "Role D tagged"
"msg": "=============== untagged roles z d c b a untagged tasks reverse ======"
"msg": "Role A untagged"
"msg": "Role B untagged"
"msg": "Role C untagged"
"msg": "Role D untagged"
"msg": "=============== tagged roles a b c d z tagged tasks =================="
"msg": "Role A tagged"
"msg": "Role A tagged"
"msg": "Role B tagged"
"msg": "Role B tagged"
"msg": "Role C tagged"
"msg": "Role C tagged"
"msg": "Role D tagged"
"msg": "Role D tagged"
"msg": "=============== tagged roles z d c b a tagged tasks reverse =========="
"msg": "Role A tagged"
"msg": "Role B tagged"
"msg": "Role C tagged"
"msg": "Role D tagged"
"msg": "Role D tagged"
"msg": "Role C tagged"
"msg": "Role B tagged"
"msg": "Role A tagged"
"msg": "=============== tagged roles a b c d z untagged tasks ================"
"msg": "Role A untagged"
"msg": "Role A untagged"
"msg": "Role B untagged"
"msg": "Role B untagged"
"msg": "Role C untagged"
"msg": "Role C untagged"
"msg": "Role D untagged"
"msg": "Role D untagged"
"msg": "=============== tagged roles z d c b a untagged tasks reverse ========"
"msg": "Role A untagged"
"msg": "Role B untagged"
"msg": "Role C untagged"
"msg": "Role D untagged"
"msg": "Role D untagged"
"msg": "Role C untagged"
"msg": "Role B untagged"
"msg": "Role A untagged"
./test.sh --tags 'z'
При использовании 'z' тег для выбора всех ролей / задач, только пьесы с ролями теги: по их определению дал правильный вывод. Если роль не была помечена, задачи в этой роли никогда не выполняются, несмотря на от того, помечены они или нет.
Правильный пример - { role: a_tagged, tags: a }
или - { role: a_untagged, tags: a }
порядок ролей не имеет значения
"msg": "=============== untagged roles z d c b a tagged tasks reverse ========"
"msg": "=============== untagged roles z d c b a untagged tasks reverse ======"
"msg": "=============== tagged roles a b c d z tagged tasks =================="
"msg": "Role A tagged"
"msg": "Role B tagged"
"msg": "Role C tagged"
"msg": "Role D tagged"
"msg": "=============== tagged roles z d c b a tagged tasks reverse =========="
"msg": "Role A tagged"
"msg": "Role B tagged"
"msg": "Role C tagged"
"msg": "Role D tagged"
"msg": "=============== tagged roles a b c d z untagged tasks ================"
"msg": "Role A untagged"
"msg": "Role B untagged"
"msg": "Role C untagged"
"msg": "Role D untagged"
"msg": "=============== tagged roles z d c b a untagged tasks reverse ========"
"msg": "Role A untagged"
"msg": "Role B untagged"
"msg": "Role C untagged"
"msg": "Role D untagged"
./test.sh --tags 'c'
При запуске только выбранной роли (и ее зависимостей) единственным правильным выходом было наличие тегов ролей и задач. НЕ отмечен (последние две пьесы).
Правильный пример - { role: a_untagged, tags: a }
порядок ролей не имеет значения
"msg": "=============== untagged roles z d c b a tagged tasks reverse ========"
"msg": "Role C tagged"
"msg": "=============== untagged roles z d c b a untagged tasks reverse ======"
"msg": "=============== tagged roles a b c d z tagged tasks =================="
"msg": "Role A tagged"
"msg": "Role B tagged"
"msg": "Role C tagged"
"msg": "Role C tagged"
"msg": "=============== tagged roles z d c b a tagged tasks reverse =========="
"msg": "Role C tagged"
"msg": "Role A tagged"
"msg": "Role B tagged"
"msg": "Role C tagged"
"msg": "=============== tagged roles a b c d z untagged tasks ================"
"msg": "Role A untagged"
"msg": "Role B untagged"
"msg": "Role C untagged"
"msg": "=============== tagged roles z d c b a untagged tasks reverse ========"
"msg": "Role A untagged"
"msg": "Role B untagged"
"msg": "Role C untagged"
./test.sh --tags 'b,c'
Выполняя только две выбранные роли (и их зависимости), были Нет правильные выходы.
НОТА: НИКТО конфигураций дают требуемый результат выполнения только ролей "А Б В"
"msg": "=============== untagged roles z d c b a tagged tasks reverse ========"
"msg": "Role B tagged"
"msg": "Role C tagged"
"msg": "=============== untagged roles z d c b a untagged tasks reverse ======"
"msg": "=============== tagged roles a b c d z tagged tasks =================="
"msg": "Role A tagged"
"msg": "Role B tagged"
"msg": "Role B tagged"
"msg": "Role C tagged"
"msg": "Role C tagged"
"msg": "=============== tagged roles z d c b a tagged tasks reverse =========="
"msg": "Role B tagged"
"msg": "Role C tagged"
"msg": "Role A tagged"
"msg": "Role C tagged"
"msg": "Role B tagged"
"msg": "=============== tagged roles a b c d z untagged tasks ================"
"msg": "Role A untagged"
"msg": "Role B untagged"
"msg": "Role B untagged"
"msg": "Role C untagged"
"msg": "=============== tagged roles z d c b a untagged tasks reverse ========"
"msg": "Role A untagged"
"msg": "Role B untagged"
"msg": "Role C untagged"
"msg": "Role B untagged"
Заключение ... только способ иметь возможность обрабатывать два сценария с зависимостями (запускать всю книгу (все роли) или запускать только подмножество ролей) заключается в том, чтобы гарантировать, что теги, используемые для выбора, ТОЛЬКО в определении роли и НЕ на самих задачах. Такие как :
- { role: a_untagged, tags: a }
Любые теги на задачах должны быть только для задач, НЕ для выбора любой роли. Тем не менее, это работает только при выборе одной роли / тега через - теги 'c' для запуска и не удается с кратными через - теги 'b, c' как показывает последний пример.
в test.yml playbook, это последние две игры (порядок ролей не имеет значения). Все остальные варианты не дают правильных результатов. Кажется, что нет причин иметь теги: на самих задачах, по крайней мере, если вы хотите, чтобы выбор роли / задачи работал с зависимостями, а не с несколькими выполнениями.
У меня нет точного ответа, но «хватит держать Ansible как марионетку» ;-)
Я могу представить себе потребность в таких зависимостях, но вы также можете подумать о следующем: могу ли я управлять зависимостями самостоятельно?
Я испытал почти то же самое: сценарий, в котором загружаются роли logstash
и tomcat
. Обоим нужна роль java
. Наша Java-роль также имела мета-зависимость. Итак, роль java
будет выполняться дважды при развертывании хоста (а также в зависимости от нашей java-роли).
---
- hosts: myhost
roles:
- role: logstash
- role: tomcat8
Мы решили это следующим образом:
---
- hosts: myhost
roles:
- role: java
- role: logstash
- role: tomcat8
Удалить зависимость роли java
из ролей logstash
и tomcat
. Таким образом, Java запускается только один раз за запуск playbook.
Это решение может оказаться полезным, если вы знаете и управляете своими инструментами самостоятельно и хотите, чтобы они были простыми, а не сложными.