Creation of dict on the fly

I have to create a haproxy config file with data from an unknown number of backend servers. The number is unknown, because based on the environment I need to run the playbook in, the number of backend servers could be 1 to several. My backend servers in haproxy.cfg need to defined something like this:

backend backend_nodes
description Web Servers
balance roundrobin
server web01 10.0.2.1:8080 check
server web02 10.0.2.3:8080 check
server web03 10.0.2.3:8080 check

So on any given run of the playbook, I need to define the dict ‘backend_servers’ for X items (to generate the server lines above):

  • name: <server_name>
    ip: <server_IP>
    port: <http_port>
    params:

With that block repeated for every server in groups[‘web_servers’]. I tried using set_facts, but that can’t define dict types. I have to do this as a dict, because different inventories will have different numbers of hosts in groups[‘web_servers’], and I can’t hard-code this into my playbook or template, because the playbook will be used to configure different haproxy roles with different parameters, so this role needs to remain generic.

I wonder if there might be a simpler way to approach this, but you could use a trick I have used a couple of times and use a template to generate a yaml data structure. Something like:

backend_servers.j2:

I like your yaml template idea, but I did end up pushing the logic off into my backend.cfg.j2 template:

{% for server in groups[‘web_servers’] %}
server {{ server }} {{ hostvars[server].ansible_fqdn }}:{{ hostvars[server].http_port }} params
{% endfor %}

This is based off my current model where role ‘haproxy/common’ handles the global and default settings and role ‘haproxy/web_servers’ handles backend, frontend and listen settings. This should suffice going forward as long as other uses of haproxy get their own ‘haproxy/other_backend’ roles.