Назад | Перейти на главную страницу

Ansible - правильный метод обработки ролей, задач, зависимостей?

Ansible - правильный метод обработки ролей, задач, зависимостей?

Относится к Как сделать так, чтобы доступная роль не запускалась несколько раз, если она указана как зависимость?

Это длинный пост / вопрос. TL; DR - как правильно настроить теги для ролей и задач, чтобы зависимости работали правильно без многократного запуска ролей.

Видеть Ansible-test-deps для настройки playbook, чтобы проиллюстрировать проблемы.

У меня возникли проблемы с тем, чтобы игровые книги хорошо работали с тегами и зависимостями. В общем, я хочу, чтобы сценарий с кучей ролей (каждая со своим набором зависимостей) «работал чисто». Сам по себе это довольно легко настроить, и он хорошо работает при использовании всех ролей во всей книге. Роли с зависимостями могут быть определены в любом порядке в 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 основных сценария проведения спектаклей ...

Каждая игра в файле 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.

Это решение может оказаться полезным, если вы знаете и управляете своими инструментами самостоятельно и хотите, чтобы они были простыми, а не сложными.