Repository: ansible/ansible

Issue:
Regression in variables precedence: extra_vars do not override values inside rolename/vars interpolation
Upgraded from 1.7.2 to 1.9.0.1, and found the regression in variable interpolation and precedence (still present in 1.9.1): the variables from extra_vars, if used inside an interpolation within another variable defined in <rolename>/vars/main.yml, lose their precedence.

Imagine the following playbook:
## ansible/group_vars/all

```
v1: group-vars-v1
v2: group-vars-v2
```
## ansible/inventories/local

```
[local]
127.0.0.1
```
## ansible/roles/test-role/tasks/main.yml

```
- name: "Print variables"
  debug: msg="v1={{ v1 }}, v2={{ v2 }}, v_total={{ v_total }}"
```
## ansible/roles/test-role/vars/main.yml

```
v_total: "/{{ v1 }}/{{ v2 }}"
```
## ansible/site.yml

```
- name: Test playbook
  hosts: all
  roles:
   - test-role
```

What happens if we launch `ansible-playbook --inventory=ansible/inventories/local --connection=local ansible/site.yml --extra-vars="v1=extra-v1"` (pay attention to `v_total` value):
## Ansible 1.7.2 (correct)

```
PLAY [Test playbook] ********************************************************** 

GATHERING FACTS *************************************************************** 
ok: [127.0.0.1]

TASK: [test-role | Print variables] ******************************************* 
ok: [127.0.0.1] => {
    "msg": "v1=extra-v1, v2=group-vars-v2, v_total=/extra-v1/group-vars-v2"
}

PLAY RECAP ******************************************************************** 
127.0.0.1                  : ok=2    changed=0    unreachable=0    failed=0
```
## Ansible 1.9.0.1/1.9.1 (wrong)

```
PLAY [Test playbook] ********************************************************** 

GATHERING FACTS *************************************************************** 
ok: [127.0.0.1]

TASK: [test-role | Print variables] ******************************************* 
ok: [127.0.0.1] => {
    "msg": "v1=extra-v1, v2=group-vars-v2, v_total=/group-vars-v1/group-vars-v2"
}

PLAY RECAP ******************************************************************** 
127.0.0.1                  : ok=2    changed=0    unreachable=0    failed=0
```

May be related to bug #10817 

Regression in variables precedence: extra_vars do not override values inside rolename/vars interpolation
Upgraded from 1.7.2 to 1.9.0.1, and found the regression in variable interpolation and precedence (still present in 1.9.1): the variables from extra_vars, if used inside an interpolation within another variable defined in <rolename>/vars/main.yml, lose their precedence.

Imagine the following playbook:
## ansible/group_vars/all

```
v1: group-vars-v1
v2: group-vars-v2
```
## ansible/inventories/local

```
[local]
127.0.0.1
```
## ansible/roles/test-role/tasks/main.yml

```
- name: "Print variables"
  debug: msg="v1={{ v1 }}, v2={{ v2 }}, v_total={{ v_total }}"
```
## ansible/roles/test-role/vars/main.yml

```
v_total: "/{{ v1 }}/{{ v2 }}"
```
## ansible/site.yml

```
- name: Test playbook
  hosts: all
  roles:
   - test-role
```

What happens if we launch `ansible-playbook --inventory=ansible/inventories/local --connection=local ansible/site.yml --extra-vars="v1=extra-v1"` (pay attention to `v_total` value):
## Ansible 1.7.2 (correct)

```
PLAY [Test playbook] ********************************************************** 

GATHERING FACTS *************************************************************** 
ok: [127.0.0.1]

TASK: [test-role | Print variables] ******************************************* 
ok: [127.0.0.1] => {
    "msg": "v1=extra-v1, v2=group-vars-v2, v_total=/extra-v1/group-vars-v2"
}

PLAY RECAP ******************************************************************** 
127.0.0.1                  : ok=2    changed=0    unreachable=0    failed=0
```
## Ansible 1.9.0.1/1.9.1 (wrong)

```
PLAY [Test playbook] ********************************************************** 

GATHERING FACTS *************************************************************** 
ok: [127.0.0.1]

TASK: [test-role | Print variables] ******************************************* 
ok: [127.0.0.1] => {
    "msg": "v1=extra-v1, v2=group-vars-v2, v_total=/group-vars-v1/group-vars-v2"
}

PLAY RECAP ******************************************************************** 
127.0.0.1                  : ok=2    changed=0    unreachable=0    failed=0
```

May be related to bug #10817 



Discussion:
Would be great to have this fixed. I'm facing the exact same problem

this probably broke in 1.8 when var merging was restructured.

Yup, I just upgraded ansible from 1.7.2 to 1.9.1 and started facing this problem. I'm now stuck with 1.9.1 and cannot revert back to 1.7.2
Found a temporary work around by using `set_fact` until we have a fix for this

What is the workaround? I'm trying to fix the same issue.

@rossimo I had to work around by moving vars from group_vars to `roles/foo/defaults/main.yml`. Not particularly desirable but that's the only thing that seemed to work in my situation.

@darshanrp could you provide more details explaining how you used `set_fact` to work around this?

