Q: "Тот факт, что, очевидно, все остальные могут использовать переменные без проблем, я более склонен полагать, что есть некоторая фундаментальная концепция, которую я пропустил по пути."
A: К сожалению, не так. Очень вероятно, что это проблема Ansible. Есть десяток проблем с включением и импортом . Некоторые из них напоминают о проблеме, описанной здесь
Мне удалось воспроизвести отчетный результат , Игра
- hosts: localhost
roles:
- role_1a
- role_1b
дает
"msg": "role_1a v1 = role_1a default"
"msg": "role_2 v1 = role_1a default"
"msg": "role_3 v1 = role_1a default"
"msg": "role_4 v1 = role_1b default"
"msg": "role_5 v1 = role_1b default"
"msg": "role_1b v1 = role_1b default"
"msg": "role_2 v1 = role_1b default"
"msg": "role_3 v1 = role_1a default"
"msg": "role_4 v1 = role_1b default"
"msg": "role_5 v1 = role_1b default"
Давайте удостоверимся, что порядок сообщений правильный. Измененные задачи (аналогично role_1a, 2,3,4)
# roles/role_1b/tasks/main.yml
- debug: msg="role_1b v1 = {{ v1 }}"
- import_role:
name: role_2
vars:
root: "role_1b"
# roles/role_5/tasks/main.yml
- debug: msg="root = {{ root }} | role_5 v1 = {{ v1 }}"
дают
"msg": "role_1a v1 = role_1a default"
"msg": "root = role_1a | role_2 v1 = role_1a default"
"msg": "root = role_1a | role_3 v1 = role_1a default"
"msg": "root = role_1a | role_4 v1 = role_1b default"
"msg": "root = role_1a | role_5 v1 = role_1b default"
"msg": "role_1b v1 = role_1b default"
"msg": "root = role_1b | role_2 v1 = role_1b default"
"msg": "root = role_1b | role_3 v1 = role_1b default" <=== was: role_1a default
"msg": "root = role_1b | role_4 v1 = role_1b default"
"msg": "root = role_1b | role_5 v1 = role_1b default"
Это показывает, что порядок сообщений правильный. Но результат изменился. Теперь результат role_1b
соответствует ожидаемому.
Q: "Пространство имен для избежания конфликтов. Что такое пространство имен?"
A: «Пространство имен» означает «определить переменную» или, в частности, «зарегистрировать переменную на хосте», т.е. поместить переменную в hostvars
. Например,
# roles/role_1a/tasks/main.yml
- set_fact:
v1: "{{ v1 }}"
- debug: msg="role_1a v1 = {{ v1 }}"
- import_role:
name: role_2
vars:
root: "role_1a"
дает ожидаемый результат
"msg": "role_1a v1 = role_1a default"
"msg": "root = role_1a | role_2 v1 = role_1a default"
"msg": "root = role_1a | role_3 v1 = role_1a default"
"msg": "root = role_1a | role_4 v1 = role_1a default"
"msg": "root = role_1a | role_5 v1 = role_1a default"
"msg": "role_1b v1 = role_1a default"
"msg": "root = role_1b | role_2 v1 = role_1a default"
"msg": "root = role_1b | role_3 v1 = role_1a default"
"msg": "root = role_1b | role_4 v1 = role_1a default"
"msg": "root = role_1b | role_5 v1 = role_1a default"
, поскольку, как только переменная v1
была определена в области действия платежной книжки, нет необходимости искать значение по умолчанию. Следует отметить, что
- debug: msg="role_1a v1 = {{ v1 }}"
не определяет переменную v1
. Этот оператор будет оценивать только переменную v1
по требованию. Цитата из Ansible Глоссарий :
Lazy Evaluation : В целом, Ansible оценивает любые переменные в содержимом playbook в последнюю возможную секунду, что означает, что если вы определяете структуру данных, то сама структура данных может определять значения переменных внутри нее, и все «просто работает» так, как вы ожидаете. Это также означает, что переменные строки могут включать другие переменные внутри этих строк.
Тот же результат должен быть достигнут с измененным порядком ролей, поскольку все роли импортированы.
- hosts: localhost
roles:
- role_1b
- role_1a
дает
"msg": "role_1b v1 = role_1b default" <=== expected role_1a default
"msg": "root = role_1b | role_2 v1 = role_1b default" <=== expected role_1a default
"msg": "root = role_1b | role_3 v1 = role_1b default" <=== expected role_1a default
"msg": "root = role_1b | role_4 v1 = role_1a default"
"msg": "root = role_1b | role_5 v1 = role_1a default"
"msg": "role_1a v1 = role_1a default"
"msg": "root = role_1a | role_2 v1 = role_1a default"
"msg": "root = role_1a | role_3 v1 = role_1a default"
"msg": "root = role_1a | role_4 v1 = role_1a default"
"msg": "root = role_1a | role_5 v1 = role_1a default"
Это показывает, что «пространство имен», вероятно, необходимо во всех ролях. Например,
# roles/role_1b/tasks/main.yml
- set_fact:
v1: "{{ v1 }}"
- debug: msg="role_1b v1 = {{ v1 }}"
- import_role:
name: role_2
vars:
root: "role_1b"
решает проблему.