I cannot find any where in the document about when the variable 
substitution happen. I want to know this because we can define variables in 
several places and we can refer to variables in different scopes. For 
example, a group var or host var or even a extra var can refer to a 
variable defined in roles. This is some kind of unexpected. Because there 
is a variable override priority described here: 
https://docs.ansible.com/ansible/latest/user_guide/playbooks_variables.html#understanding-variable-precedence

Normally we would thought the variable in higher priority get initialized 
first and cannot refer to low priority variables (extra vars override group 
vars, so normal people would expect we cannot refer to a group var in extra 
var) but this is not true. Normally we can refer to a variable anywhere in 
any scope. Even extra variable `-e testvar04='t
estvar03:{{testvar03}}'` can be expand in playbook. Here the testvar03 is 
defined in group vars and refer to a variable only defined in role 
defaults. So it looks like the variable substitution only happens at the 
very end right before the variable is used in a task. However, when I try 
to obtain variable in another host this rule is broken again: `
hostvars[ansible_host].testvar02` expands to `var_in_role: {{var_in_role}}`. 
The var_in_role is defined in role vars. So I wonder what is the actual 
rule about variable substitution? When the substitution actually happens? 
Do we have any chapter in the document define this behaviour?

Here is any example:

we have project structure like following:

```
├── inventory
│   └── hosts.yml
├── roles
│   └── test_var_substitution
│       ├── defaults
│       │   └── main.yml
│       ├── tasks
│       │   └── main.yml
│       └── vars
│           └── main.yml
└── test_var_substitution.yml
```

hosts.yml
```yaml
all:
  children:
    local:
      hosts:
        localhost:
          ansible_connection: local
          hostname: localhost
          host_var01: "define in host file"
          host_var02: "group_local_var01: {{group_local_var01}}"
      vars:
        group_local_var01: "define in local group"
  vars:
    testvar01: "set in group"
    testvar02: "var_in_role: {{var_in_role}}"
    testvar03: "var_in_role_default: {{var_in_role_default}}"
```

`roles/test_var_substitution/defaults/main.yml`:

```yaml
var_in_role_default: "define in role default only"
```
`roles/test_var_substitution/vars/main.yml`:
```yaml
var_in_role: "define in role only"
```

`roles/test_var_substitution/tasks/main.yml`:
```yaml

- debug:
    var: ansible_host
- name: show hostvars[ansible_host].testvar02
  debug:
    msg: "{{hostvars[ansible_host].testvar02}}"
- name: show hostvars[ansible_host].testvar03
  debug:
    msg: "{{hostvars[ansible_host].testvar03}}"
- name: show hostvars[hostname].host_var02
  debug:
    msg: "{{hostvars[hostname].host_var02}}"
- debug:
    var: testvar01
- debug:
    var: testvar02
- debug:
    var: testvar03
- debug:
    var: host_var02
```
`test_var_substitution.yml`:
```yaml
- hosts: all
  connection: local
  roles:
    - test_var_substitution
  tasks:
    - debug:
        var: testvar01
    - debug:
        var: testvar02
    - debug:
        var: testvar03
    - debug:
        var: testvar04
    - debug:
        var: hostvars[ansible_host].testvar02
```

```
$ ansible-playbook -i inventory test_var_substitution.yml -e 
testvar04='testvar03:{{testvar03}}'

PLAY [all] 
**************************************************************************************************

TASK [Gathering Facts] 
**************************************************************************************
ok: [localhost]

TASK [test_var_substitution : debug] 
************************************************************************
ok: [localhost] => {
    "ansible_host": "localhost"
}

TASK [test_var_substitution : show hostvars[ansible_host].testvar02] 
****************************************
ok: [localhost] => {
    "msg": "var_in_role: {{var_in_role}}"
}

TASK [test_var_substitution : show hostvars[ansible_host].testvar03] 
****************************************
ok: [localhost] => {
    "msg": "var_in_role_default: {{var_in_role_default}}"
}

TASK [test_var_substitution : show hostvars[hostname].host_var02] 
*******************************************
ok: [localhost] => {
    "msg": "group_local_var01: define in local group"
}

TASK [test_var_substitution : debug] 
************************************************************************
ok: [localhost] => {
    "testvar01": "set in group"
}

TASK [test_var_substitution : debug] 
************************************************************************
ok: [localhost] => {
    "testvar02": "var_in_role: define in role only"
}

TASK [test_var_substitution : debug] 
************************************************************************
ok: [localhost] => {
    "testvar03": "var_in_role_default: define in role default only"
}

TASK [test_var_substitution : debug] 
************************************************************************
ok: [localhost] => {
    "host_var02": "group_local_var01: define in local group"
}

TASK [debug] 
************************************************************************************************
ok: [localhost] => {
    "testvar01": "set in group"
}

TASK [debug] 
************************************************************************************************
ok: [localhost] => {
    "testvar02": "var_in_role: define in role only"
}

TASK [debug] 
************************************************************************************************
ok: [localhost] => {
    "testvar03": "var_in_role_default: define in role default only"
}

TASK [debug] 
************************************************************************************************
ok: [localhost] => {
    "testvar04": "testvar03:var_in_role_default: define in role default 
only"
}

TASK [debug] 
************************************************************************************************
ok: [localhost] => {
    "hostvars[ansible_host].testvar02": "var_in_role: {{var_in_role}}"
}

PLAY RECAP 
**************************************************************************************************
localhost                  : ok=14   changed=0    unreachable=0    
failed=0    skipped=0    rescued=0    ignored=0
```

-- 
You received this message because you are subscribed to the Google Groups 
"Ansible Project" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/ansible-project/be738890-b91e-4307-9c9f-4522a1981467n%40googlegroups.com.

Reply via email to