advanced jinja2 templating help - dynamic configuration

Hi all,

I’m starting to play with the Jinja2 templating, specifically generating a load balancer configuration based on public_dns and public_ip information returned by the ec2 module.

I’ve got the following haproxy.cfg.j2:

{% set inst = ec2 %}
global
log 127.0.0.1 local2

chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
maxconn 4000
user haproxy
group haproxy
daemon

stats socket /var/lib/haproxy/stats

defaults
mode http
timeout connect 5000ms
timeout client 50000ms
timeout server 50000ms

#---------------------------------------------------------------------

main frontend which proxys to the backends

#---------------------------------------------------------------------

frontend main *:8888
default_backend console

#---------------------------------------------------------------------

round robin balancing between the various backends

#---------------------------------------------------------------------

backend console
{% for instances in inst %}
server {{ public_dns }} {{ public_ip }}:8888 check
{% endfor %}

server console1 {{ inst.instances[0].public_ip }}:8888 check

server console2 {{ inst.instances[1].public_ip }}:8888 check

server console3 {{ inst.instances[2].public_ip }}:8888 check

I can pick out the items from the instances return by those last 3 lines commented above. However, I’d like this to be dynamic based on the number of instances as a user spins up. Unfortunately this doesn’t work:

{% for instances in inst %}
server {{ public_dns }} {{ public_ip }}:8888 check
{% endfor %}

Am I missing something obvious here? Should it be instances.public_dns and instances.public_ip ?

I’m starting to familiarise myself with Jinja2 template designer but I’m in the early stages :wink:

Thanks for continued help :slight_smile:

A small jinja trick: {{ inst|pprint}} will show you data structure.
That should help narrow down the issue if it is a incorrect key or
scope.

{% for instance in inst.instances %}
server {{ instance.public_dns }} {{ instance.public_ip }}:8888 check
{% endfor %}

Thanks folks.

Neat about pprint, that is VERY handy indeed for debugging.

I didn't know about pprint myself.

You also have {{ foo|to_json }} and {{ foo|to_yaml }}

Developer tech kind of sidenote -- These are made available by "filter
plugins" in Ansible if someone ever wants to add more... but that's a
niche thing and not many people will need to do that.