# Include Files for Role Variables

**URL:** <https://forum.ansible.com/t/include-files-for-role-variables/14368>\
**Category:** Ansible Project\
**Created:** [January 17, 2014, 5:14pm UTC](https://forum.ansible.com/t/include-files-for-role-variables/14368 "2014-01-17T17:14:06Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![AmiableAlbion](https://avatars.discourse-cdn.com/v4/letter/a/ea5d25/32.png) [@AmiableAlbion](https://forum.ansible.com/u/AmiableAlbion)\
**Post date:** [January 17, 2014, 5:14pm UTC](https://forum.ansible.com/t/include-files-for-role-variables/14368/1 "2014-01-17T17:14:06Z")

</div>

I am struggling to break out variables in the “var” directory of roles into individual files

I have tried and continue to get tracebacks. I thought this would be straight forward after seeing the documentation for include\_vars, but evidently I am missing something here.

I was trying something like this with Ansible 1.4.4

**vars/main.yml**  
**- include\_vars: credentials.yml**  
**- include\_vars: imagenames.yml**

**vars/imagenames.yml**  
**centos64: 52225cb3-441b-47b6-9cca-deb14d24d72f**

**rhel64: 364cd1c1-e958-4327-a0b4-3251da47869c**

**\> ansible-playbook vm.yml**  
  
**Traceback (most recent call last):  
File “/usr/bin/ansible-playbook”, line 269, in   
sys.exit(main(sys.argv[1:]))  
File “/usr/bin/ansible-playbook”, line 209, in main  
pb.run()  
File “/usr/lib/python2.6/site-packages/ansible/playbook/init.py”, line 229, in run  
play = Play(self, play\_ds, play\_basedir)  
File “/usr/lib/python2.6/site-packages/ansible/playbook/play.py”, line 83, in init  
ds = self.\_load\_roles(self.roles, ds)  
File “/usr/lib/python2.6/site-packages/ansible/playbook/play.py”, line 327, in \_load\_roles  
roles = self.\_build\_role\_dependencies(roles, , self.vars)  
File “/usr/lib/python2.6/site-packages/ansible/playbook/play.py”, line 192, in \_build\_role\_dependencies  
role\_vars = utils.combine\_vars(vars\_data, role\_vars)  
File “/usr/lib/python2.6/site-packages/ansible/utils/init.py”, line 1008, in combine\_vars  
return dict(a.items() + b.items())  
AttributeError: ‘list’ object has no attribute ‘items’**

Perhaps I am abusing syntax here though …

Thanks  
Albion

---

<div class="post-metadata">

**Author:** ![sivel](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/sivel/32/1198_2.png) [@sivel](https://forum.ansible.com/u/sivel)\
**Post date:** [January 17, 2014, 5:17pm UTC](https://forum.ansible.com/t/include-files-for-role-variables/14368/2 "2014-01-17T17:17:44Z")

</div>

include\_vars is a module that should be executed under a ‘tasks’ section.

What I believe you are looking for is vars\_files.

See [http://docs.ansible.com/playbooks\_variables.html#variable-file-separation](http://docs.ansible.com/playbooks_variables.html#variable-file-separation)

---

<div class="post-metadata">

**Author:** ![AmiableAlbion](https://avatars.discourse-cdn.com/v4/letter/a/ea5d25/32.png) [@AmiableAlbion](https://forum.ansible.com/u/AmiableAlbion)\
**Post date:** [January 17, 2014, 5:34pm UTC](https://forum.ansible.com/t/include-files-for-role-variables/14368/3 "2014-01-17T17:34:59Z")

</div>

Thanks Matt, overlooked that obvious detail (need more coffee).

So, following the vars\_files documentation I am still struggling.

**vars/main.yml**  
**vars\_files:**  
**- imagenames.yml**

**vars/imagenames.yml**  
**centos64: 52225cb3-441b-47b6-9cca-deb14d24d72f**

**\> ansible-playbook vm.yml**

PLAY [admin-vm] \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*

TASK: [provision | Creating virtual machine instances] \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
fatal: [10.0.0.6] =\> One or more undefined variables: ‘centos64’ is undefined

FATAL: all hosts have already failed – aborting

PLAY RECAP \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
to retry, use: --limit @/root/vm.retry

**10.0.0.6 : ok=0 changed=0 unreachable=1 failed=0**

I have tried using a relative and absolute paths to imagenames.yml with no luck.

Thanks  
Albion

---

<div class="post-metadata">

**Author:** ![sivel](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/sivel/32/1198_2.png) [@sivel](https://forum.ansible.com/u/sivel)\
**Post date:** [January 17, 2014, 5:48pm UTC](https://forum.ansible.com/t/include-files-for-role-variables/14368/4 "2014-01-17T17:48:44Z")

</div>

I think I overlooked something in your initial email.

vars\_files is usable from within a playbook, not from within a vars file. In your playbook just specify all of the vars files you want to include.

Something like:

---

<div class="post-metadata">

**Author:** ![Albion\_Baucom](https://avatars.discourse-cdn.com/v4/letter/a/838e76/32.png) [@Albion\_Baucom](https://forum.ansible.com/u/Albion_Baucom)\
**Post date:** [January 17, 2014, 6:20pm UTC](https://forum.ansible.com/t/include-files-for-role-variables/14368/5 "2014-01-17T18:20:08Z")

</div>

Thanks Matt, that works for me.

Best,  
Albion

---

<div class="post-metadata">

**Author:** ![kesten\_broughton1](https://avatars.discourse-cdn.com/v4/letter/k/dc4da7/32.png) [@kesten\_broughton1](https://forum.ansible.com/u/kesten_broughton1)\
**Post date:** [January 19, 2014, 4:00pm UTC](https://forum.ansible.com/t/include-files-for-role-variables/14368/6 "2014-01-19T16:00:10Z")

</div>

Another approach that is working for me is to pass in a vars file that points to all the other vars files that you may need that change from run to run.

ansible-playbook -i hosts site.yml -e “@cluster\_config.yml”

The use case is for creating clusters of hadoop based apps that have a high degree of configuration for various environments.  
I find ansible’s variables architecture ideal for setting up a situation that is more or less the same from run to run.  
But when you have network variables that change from one datacenter to the next, or a cluster configuration that depends on staging/prod/dev  
I find In need a more robust and de-coupled way of passing in re-usable but swappable configs.  
Note that you could do this by putting all the vars into a group\_vars/cluster\_name.yml but then you have to get creative with groups or lose the re-usability of components that can be shared between groups.

Here’s how i do it.

cluster\_cards/deployment\_name/cluster\_config.yml in my ansible playbook directory contains  
network\_config: “path to networking details for deployment”  
hadoop\_config: “path to architecture of hadoop cluster”  
environment\_config: “path to file with specific dev/prod config stuff”

Then in site.yml (or a tasks file with include\_vars: )

- hosts: hadoop\_cluster  
vars\_files:
- ["{{network\_config}}]
- ["{{environment\_config}}]
- ["{{hadoop\_config}}]

deployment1/network\_config\_1.yml  
/environment\_config.yml  
deployment2/network\_config\_2.yml

/  
shared/small\_hadoop\_cluster.yml  
/medium\_hadoop\_cluster.yml

I still use the ansible hierarchy of vars for less variable/configurable constants, but this has worked well for me

kesten

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan2](https://avatars.discourse-cdn.com/v4/letter/m/da6949/32.png) [@Michael\_DeHaan2](https://forum.ansible.com/u/Michael_DeHaan2)\
**Post date:** [January 19, 2014, 8:29pm UTC](https://forum.ansible.com/t/include-files-for-role-variables/14368/7 "2014-01-19T20:29:17Z")

</div>

I’d find that above a bit of an anti-pattern.

If you want to include multiple files and have that role associated versus play associated, the best way to do this is to use the “include\_vars” module inside a task file.

There’s an open RFE to include every file in “vars/” automatically with “main” coming first, but I’m thinking we’re likely to close that idea entirely – as conditional includes are useful things.

---

<div class="post-metadata">

**Author:** ![kesten\_broughton1](https://avatars.discourse-cdn.com/v4/letter/k/dc4da7/32.png) [@kesten\_broughton1](https://forum.ansible.com/u/kesten_broughton1)\
**Post date:** [January 20, 2014, 11:33pm UTC](https://forum.ansible.com/t/include-files-for-role-variables/14368/8 "2014-01-20T23:33:43Z")

</div>

> I’d find that above a bit of an anti-pattern.
> 
> If you want to include multiple files and have that role associated versus play associated, the best way to do this is to use the “include\_vars” module inside a task file.
> 
> There’s an open RFE to include every file in “vars/” automatically with “main” coming first, but I’m thinking we’re likely to close that idea entirely – as conditional includes are useful things.

> I had most of the items using include\_vars to begin with, but I make heavy use of --start-at-task while developing scripts / debugging.

It would be nice if include\_vars at the top of the file would get loaded even when starting at a task below that.  
It’s hard to imagine a case where that would be bad.

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan2](https://avatars.discourse-cdn.com/v4/letter/m/da6949/32.png) [@Michael\_DeHaan2](https://forum.ansible.com/u/Michael_DeHaan2)\
**Post date:** [January 21, 2014, 12:01am UTC](https://forum.ansible.com/t/include-files-for-role-variables/14368/9 "2014-01-21T00:01:49Z")

</div>

" It would be nice if include\_vars at the top of the file would get loaded even when starting at a task below that."

If include vars is below a task they are definitely injected into the namespace by the time a task below it is executed.

If you mean you want to write include vars after a task apply to a task before, this can’t happen, because the path may be derived from a registered variable or a call to a custom fact module, etc.

---

<div class="post-metadata">

**Author:** ![Albion\_Baucom](https://avatars.discourse-cdn.com/v4/letter/a/838e76/32.png) [@Albion\_Baucom](https://forum.ansible.com/u/Albion_Baucom)\
**Post date:** [January 21, 2014, 6:38pm UTC](https://forum.ansible.com/t/include-files-for-role-variables/14368/10 "2014-01-21T18:38:21Z")

</div>

I wanted to jump back into this conversation. It has been interesting.

I did like Kesten’s use of command line variables, but it looks like it is a better practice to have conditional inclusion of variables that are specific to a particular use of a role if I read this right.

We certainly have use cases like Kesten’s where I want to reuse a role but change variables. For instance, using the Nova compute module in a role to provision, it is ideal to have flexible variables to define the users OpenStack environment and project details like image IDs, security groups and other user specific configurations.

The ability to include variable files via the main in the “vars/” directory of a role seems it would be an improvement, and would be more consistent with the behavior of “tasks/”, but perhaps there is a specific reason this was not implemented from the get-go.

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan2](https://avatars.discourse-cdn.com/v4/letter/m/da6949/32.png) [@Michael\_DeHaan2](https://forum.ansible.com/u/Michael_DeHaan2)\
**Post date:** [January 21, 2014, 6:43pm UTC](https://forum.ansible.com/t/include-files-for-role-variables/14368/11 "2014-01-21T18:43:21Z")

</div>

"The ability to include variable files via the main in the “vars/” directory of a role seems it would be an improvement, "

It wouldn’t, and it provides a bit too much of a “more than seven ways to do this” kind of thing.

If something in variables is defining a block of variables, having an “include” in the middle of the data means you’re now defining a way that a datastructure can reference other data structures by naming specific files that they are in, and how do you distinguish a valid datastructure with a key named “include:” versus the desire to include?

It muddles semantics.

include\_vars is going to be the way we are going to do this for multiple files.

---

<div class="post-metadata">

**Author:** ![Brian\_Coca1](https://avatars.discourse-cdn.com/v4/letter/b/278dde/32.png) [@Brian\_Coca1](https://forum.ansible.com/u/Brian_Coca1)\
**Post date:** [January 21, 2014, 6:43pm UTC](https://forum.ansible.com/t/include-files-for-role-variables/14368/12 "2014-01-21T18:43:43Z")

</div>

vars files are pure YAML, there is no inclusion mechanism in YAML which is what parses these files.

playbooks or tasks/main.yml are YAML files in ‘ansible format’ and are parsed by ansible, which has include directives.

---

<div class="post-metadata">

**Author:** ![Albion\_Baucom](https://avatars.discourse-cdn.com/v4/letter/a/838e76/32.png) [@Albion\_Baucom](https://forum.ansible.com/u/Albion_Baucom)\
**Post date:** [January 21, 2014, 6:53pm UTC](https://forum.ansible.com/t/include-files-for-role-variables/14368/13 "2014-01-21T18:53:15Z")

</div>

Then help me understand how this is any different than includes in a main task file?

There could be a block of tasks, with an include in the middle. Also that means the behavior is inconsistent across the role sub-systems. What did I do when I wanted to break out variables and organize them logically in my vars/main.yml? I followed the logic in tasks/main.yml to break out tasks.

Its fine. As this thread is demonstrating, there are already a number of ways to do this. From a user perspective what I suggested makes sense to me, but perhaps I should fall in-line with semantics.

---

<div class="post-metadata">

**Author:** ![Albion\_Baucom](https://avatars.discourse-cdn.com/v4/letter/a/838e76/32.png) [@Albion\_Baucom](https://forum.ansible.com/u/Albion_Baucom)\
**Post date:** [January 21, 2014, 6:56pm UTC](https://forum.ansible.com/t/include-files-for-role-variables/14368/14 "2014-01-21T18:56:35Z")

</div>

OK, well this makes more sense from an implementation perspective.

I was under the impression that Ansible was using pure YAML throughout, but shows how well I understand the language currently 🙂

---

<div class="post-metadata">

**Author:** ![Brian\_Coca1](https://avatars.discourse-cdn.com/v4/letter/b/278dde/32.png) [@Brian\_Coca1](https://forum.ansible.com/u/Brian_Coca1)\
**Post date:** [January 21, 2014, 8:26pm UTC](https://forum.ansible.com/t/include-files-for-role-variables/14368/15 "2014-01-21T20:26:49Z")

</div>

ansible playbook/task files ARE YAML, but they get processed a 2nd time with the ansible engine, vars/files do not, they only get processed by YAML, they were just meant to be static data files.
