Accessing Variables within Inventory Vars using Jinja2

6,443 views
Skip to first unread message

Adam Keech

unread,
May 16, 2014, 3:09:43 PM5/16/14
to ansible...@googlegroups.com
I have been having a really tough time trying to use variables that are defined within an Inventory file.

For Example:

Inventory File:

[WebApp_Login]
server1
server2
server3

[WebApp_Login:vars]
route=login

[WebApp_Sweetness]
server2

[WebApp_Sweetness:vars]
route=sweetness

[WebApp_ReallyAwesomeSweetness]
server3

[WebApp_ReallyAwesomeSweetness:vars]
route=reallyawesomesweetness

J2 Template:

<Services description="XML Representation of AD Deployment Groups">
{% for service_name in groups|sort %}
  <Service id="{{ service_name }}" route=" THIS IS WHAT I NEED TO FILL IN WITH ROUTE VARIABLE ">
{% for host in groups[service_name]|sort %}
    <Machine>{{ host }}</Machine>
{% endfor %}
  </Service>
{% endfor %}
</Services>

I need to fill in the part that is bolded in the J2 Template.  Any help would be greatly appreciated.  I feel like there should be something called "groupvars" to be able to access, but there doesn't appear to be.

Thank You!

Matt Martz

unread,
May 16, 2014, 3:41:09 PM5/16/14
to ansible...@googlegroups.com, Adam Keech
groupvars are applied directly to the hosts that reside within that group.

So you should just be able to use {{route}} as long as the server resides within a group that contains the "route" variable.

-- 
Matt Martz
ma...@sivel.net
--
You received this message because you are subscribed to the Google Groups "Ansible Project" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ansible-proje...@googlegroups.com.
To post to this group, send email to ansible...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ansible-project/d236d7ac-1017-4c20-8a29-144195fe6300%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Brian Coca

unread,
May 16, 2014, 3:41:11 PM5/16/14
to ansible...@googlegroups.com
the problem is that group_vars are not 'by group' when you access them, they are collapsed into host. This should give you what you want.

route={{hostvars[groups[service_name][0]].route}} 

^ might need to ensure all {} and [] match



--
Brian Coca
Stultorum infinitus est numerus
0110000101110010011001010110111000100111011101000010000001111001011011110111010100100000011100110110110101100001011100100111010000100001
Pedo mellon a minno

Brian Coca

unread,
May 16, 2014, 3:43:59 PM5/16/14
to ansible...@googlegroups.com
I should explain what the monster in my previous answer does:

hostvars[ <hostname> ].<varname> <= gives you access to the variable (varname) for a  'non current host' (hostname), otherwise you could just use <varname>.

groups[service_name][0] <== this retrieves the first hostname from the current groupname in the service_name variable.

compose both and your template 'should' work

Adam Keech

unread,
May 16, 2014, 3:48:07 PM5/16/14
to ansible...@googlegroups.com
Thanks a lot for the explanation.  I will give it a try!

Adam Keech

unread,
May 16, 2014, 3:52:35 PM5/16/14
to ansible...@googlegroups.com
I changed my template to:

<Services description="XML Representation of AD Deployment Groups">
{% for service_name in groups|sort %}
{% if service_name not in ['all', 'ungrouped'] %}
{% if hostvars[groups[service_name][0]].route  %}
  <Service id="{{ service_name }}" route="{{ hostvars[groups[service_name][0]].route }}">
{% else %}
  <Service id="{{ service_name }}">
{% endif %}
{% for host in groups[service_name]|sort %}
    <Machine>{{ host }}</Machine>
{% endfor %}
  </Service>
{% endif %}
{% endfor %}
</Services>

The idea is to have a route next to id in the xml it's generating if it has a route, otherwise, do not add a route to the xml.

I get an odd error back stating:
[localhost] => {'msg': 'host not found: ', 'failed': True}

Keep in mind, my hosts I am running this against is localhost.  The idea behind this playbook is to just generate an xml file via the services inventory file.
Message has been deleted

Adam Keech

unread,
May 16, 2014, 4:00:42 PM5/16/14
to ansible...@googlegroups.com
Adding [0] after the groups[service_name] command is what is causing it to blow up.

Adam Keech

unread,
May 16, 2014, 4:05:34 PM5/16/14
to ansible...@googlegroups.com
I figured out what was wrong.  Some of my groups did not have servers.

It now runs, but everything in the generated xml has the same route.  I will continue working on this, but the help so far was huge.  Much further than I was before.

Brian Coca

unread,
May 16, 2014, 4:13:16 PM5/16/14
to ansible...@googlegroups.com
removing the [0] should return a list, not a single host, see if this is a bit cleaner

{% for service_name in groups|sort|difference(['all', 'ungrouped']) %}
{% set first_host = groups[service_name][0] %}
{% if 'route' in  hostvars[first_host] %}
 <Service id="{{ service_name }}" route="{{ hostvars[first_host].route }}">

this also assumes that the first host in the group has the correct route var (it can be overridden by individual hosts)

Adam Keech

unread,
May 16, 2014, 4:28:25 PM5/16/14
to ansible...@googlegroups.com
Understood.  The issue is all of the groups have the same host.  What seems to be happening is the last route I assign to that host is what is used for all three.  I will have to make the routevariables unique for each and call them all separately.  Maybe something like this:

Inventory:
[WebApp_Login:vars]
WebApp_Login_route=login

[WebApp_number2]
KSQ-B-WEB-D01

[WebApp_number2:vars]
WebApp_number2_route=exposureindexbuilder

[WebApp_number3]
KSQ-B-WEB-D01

[WebApp_number3:vars]
WebApp_number3_route=marketdataadministration

{% for service_name in groups|sort|difference(['all', 'ungrouped']) %}
{% set first_host = groups[service_name][0] %}
{% if 'service_name_route' in  hostvars[first_host] %}
 <Service id="{{ service_name }}" route="{{ hostvars[first_host].service_name_route }}">

This is what I am working on now.  Thanks again for all of your help.

I realize I am doing something out of the ordinary here.  (Not using this inventory file as a typical inventory file.)

Adam Keech

unread,
May 16, 2014, 4:44:14 PM5/16/14
to ansible...@googlegroups.com
This is what I came up with and it's now working great!  Thanks a lot for the help!

{% set route = service_name + "_route" %}
{% if hostvars[groups[service_name][0]][route]  %}
  <Service id="{{ service_name }}" route="{{ hostvars[groups[service_name][0]][route] }}">

Michael DeHaan

unread,
May 16, 2014, 7:28:10 PM5/16/14
to ansible...@googlegroups.com
Good deal!

FYI -- It looks like for each group of hosts in the list "groups" the OP wants to do print some things.   If so, this first outer loop should just be

{% for service_name in group_names|sort %}

Versus "groups" above.   Else service_name isn't a string, it's a list of hosts if you had "groups" instead.







--
You received this message because you are subscribed to the Google Groups "Ansible Project" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ansible-proje...@googlegroups.com.
To post to this group, send email to ansible...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages