Using a variable inside a jinja loop

248 views
Skip to first unread message

Claus Strommer

unread,
Jun 24, 2014, 10:48:06 AM6/24/14
to ansible...@googlegroups.com
Hi there,

I have a play with a role that creates a load balancer template.  I've successfully tested it in my dev environment, using


{% for host in groups['dev-web'] %}
    server {{ host }} {{ host }}:80
{% endfor %}


the 'dev-web' group is defined in my inventory, as well as 'stage-web', 'prod-web', etc.  What I'd like to do is change this template so that it can be used in any environment.  I am already passing a parameter upon calling the play,  --extra-vars "deploy_env=dev".  In the play itself I can use this variable to determine on which balancer the template gets applied, by using something like this:


- hosts: [ '{{ deploy_env }}-bal' ]
  serial: 1
  vars_files:
  - /var/lib/ansible/vars/{{ deploy_env }}.yml
  roles:
  - role: "haproxy-webbal"


However, if I try something similar in the template, e.g.


{% for host in groups['{{ deploy_env }}-web'] %}
    server {{ host }} {{ host }}:80
{% endfor %}

I get this error:


fatal: [stage-webbal-06.aws.primal.com] => {'msg': "One or more undefined variables: 'dict object' has no attribute '{{ deploy_env }}-varnish'", 'failed': True}


It seems that {{ deploy_env }} is not being expanded, and it's being taken as a literal.  Is this because it's within the {% %} section?  If so, then what is the correct syntax for doing this?  Alternatively, is there a cleaner way to approach this?



Michael Peters

unread,
Jun 24, 2014, 11:05:12 AM6/24/14
to ansible...@googlegroups.com
When inside the {% %} part you are inside of jinja and don't need
special syntax to tell it that your using jinja variables. Something
like this should work:

{% for host in groups[deploy_env + '-web'] %}
server {{ host }} {{ host }}:80
{% endfor %}

> --
> 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/CABkDv%2B5o4bLiUiNgr-UxP9P8hWpe0SxkhPvhb-T25VrErrMvkw%40mail.gmail.com.
> For more options, visit https://groups.google.com/d/optout.

Petros Moisiadis

unread,
Jun 24, 2014, 11:11:25 AM6/24/14
to ansible...@googlegroups.com
Access your var inside the "{% %}" block without a "{{ }}" surrounding and use string concatenation like this:

{% for host in groups[deploy_env + '-web'] %}

    server {{ host }} {{ host }}:80
{% endfor %}


Claus Strommer

unread,
Jun 24, 2014, 11:13:32 AM6/24/14
to ansible...@googlegroups.com
d'oh!  I should have known that.  Thanks a bunch!


Michael DeHaan

unread,
Jun 24, 2014, 12:09:01 PM6/24/14
to ansible...@googlegroups.com
"
- hosts: [ '{{ deploy_env }}-bal' ]
"

This is gross and I would recommend not doing this.

Instead consider seperating your different environments into different inventory files (-i production), and having the host group just named "bal" in this case.  You can still put nodes in different groups and keep your group_vars/ and host_vars/ directories all together.




Claus Strommer

unread,
Jun 25, 2014, 2:05:49 PM6/25/14
to ansible...@googlegroups.com
I like that idea.

<rant>
Right now we're in a transition phase because I've inherited a horrible Puppet configuration that does unspeakably stupid/evil things.  I actually have a rudimentary inventory script that polls puppetdb - eventually I'll put that monstrosity to rest, but for now it's convenient.  Right now I still need to pass in the deploy_env variable because some configurations require it and I haven't gotten around to having the inventory script define them, but once that's in place I'll definitively go with your suggestion and make environment-specific inventories. 
</rant>


Reply all
Reply to author
Forward
0 new messages