Ansible: хост появляется в нескольких группах, и в обеих группах одинаковые задачи; любой способ запустить задачи один раз?

9

У меня есть пьеса, которая выглядит примерно так:

---
- hosts: group1
  roles:
    - role1
    - role2

- hosts: group2
  roles:
    - role2
    - role3

Теперь скажите, что у меня есть файл hosts, в котором есть такая запись:

[group1]
host1.example.com

[group2]
host1.example.com

Ansible будет запускать задачи в role2 TWICE для host1.example.com, потому что он отображается в 2 группах, и каждой из них назначена role2.

Как я могу заставить Ansible понять, что в нее включена одна и та же роль дважды, и поэтому он должен запускать ее только один раз?

Асфанд Кази
источник
Было бы лучше привести нам реальные примеры вместо "role1", "role2" и т. Д., Потому что, возможно, вам следует делать это по-другому. Но это зависит от того, чего вы на самом деле пытаетесь достичь.
Антонис Христофидес

Ответы:

10

Как уже упоминалось, это по замыслу. Ansible выполняет только одну игру за раз. Ваша книга воспроизведения состоит из двух пьес (два элемента в списке YAML корневого уровня, определенные файлом playbook). Первая игра применяет role1 и role2 к group1. Эта игра исполняется первой, и только после ее завершения начинается вторая игра. Но Ansible не пытается логически объединить пьесы. В конце концов, вы можете захотеть, чтобы задачи в role2 запускались дважды.

Что касается решения проблемы, есть несколько способов обойти это, и выбор, который вы выберете, будет зависеть от деталей групп и ролей.

Если все задачи в role2 являются идемпотентными, то есть если они могут выполняться несколько раз и каждый раз приводить к одному и тому же результату, то все, что вы действительно теряете, это время, и все в порядке, если роли повторяются. Если для применения ролей требуется очень много времени или если вы не можете сделать их идемпотентными, подумайте над следующими идеями:


Вы можете разделить сборник пьес на три пьесы и применять роли по отдельности:

---
- hosts: group1
  roles:
    - role1

- hosts: group1:group2
  roles:
    - role2

- hosts: group2
  roles:
    - role3

Или, если ваши роли должны быть сгруппированы вместе, вы можете создать третью группу для серверов, которым нужны все три роли. Вам не нужно брать их из двух других групп. Вы можете создать группу в вашем файле инвентаря следующим образом:

[group1and2:children]
group1
group2

Затем в своей пьесе вы снова можете разделиться на три пьесы, но используйте третью группу, чтобы избежать повторного запуска ролей:

---
- hosts: group1:!group1and2
  roles:
    - role1
    - role2

 - hosts: group1and2
   roles:
     - role1
     - role2
     - role3

 - hosts: group2:!group1and2
   roles:
     - role2
     - role3

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

daveadams
источник
Спасибо, я думаю, что я пойду с вариантом (2) - я сделаю свои группы и роли более детальными, чтобы сгруппировать мои серверы вместе.
Асфанд Кази
Если я называю хосты через переменную как {{host1}} и {{host2}}, как я могу собрать их вместе?
BMW
Если вы ищете раздел документации: Общие шаблоны
Sahap Asci
3

Это по замыслу. Единственный способ сделать это - применить role2 только в одной пьесе к одной конкретной группе, а не использовать role2 в любой другой пьесе в группе, в которой могут быть общие члены, как здесь.

Серж ван Гиндерахтер
источник