# variables messed up when using including tasks

**URL:** <https://forum.ansible.com/t/variables-messed-up-when-using-including-tasks/19965>\
**Category:** Ansible Project\
**Created:** [December 8, 2015, 5:56pm UTC](https://forum.ansible.com/t/variables-messed-up-when-using-including-tasks/19965 "2015-12-08T17:56:26Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![silverdr](https://avatars.discourse-cdn.com/v4/letter/s/e19adc/32.png) [@silverdr](https://forum.ansible.com/u/silverdr)\
**Post date:** [December 8, 2015, 5:56pm UTC](https://forum.ansible.com/t/variables-messed-up-when-using-including-tasks/19965/1 "2015-12-08T17:56:26Z")

</div>

Hello, group, I encountered a strange problem with variables when running a role. The role has some defaults and the variables are used throughout the plays. At some point in the tasks/mains playbook, there are included other tasks from the same directory. Those also include tasks from root directory. Everything seems fine but when the plays AFTER the included are executed then the variables are no longer valid (seems like they are taken from another role’s). None of the included tasks changes the variables in question. Seems like a bug? Or am I missing something.

---

<div class="post-metadata">

**Author:** ![silverdr](https://avatars.discourse-cdn.com/v4/letter/s/e19adc/32.png) [@silverdr](https://forum.ansible.com/u/silverdr)\
**Post date:** [December 8, 2015, 6:29pm UTC](https://forum.ansible.com/t/variables-messed-up-when-using-including-tasks/19965/2 "2015-12-08T18:29:12Z")

</div>

Actually the problem shows up even when the included tasks do not include any other ones.

---

<div class="post-metadata">

**Author:** ![Brian\_Coca](https://avatars.discourse-cdn.com/v4/letter/b/6de8d8/32.png) [@Brian\_Coca](https://forum.ansible.com/u/Brian_Coca)\
**Post date:** [December 8, 2015, 11:10pm UTC](https://forum.ansible.com/t/variables-messed-up-when-using-including-tasks/19965/3 "2015-12-08T23:10:58Z")

</div>

I’m not understanding the problem, can you post an acual example and also what versions you are using?

---

<div class="post-metadata">

**Author:** ![silverdr](https://avatars.discourse-cdn.com/v4/letter/s/e19adc/32.png) [@silverdr](https://forum.ansible.com/u/silverdr)\
**Post date:** [December 8, 2015, 11:54pm UTC](https://forum.ansible.com/t/variables-messed-up-when-using-including-tasks/19965/4 "2015-12-08T23:54:24Z")

</div>

> I'm not understanding the problem, can you post an acual example and also what versions you are using?

There are several roles with practically the same structures:

- role0  
&nbsp;&nbsp;- defaults  
&nbsp;&nbsp;&nbsp;&nbsp;- main.yml  
&nbsp;&nbsp;- tasks  
&nbsp;&nbsp;&nbsp;&nbsp;- main.yml  
&nbsp;&nbsp;&nbsp;&nbsp;- task1.yml  
&nbsp;&nbsp;&nbsp;&nbsp;- task2.yml  
&nbsp;&nbsp;&nbsp;&nbsp;- etc.yml

- role1  
&nbsp;&nbsp;- defaults  
&nbsp;&nbsp;&nbsp;&nbsp;- main.yml  
&nbsp;&nbsp;- tasks  
&nbsp;&nbsp;&nbsp;&nbsp;- main.yml  
&nbsp;&nbsp;&nbsp;&nbsp;- task1.yml  
&nbsp;&nbsp;&nbsp;&nbsp;- task2.yml  
&nbsp;&nbsp;&nbsp;&nbsp;- etc.yml

- role2  
&nbsp;&nbsp;- defaults  
&nbsp;&nbsp;&nbsp;&nbsp;- main.yml  
&nbsp;&nbsp;- tasks  
&nbsp;&nbsp;&nbsp;&nbsp;- main.yml  
&nbsp;&nbsp;&nbsp;&nbsp;- task1.yml  
&nbsp;&nbsp;&nbsp;&nbsp;- task2.yml  
&nbsp;&nbsp;&nbsp;&nbsp;- etc.yml

and so on. There are other directories but "vars" are empty in all of them. Each role's "main" task uses variables defined in respective "defaults" but also includes other tasks from the same role and tasks directory. While default values are all fine as long as they are used before the first

- include?: task1.yml

they get their values overwritten with some defaults from another role (sic!) once finished processing the included task file. Now that looks to me like a bug but I might be missing something.

A real example:

# Prerequisities / system dependencies  
- name: install python http library  
&nbsp;&nbsp;apt: name={{item}} state=present  
&nbsp;&nbsp;with\_items:  
&nbsp;&nbsp;&nbsp;&nbsp;- python-httplib2

# Configuring PHP  
- include: php.yml

# Configuring database  
- include: database.yml

# Configuring network  
- include: network.yml

# Configuring httpd  
- include: httpd.yml

# Getting and preparing / installing the code  
- name: clone repository  
&nbsp;&nbsp;git: repo={{repository}} dest={{destination}} accept\_hostkey=yes

When I place git above the included tasks then {{destination}} is correct. When I place it below any of the included tasks, then the destination gets wrong value of a default from a completely different role...

---

<div class="post-metadata">

**Author:** ![igorc](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/igorc/32/5491_2.png) [@igorc](https://forum.ansible.com/u/igorc)\
**Post date:** [December 9, 2015, 9:35pm UTC](https://forum.ansible.com/t/variables-messed-up-when-using-including-tasks/19965/5 "2015-12-09T21:35:48Z")

</div>

Do you by any chance have some of those vars also defined in the group\_vars/all file? In that case they overide the ones in the roles default file causing unexpected results for people unaware of this fact.

---

<div class="post-metadata">

**Author:** ![patrycjusz.logiewa](https://avatars.discourse-cdn.com/v4/letter/p/71e660/32.png) [@patrycjusz.logiewa](https://forum.ansible.com/u/patrycjusz.logiewa)\
**Post date:** [December 10, 2015, 11:29am UTC](https://forum.ansible.com/t/variables-messed-up-when-using-including-tasks/19965/6 "2015-12-10T11:29:35Z")

</div>

No, that would actually explain - Definitely there is no "destination" for example in any group\_vars/, host\_vars/, etc. In group\_vars/all, there is only a vaulted set of "sensitive" variables like passwords, keys, etc.

---

<div class="post-metadata">

**Author:** ![igorc](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/igorc/32/5491_2.png) [@igorc](https://forum.ansible.com/u/igorc)\
**Post date:** [December 10, 2015, 10:13pm UTC](https://forum.ansible.com/t/variables-messed-up-when-using-including-tasks/19965/7 "2015-12-10T22:13:51Z")

</div>

Strange, because I'm sure every time I call a tasks file from another role I have to explicitly include that role's defaults|vars file via vars\_files to be able to use its variables. So you are saying you are seeing this happen without this linking. Do you mind showing us the whole main playbook?

---

<div class="post-metadata">

**Author:** ![silverdr](https://avatars.discourse-cdn.com/v4/letter/s/e19adc/32.png) [@silverdr](https://forum.ansible.com/u/silverdr)\
**Post date:** [December 11, 2015, 12:09am UTC](https://forum.ansible.com/t/variables-messed-up-when-using-including-tasks/19965/8 "2015-12-11T00:09:16Z")

</div>

FYI: I - kind of - worked the problem around by moving the variables from "defaults" to "vars" but this causes other inconveniences when I actually want to overwrite them.

Example playbook ({{destination}} value changes after the first -include:

---

<div class="post-metadata">

**Author:** ![silverdr](https://avatars.discourse-cdn.com/v4/letter/s/e19adc/32.png) [@silverdr](https://forum.ansible.com/u/silverdr)\
**Post date:** [December 11, 2015, 12:13am UTC](https://forum.ansible.com/t/variables-messed-up-when-using-including-tasks/19965/9 "2015-12-11T00:13:54Z")

</div>

Actually I stay within one role. The problem is that when I include other tasks from the same role, the role's defaults change into values from another role, which defaults have variables named the same as in the current one.

---

<div class="post-metadata">

**Author:** ![igorc](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/igorc/32/5491_2.png) [@igorc](https://forum.ansible.com/u/igorc)\
**Post date:** [December 11, 2015, 4:37am UTC](https://forum.ansible.com/t/variables-messed-up-when-using-including-tasks/19965/10 "2015-12-11T04:37:37Z")

</div>

Just out of curiosity, what happens when you supply destination via extra\_vars and leave everything as it was in defaults file?

---

<div class="post-metadata">

**Author:** ![igorc](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/igorc/32/5491_2.png) [@igorc](https://forum.ansible.com/u/igorc)\
**Post date:** [December 11, 2015, 4:45am UTC](https://forum.ansible.com/t/variables-messed-up-when-using-including-tasks/19965/11 "2015-12-11T04:45:59Z")

</div>

Also if you can put

- debug: var=destination

before and after every include call would be very helpful to see where the var actually gets changed.

Just realized that my previous message might not be clear enough, what I mean is add:

–extra-vars ‘{“destination”:“some\_value\_here”}’

to the ansible-playbook command and move back all your vars in their respective defaults files as they were before.

---

<div class="post-metadata">

**Author:** ![silverdr](https://avatars.discourse-cdn.com/v4/letter/s/e19adc/32.png) [@silverdr](https://forum.ansible.com/u/silverdr)\
**Post date:** [December 12, 2015, 4:31pm UTC](https://forum.ansible.com/t/variables-messed-up-when-using-including-tasks/19965/12 "2015-12-12T16:31:04Z")

</div>

I /think/ I know where the problem comes from: I encountered it with group vars defined in the inventory file. I eventually moved both the role variables and group\_vars into inventory file, trying to establish one place where the variables are defined. Now:

My inventory file looks like this (IPs are dummy):

[group0]  
234.123.41.44  
[group0:vars]  
var0=00  
var1=01

[group1]  
234.123.41.45  
[group1:vars]  
var0=10  
var1=11

Now, in this configuration, variables have their values intact. But when I refer with both groups to the same host, like:

[group0]  
234.123.41.44  
[group0:vars]  
var0=00  
var1=01

[group1]  
234.123.41.44  
[group1:vars]  
var0=10  
var1=11

which I guess is rather typical when deploying to development environment, then the group0 variables get overwritten!

Since my configuration with "defaults" has been applied to similar inventory, my best guess is that this caused the problem there too. Now - what to do in order to have the variables keep their values for different groups, even if the host happens to be the same? And shouldn't it be the case anyway?

---

<div class="post-metadata">

**Author:** ![igorc](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/igorc/32/5491_2.png) [@igorc](https://forum.ansible.com/u/igorc)\
**Post date:** [December 13, 2015, 12:07am UTC](https://forum.ansible.com/t/variables-messed-up-when-using-including-tasks/19965/13 "2015-12-13T00:07:40Z")

</div>

Well of course they get overwritten in the _same_ play since all variables are _global_ during the play execution, otherwise if you call group1 after group0 what will happen is group1 will get the variables from group0, which is not desirable, right?

What you need to do is rethink your playbooks and inventory structure, think of using multiple roles instead of single one with many tasks and keep the global variables names unique if you don’t want them overwritten.

---

<div class="post-metadata">

**Author:** ![silverdr](https://avatars.discourse-cdn.com/v4/letter/s/e19adc/32.png) [@silverdr](https://forum.ansible.com/u/silverdr)\
**Post date:** [December 13, 2015, 12:03pm UTC](https://forum.ansible.com/t/variables-messed-up-when-using-including-tasks/19965/14 "2015-12-13T12:03:15Z")

</div>

> Well of course they get overwritten in the \*same\* play since all variables are \*global\* during the play execution,

Well, until yesterday I wouldn't say "of course". If I used host variables, then I would understand this as being "of course". I thought that group variables are applied to the group's host(s) upon processing. In the sense that if I don't process the other group, the variables would remain intact. But then, after writing the previous post, I dumped the 'hostvars' and only then realised what's going on.

> otherwise if you call group1 after group0 what will happen is group1 will get the variables from group0, which is not desirable, right?

Frankly - I would expect/desire that when I call group0, I get variables defined for group0, when I call group1, I get the values as defined for group1. Even if they apply to the same host in the end. And if I wanted them within the host scope, I would use host\_vars rather then group\_vars. I understand that this is somewhat more difficult to implement, because a kind of "group context" or "group scope" would need to be introduced to the Ansible's inner workings. From what I saw in the variables dump, nothing like that's been done so far. Seems like during play execution, everything's thrown into one basket (becomes global as you mentioned). This is surely easier to implement but in this case I find the group\_vars concept of noticeably lower value and also susceptible to errors, unless one understands that they are actually kind of "global host\_vars".

> What you need to do is rethink your playbooks and inventory structure, think of using multiple roles instead of single one with many tasks

The setup is quite complex with many roles and even those roles have number of tasks, many of them being very similar, which is why tried to extract the repetitive tasks from within the roles and place those in the upper level, where it would be accessible for all roles. You know, the good, old DRY stuff.. "Of course" I used the same variable names in all the roles as they do the same thing and the shared, included tasks use them this way. Things - kind of - worked until I started including tasks, which is probably where it traverses the directory structure and overwrites the values.

> and keep the global variables names unique if you don't want them overwritten.

Actually - as I wrote above - I didn't expect them to be global. I wanted to keep them within the scope of role/group. Both approaches fail due to variables being overwritten. I spent several days on this already and eventually ended up generating different role/group variable naming (prefixes). Then I assign them (set\_fact:) to the required variables right before including the tasks from upper level. Reworked half of the setup this way - works so far but I don't find it an elegant way. I've got this feeling like I am writing a program with tens of thousands lines of code and am allowed to use only global variables everywhere...
