Comments 11
Меж тем, локальные переменные (уровня task) для import_role переопределяют переменные для всей плей.
И это не баг. Это просто WTF, которое надо проглотить и радоваться.
Пример:
inventory:
host1: foo=1
play.yaml
- hosts: host1
tasks:
- debug: var=foo
- import_role: name=somerole
vars:
foo: 2
- import_role: name=somerole
vars:
foo: 3
- debug: var=foo
(Внутри somerole такой же -debug: var=foo
).
Догадайтесь, какие 4 числа будут выведены на экран? (Кандидаты из комбинации чисел 1, 2 и 3).
docs.ansible.com/ansible/latest/user_guide/playbooks_variables.html#variable-precedence-where-should-i-put-a-variable
TASK [debug] *************************************************************************************************************************************************
ok: [localhost] => {
"foo": 1
}
TASK [somerole : debug] **************************************************************************************************************************************
ok: [localhost] => {
"foo": 2
}
TASK [somerole : debug] **************************************************************************************************************************************
ok: [localhost] => {
"foo": 3
}
TASK [debug] *************************************************************************************************************************************************
ok: [localhost] => {
"foo": 1
}
ansible --version
ansible 2.6.2
ansible 2.7.13
TASK [debug] *************************************************************************************************************************************************
ok: [localhost] => {
"foo": 3
}
TASK [somerole : debug] **************************************************************************************************************************************
ok: [localhost] => {
"foo": 2
}
TASK [somerole : debug] **************************************************************************************************************************************
ok: [localhost] => {
"foo": 3
}
TASK [debug] *************************************************************************************************************************************************
ok: [localhost] => {
"foo": 3
}
найс… что они там курят то?
- hosts: host1
tasks:
- debug: var=foo
- include_role: name=somerole
vars:
foo: 2
- include_role: name=somerole
vars:
foo: 3
- debug: var=foo
Дело не в том, как фиксить, а в том, что они сами себе противоречат.
Если vars выставляют переменные для всей плебуки, то почему одна роль получает два, а вторая три? А если она выставляет для "кусочка" (т.е. одно import_role), то почему она тогда затрагивает таски над import_role?
И так у них всегда.
Так это репортить или нет?
Документация говорит, что это фича. Но я эту фичу не понимаю.
Since Ansible 2.7 variables defined in vars and defaults for the role are exposed at playbook parsing time. Due to this, these variables will be accessible to roles and tasks executed before the location of the import_role task.
https://docs.ansible.com/ansible/latest/modules/import_role_module.html
Т.е. если бы она в этом примере всем 3 сделала — я бы вздохнул и понял. (и всё равно приводил бы этот пример как идиотизм), но комбинация 3, 2, 3, 3 — это совершенно нелогично.
Баг или фича?
Потому что сначала при импорте ролей все переменные применяются и в итоге последнее значение записывается.
а потом при проигрывании опять для каждой роли применяются переменные…
и зачем они их применяют Джва раза — вот тут непонятное.
вывод:
в ролях использовать уникальные имена переменных
если надо вызывать одну роль с разным параметром, то при вызове присваивать значение параметра уникальной переменной в роли, которая нигде снаружи роли использоваться не должна.
Не будут они это фиксить, иначе есть риск что у кого-нибудь сломаются плейбуки, отлаженные "с этим" багом.
К сожалению, ансибл похож на php — от рождения сломан во всех местах, и с каждым релизом яма все глубже, и можно только смириться. Выиграет фреймворк, кооторые сумеет заюзать модули ансибл, но будет иметь нормальную архитектуру и язык.
Имхо есть шансы у Salt, особенно если появятся удобные средства модульного и интеграционного тестирования стейтов/формул. Да, есть плагин к kitchen — но это только интеграционное, и с multi-node там все грустно. И есть внутренняя система тестов — но если я правильно понимаю для тестирования своих стейтов их придется положить внутрь сальтовских исходников, что вообще за гранью...
The Inside Playbook. Сетевые функции в новом Ansible Engine 2.9