Given the tree
shell> tree vars/
vars/
├── as_bgp.yml
└── ip.yml
0 directories, 2 files
shell> cat vars/as_bgp.yml
---
U01:
as_bgp: as1
U02:
as_bgp: as2
shell> cat vars/ip.yml
---
U01:
ip: 1.1.1.1
U02:
ip: 2.2.2.2
The option hash_behaviour: merge works as expected (Ansible 2.12)
- name: iterate over files
include_vars:
file: "{{ item }}"
hash_behaviour: merge
name: my_vars
loop: "{{ query('fileglob', 'vars/*') }}"
vars:
my_vars: {}
gives
my_vars:
U01:
as_bgp: as1
ip: 1.1.1.1
U02:
as_bgp: as2
ip: 2.2.2.2
If the parameter hash_behaviour is not available create the names of the variables from the names of the files, e.g.
- name: iterate over files
include_vars:
file: "{{ item }}"
name: "u_{{ item|basename|splitext|first }}"
loop: "{{ query('fileglob', 'vars/*') }}"
will create the variables
query('varnames', '^u_*'):
- u_as_bgp
- u_ip
In the playbook below, extract the variables, and combine the dictionary my_vars
shell> cat test.yml
- hosts: localhost
vars:
my_vars: "{{ query('varnames', '^u_*')|
map('extract', hostvars[inventory_hostname])|
combine(recursive=True) }}"
tasks:
- name: iterate over files
include_vars:
file: "{{ item }}"
name: "u_{{ item|basename|splitext|first }}"
loop: "{{ query('fileglob', 'vars/*') }}"
gives
my_vars:
U01:
as_bgp: as1
ip: 1.1.1.1
U02:
as_bgp: as2
ip: 2.2.2.2
The template is trivial
shell> cat test.txt.j2
{% for k,v in my_vars.items() %}
{{ v.ip }}
{{ v.as_bgp }}
{% endfor %}
The task below
- template:
src: test.txt.j2
dest: test.txt
will create the file
shell> cat test.txt
1.1.1.1
as1
2.2.2.2
as2
If the option recursive=True of the filter combine is not available merge the dictionaries on your own, e.g the variables below help to get the same result
my_vars: "{{ dict(_keys|zip(_vals)) }}"
_groups: "{{ query('varnames', '^u_*')|
map('extract', hostvars[inventory_hostname])|
map('dict2items')|flatten|
groupby('key') }}"
_keys: "{{ _groups|map('first')|list }}"
_vals: "{{ _groups|map('last')|
map('map', attribute='value')|
map('combine')|list }}"