Hi, this situation is no longer present in the devel branch (which will be ansible 2.0). Here is the output using a version of your example above:

<pre>
# ansible-playbook -vv -i inv site.yml --extra-vars="v1=extra-v1" -c local
Using /etc/ansible/ansible.cfg as config file
1 plays in site.yml
PLAY: Test playbook *************************************************************
TASK [setup] ********************************************************************
ok: [127.0.0.1]
TASK [test-role : test-role : Print variables] **********************************
ok: [127.0.0.1] => {
    "changed": false, 
    "msg": "v1=extra-v1, v2=group-vars-v2, v_total=/extra-v1/group-vars-v2"
}
PLAY RECAP **********************************************************************
127.0.0.1                  : ok=2    changed=0    unreachable=0    failed=0   
</pre>

Per our normal policy, we close bug report issues when we see the issue has been corrected in the devel branch, so we will close this issue now.

If you continue seeing any problems related to this issue, or if you have any further questions, please let us know by stopping by one of the two mailing lists, as appropriate:
- https://groups.google.com/forum/#!forum/ansible-project - for user questions, tips, and tricks
- https://groups.google.com/forum/#!forum/ansible-devel - for strategy, future planning, and questions about writing code

Because this project is very active, we're unlikely to see comments made on closed tickets, but the mailing list is a great way to ask questions, or post if you don't think this particular issue is resolved.

Thank you!

That still happens in 1.9.4. Although I understand the 'normal policy', variable precedence is quite different from 2.x to 1.x (among other things), so "update to v2" might not be a solution. This is not going to be solved on stable-1.9? That means that 1.x is considered unmaintained?
I expect variables supplied by the user on command line should override everything (as otherwise is stated in the documentation), so I consider this a major issue.
If this issue is not going to be reopened, please a better hint to '1.8 when var merging was restructured' will make easier to me investigate it.

Would be great to have this fixed. I'm facing the exact same problem

this probably broke in 1.8 when var merging was restructured.

Yup, I just upgraded ansible from 1.7.2 to 1.9.1 and started facing this problem. I'm now stuck with 1.9.1 and cannot revert back to 1.7.2
Found a temporary work around by using `set_fact` until we have a fix for this

What is the workaround? I'm trying to fix the same issue.

@rossimo I had to work around by moving vars from group_vars to `roles/foo/defaults/main.yml`. Not particularly desirable but that's the only thing that seemed to work in my situation.

@darshanrp could you provide more details explaining how you used `set_fact` to work around this?

Hi, this situation is no longer present in the devel branch (which will be ansible 2.0). Here is the output using a version of your example above:

<pre>
# ansible-playbook -vv -i inv site.yml --extra-vars="v1=extra-v1" -c local
Using /etc/ansible/ansible.cfg as config file
1 plays in site.yml
PLAY: Test playbook *************************************************************
TASK [setup] ********************************************************************
ok: [127.0.0.1]
TASK [test-role : test-role : Print variables] **********************************
ok: [127.0.0.1] => {
    "changed": false, 
    "msg": "v1=extra-v1, v2=group-vars-v2, v_total=/extra-v1/group-vars-v2"
}
PLAY RECAP **********************************************************************
127.0.0.1                  : ok=2    changed=0    unreachable=0    failed=0   
</pre>

Per our normal policy, we close bug report issues when we see the issue has been corrected in the devel branch, so we will close this issue now.

If you continue seeing any problems related to this issue, or if you have any further questions, please let us know by stopping by one of the two mailing lists, as appropriate:
- https://groups.google.com/forum/#!forum/ansible-project - for user questions, tips, and tricks
- https://groups.google.com/forum/#!forum/ansible-devel - for strategy, future planning, and questions about writing code

Because this project is very active, we're unlikely to see comments made on closed tickets, but the mailing list is a great way to ask questions, or post if you don't think this particular issue is resolved.

Thank you!

That still happens in 1.9.4. Although I understand the 'normal policy', variable precedence is quite different from 2.x to 1.x (among other things), so "update to v2" might not be a solution. This is not going to be solved on stable-1.9? That means that 1.x is considered unmaintained?
I expect variables supplied by the user on command line should override everything (as otherwise is stated in the documentation), so I consider this a major issue.
If this issue is not going to be reopened, please a better hint to '1.8 when var merging was restructured' will make easier to me investigate it.


Resolving patch:
diff --git a/lib/ansible/runner/__init__.py b/lib/ansible/runner/__init__.py
--- a/lib/ansible/runner/__init__.py
+++ b/lib/ansible/runner/__init__.py
@@ -611,6 +611,7 @@ def get_inject_vars(self, host):
         # since some of the variables we'll be replacing may be contained there too
         module_vars_inject = utils.combine_vars(host_variables, combined_cache.get(host, {}))
         module_vars_inject = utils.combine_vars(self.module_vars, module_vars_inject)
+        module_vars_inject = utils.combine_vars(module_vars_inject, self.extra_vars)
         module_vars = template.template(self.basedir, self.module_vars, module_vars_inject)
 
         # remove bad variables from the module vars, which may be in there due


Test patch: