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:
---
{% for x in groups['web_servers'] %}
- name: {{ x }}
ip: {{ hostvars[x]['ansible_eth0']['ipv4']['address'] }}
port: 8080
params: blargh
{% endfor %}
Now, you can load this in the playbook like this:
- name: set the fact
set_fact:
backend_servers: "{{ lookup('template', 'backend_servers.j2')|from_yaml }}"
(Note that you need to use the "complex arguments" form and not the "set_fact: key=value" form, otherwise you will end up with a string and not a dict.)
This seems a little convoluted to me--and I don't fully understand why you couldn't simply template the haproxy.cfg file and just push the logic for the servers into the template, but I've used this pattern a couple of times when a simpler solution was not available.
-Tim