I've been playing with ansible for the last couple of days and have run into a behavior that makes no sense to me. I can reproduce this with a simple playbook that runs two roles. Each role sets a variable, then imports a chain of other roles. The other roles do nothing but print out the value of the variable, then import the next role in the chain. The output I get is:
$ ansible-playbook site.yml
"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" <=== expected role_1a default
"msg": "role_5 v1 = role_1b default" <=== expected role_1a default
"msg": "role_1b v1 = role_1b default"
"msg": "role_2 v1 = role_1b default"
"msg": "role_3 v1 = role_1a default" <=== expected role_1b default
"msg": "role_4 v1 = role_1b default"
"msg": "role_5 v1 = role_1b default"
I've read the section on variables about twenty times now and the only thing I can see that may have a bearing on this is "Since Ansible 2.7 variables defined in vars and defaults for the role are exposed at playbook parsing time", which I suppose could mean that variable inheritance at execution time is a crapshoot.
# site.yml
- hosts: testserver
roles:
- role_1a
- role_1b
# roles/role_1a/defaults/main.yml
v1: "role_1a default"
# roles/role_1a/tasks/main.yml
- debug: msg="role_1a v1 = {{ v1 }}"
- import_role: name=role_2
# roles/role_2/tasks/main.yml
- debug: msg="role_2 v1 = {{ v1 }}"
- import_role: name=role_3
# roles/role_3/tasks/main.yml
- debug: msg="role_3 v1 = {{ v1 }}"
- import_role: name=role_4
# roles/role_4/tasks/main.yml
- debug: msg="role_4 v1 = {{ v1 }}"
- import_role: name=role_5
# roles/role_5/tasks/main.yml
- debug: msg="role_5 v1 = {{ v1 }}"
# roles/role_1b/defaults/main.yml
v1: "role_1b default"
# roles/role_1b/tasks/main.yml
- debug: msg="role_1b v1 = {{ v1 }}"
- import_role: name=role_2
# hosts
[testing]
testserver
# /etc/ansible/ansible.cfg
[defaults]
[inventory]
[privilege_escalation]
[paramiko_connection]
[ssh_connection]
[persistent_connection]
[accelerate]
[selinux]
[colors]
[diff]
$ ansible --version
ansible 2.9.3
config file = /etc/ansible/ansible.cfg
configured module search path = [u'/home/joe/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
ansible python module location = /usr/lib/python2.7/site-packages/ansible
executable location = /usr/bin/ansible
python version = 2.7.5 (default, Aug 7 2019, 00:51:29) [GCC 4.8.5 20150623 (Red Hat 4.8.5-39)]
re