You can do a simple loop first and then collect the results:
- hosts: all
connection: local
vars:
servers:
- name: foo
port: 1000
- name: bar
port: 2000
tasks:
- set_fact:
result_item: '{{ item.name }}-{{ item.port }}'
with_items:
- '{{ servers }}'
register: result_list
- set_fact:
result: '{{ result_list.results | map(attribute="ansible_facts.result_item") | join(",") }}'
- debug:
var: result
Alternatively try some jinja built-in loops:
- hosts: all
connection: local
vars:
servers:
- name: foo
port: 1000
- name: bar
port: 2000
tasks:
- set_fact:
result: "{% for item in servers %}{{item.name}}-{{item.port}}{{ '' if loop.last else ',' }}{% endfor %}"
- debug:
var: result
This should also work from the template file:
result={% for item in servers %}{{item.name}}-{{item.port}}{{ '' if loop.last else ',' }}{% endfor %}