# How do variables really work?

**URL:** <https://forum.ansible.com/t/how-do-variables-really-work/13180>\
**Category:** Ansible Project\
**Created:** [July 23, 2013, 8:41pm UTC](https://forum.ansible.com/t/how-do-variables-really-work/13180 "2013-07-23T20:41:51Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![David\_Reagan](https://avatars.discourse-cdn.com/v4/letter/d/71e660/32.png) [@David\_Reagan](https://forum.ansible.com/u/David_Reagan)\
**Post date:** [July 23, 2013, 8:41pm UTC](https://forum.ansible.com/t/how-do-variables-really-work/13180/1 "2013-07-23T20:41:51Z")

</div>

I’ve read the docs, several topics in this group, the examples github, plus several experiments on some testing vms, but I can’t seem to make it click.

The precedence vars take is this: (I think…)

1. vars passed in from the commandline
2. vars directly in the playbook
3. vars in host\_vars/hostname
4. vars in group\_vars/group
5. vars in roles/rolename/vars (how does this work with more than one role defining a var?)
6. vars in group\_vars/all

I also have been having issues referencing vars. I thought you could do use ${var}, {{ var }}, or $var (see: [http://www.ansibleworks.com/docs/playbooks.html#vars-section](http://www.ansibleworks.com/docs/playbooks.html#vars-section)), but when I do something like:

> template: src=blah.j2 dest=/etc/blah/{{ var }}

It creates a file named {{ var }} rather than what the variable is supposed to be. Same if I used ${var}

I also have a task in a role that I want to run only if the host has the correct variable defined. As in host\_vars/alpha.blah.org has ‘vhost’ defined, but host\_vars/beta.blah.org does not. So the task would run for [alpha.blah.org](http://alpha.blah.org), but not for [beta.blah.org](http://beta.blah.org). I tried:

> - name: blah  
> template: src=blah dest=blah  
> when: vhost is defined

where only host\_vars/alpha.blah.org had vhost defined. The result was no tasks were run for [alpha.blah.org](http://alpha.blah.org), but the other two hosts I’m testing on had tasks run…

I guess I need these questions answered:

1. What do I have wrong in what I wrote above?

2. How do I correctly reference vars?

3. How do I make sure var files are loaded correctly?

4. As in vars for [alpha.blah.org](http://alpha.blah.org) are only used for [alpha.blah.org](http://alpha.blah.org), vars for [beta.blah.org](http://beta.blah.org) are only used for [beta.blah.org](http://beta.blah.org), and so on.1. How do I run tasks only when the correct variable is defined?

The way I’ve been testing this, is by trying to create apache vhost files. Here are what I think are the relevant files:

> * * *
> 
> # file: roles/webtier/tasks/main.yml
> 
> - include: php-apache-stack.yml
> - include: apache2-vhosts.yml

> * * *
> 
> # file: roles/webtier/tasks/apache2-vhosts.yml
> 
> - name: create and enable vhosts  
> when: apache2\_vhosts is defined  
> template: src=http-vhost.j2 dest=/etc/apache2/sites-available/${item.server\_name}  
> with\_items:
> - apache2\_vhosts  
> notify:
> - restart apache2

> * * *
> 
> # file: host\_vars/vm.blankalpha.lab
> 
> testvars:
> 
> - test1: “THis is a test with bad grammar.”  
> test2: “TEST TWO”
> 
> apache2\_vhosts:
> 
> - server\_name: vm.blankalpha.lab  
> server\_admin: [webservices@blah.org](mailto:webservices@blah.org)  
> server\_aliases: done.blankalpha.lab  
> docroot: /var/www/

When I did not have the when condition, it created a file named /etc/apache2/sites-available/${item.server\_name} that contained my template, without any values substituted into it.

---

<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:** [July 24, 2013, 1:09am UTC](https://forum.ansible.com/t/how-do-variables-really-work/13180/2 "2013-07-24T01:09:40Z")

</div>

This feels like you may want to stop by IRC.
