# Using include\_vars and with\_items with optiona files == bug?

**URL:** <https://forum.ansible.com/t/using-include-vars-and-with-items-with-optiona-files-bug/24945>\
**Category:** Ansible Project\
**Tags:** rhel\
**Created:** [July 10, 2017, 7:53pm UTC](https://forum.ansible.com/t/using-include-vars-and-with-items-with-optiona-files-bug/24945 "2017-07-10T19:53:29Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![dan\_linder](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/dan_linder/32/3833_2.png) [@dan\_linder](https://forum.ansible.com/u/dan_linder)\
**Post date:** [July 10, 2017, 7:53pm UTC](https://forum.ansible.com/t/using-include-vars-and-with-items-with-optiona-files-bug/24945/1 "2017-07-10T19:53:29Z")

</div>

I’m trying to setup a hierarchical set of variable files so that different teams can setup value, permitting more specific instances to override generic ones. The key is that the more specific instances may not be defined in all cases. I thought I solved it with a combination of “include\_vars” and “with\_items” and using “ignore\_errors” to skip a missing file.

But, when any of the include files are missing the entire set of included values are lost. It appears that any ignored failure in the include\_vars deletes the entire data structure when it continues on.

Here’s a sample playbook and variable files. (For what it’s worth this is Ansible 2.2.0.0 on RHEL 6)  
**teststackvars.yml**

> #!/usr/bin/env ansible-playbook
> 
> # Run like this:
> 
> # ANSIBLE\_HASH\_BEHAVIOUR=merge ./teststackvars.yml -i localhost, -l localhost --check
> 
> # or set hash behavior in ansible.cfg and run without variable.
> 
> * * *
> 
> - hosts: all
> 
> gather\_facts: False
> 
> tasks:
> 
> - name: Include the variables in precedence
> 
> include\_vars:
> 
> file: “{{ item }}”
> 
> name: myvars
> 
> with\_items:
> 
> - info\_a.yml
> 
> - info\_b.yml
> 
> - info\_{{ inventory\_hostname }}.yml
> 
> ignore\_errors: True
> 
> - debug:
> 
> msg: “{{ myvars }}”

And these three vars files:

**vars/info\_a.yml**

> * * *
> 
> var\_from\_info\_a: from info\_a.yml
> 
> some\_var: value from info\_a

**vars/info\_b.yml**

> * * *
> 
> var\_from\_info\_b: from info\_b.yml
> 
> some\_var: value from info\_b

**vars/info\_localhost.yml**

> * * *
> 
> var\_from\_info\_localhost: from info\_localhost.yml
> 
> some\_var: value from info\_localhost

When I run it with all files defined it works just fine:

> **$ ./teststackvars.yml -i localhost, -l localhost --check**
> 
> **PLAY [all] \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\***
> 
> **TASK [Include the variables in precedence] \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\***
> 
> **ok: [localhost] =\> (item=info\_a.yml)**
> 
> **ok: [localhost] =\> (item=info\_b.yml)**
> 
> **ok: [localhost] =\> (item=info\_localhost.yml)**
> 
> **TASK [debug] \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\***
> 
> **ok: [localhost] =\> {**
> 
> **“msg”: {**
> 
> **“some\_var”: “value from info\_localhost”,**
> 
> **“var\_from\_info\_a”: “from info\_a.yml”,**
> 
> **“var\_from\_info\_b”: “from info\_b.yml”,**
> 
> **“var\_from\_info\_localhost”: “from info\_localhost.yml”**
> 
> **}**
> 
> **}**
> 
> **PLAY RECAP \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\***
> 
> **localhost : ok=2 changed=0 unreachable=0 failed=0**

That looks good - all the unique variables from info\_a/b/localhost are defined, and the common “some\_var” is overwritten by the last file.

When I rename one of the YML files, the entire “myvars” variable structure goes away:

> **$ mv vars/info\_localhost.yml vars/info\_localhost.yml.disabled**
> 
> **$ ./teststackvars.yml -i localhost, -l localhost --check**
> 
> **PLAY [all] \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\***
> 
> **TASK [Include the variables in precedence] \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\***
> 
> **ok: [localhost] =\> (item=info\_a.yml)**
> 
> **ok: [localhost] =\> (item=info\_b.yml)**
> 
> **fatal: [localhost]: FAILED! =\> {“failed”: true, “msg”: “Unable to find ‘info\_localhost.yml’ in expected paths.”}**
> 
> **…ignoring**
> 
> **TASK [debug] \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\***
> 
> **fatal: [localhost]: FAILED! =\> {“failed”: true, “msg”: “the field ‘args’ has an invalid value, which appears to include a variable that is undefined. The error was: ‘myvars’ is undefined\n\nThe error appears to have been in ‘/home/dan/teststackvars/teststackvars.yml’: line 20, column 5, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n - debug:\n ^ here\n”}**
> 
> **to retry, use: --limit @/home/dan/teststackvars/teststackvars.retry**
> 
> **PLAY RECAP \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\***
> 
> **localhost : ok=1 changed=0 unreachable=0 failed=1**
> 
> **$**

I searched the group and Google in general for “with\_items” and “include\_vars” but didn’t see anything that seems to pertain to this. Shouldn’t this work - at least let the variables that were in the “myvars” stay in-spite of the missing variable file?

Thanks,  
Dan

---

<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:** [July 10, 2017, 7:59pm UTC](https://forum.ansible.com/t/using-include-vars-and-with-items-with-optiona-files-bug/24945/2 "2017-07-10T19:59:11Z")

</div>

Well, when you include\_vars you are normally overwriting existing  
vars, this will happen in a with\_ loop or outside of it, that is  
normal behaviour.

As for the error wiping out myvars ... the task failed, so none of the  
work was done. The previously accumulated data in the 2 files that did  
work is lost as the task ends up not importing any vars as it failed  
as a whole, even if parts of it succeeded.

---

<div class="post-metadata">

**Author:** ![dan\_linder](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/dan_linder/32/3833_2.png) [@dan\_linder](https://forum.ansible.com/u/dan_linder)\
**Post date:** [July 10, 2017, 8:10pm UTC](https://forum.ansible.com/t/using-include-vars-and-with-items-with-optiona-files-bug/24945/3 "2017-07-10T20:10:13Z")

</div>

I forgot to add that I’ve defined the hash\_behaviour to “merge” just for this express purpose of keeping and stacking/appending variables so the normal behavior is suppose to be modified here.

---

<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:** [July 10, 2017, 8:39pm UTC](https://forum.ansible.com/t/using-include-vars-and-with-items-with-optiona-files-bug/24945/4 "2017-07-10T20:39:15Z")

</div>

The merge setting will affect the result of the task, but not the  
internal iterator of the task.

You might want to make this 3 tasks or use vars\_files.

---

<div class="post-metadata">

**Author:** ![dan\_linder](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/dan_linder/32/3833_2.png) [@dan\_linder](https://forum.ansible.com/u/dan_linder)\
**Post date:** [July 10, 2017, 9:35pm UTC](https://forum.ansible.com/t/using-include-vars-and-with-items-with-optiona-files-bug/24945/5 "2017-07-10T21:35:51Z")

</div>

I’m falling back to the six tasks for now (three stat file, three include when exists).

In my mind this is a bug; the “ignore\_errors” setting should let it keep the partial result. The parallel being that the file module could partially succeed in setting a file owner but SELinux or other methods could deny the setting of the file group.

But I’ll agree to disagree with you on that point. 🙂

I could see the addition of the “hash\_behavior” as an argument to “include\_vars” and let it have the option of “keep\_partial” as an extension of merge (replace, merge, merge\_partial).

---

<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:** [July 11, 2017, 12:04am UTC](https://forum.ansible.com/t/using-include-vars-and-with-items-with-optiona-files-bug/24945/6 "2017-07-11T00:04:49Z")

</div>

Well, this is not include\_vars behaviour but 'merge loop results  
behaviour' that affects all modules as this is result processing.

The other part of 'saving intermediate results' would also affect all tasks.

I doubt either will change in the future.
