once again I’m trying to accomplish something with Ansible.
I built a custom dict with variables for each server that looks like this.
- name: Create and Add items to server_list
set_fact:
server_list: "{{ server_list | default({}) | combine ({ item.key : item.value }) }}"
with_items:
- { 'key': 'Servername' , 'value': "{{ ansible_hostname }}"}
- { 'key': 'IP-Adresse' , 'value': "{{ ansible_default_ipv4.address }}"}
- { 'key': 'OS' , 'value': "{{ ansible_os_family }} {{ ansible_distribution_major_version }}"}
- { 'key': 'Plattform' , 'value': "{{ ansible_system }}"}
- name: DEBUG server_list
debug:
var=server_list
That’s working. But now ansible outputs this for every server like this:
ok: [XXX] => {
"server_list": {
"IP-Adresse": "x.x.x.x",
"OS": "Debian 11",
"Plattform": "Linux",
"Servername": "XXX"
}
}
ok: [YYY] => {
"server_list": {
"IP-Adresse": "x.x.x.y",
"OS": "Debian 11",
"Plattform": "Linux",
"Servername": "YYY"
}
}
...
What I want to have now is a complete and "global" dict with every server. I think that would look like this.
Example of what I want as output (here named as server_list_dict
):
{
"server_list_dict": {
"0": {
"Servername": "XXX",
"IP-Adresse": "x.x.x.x",
"OS": "Debian 11",
"Plattform": "Linux"
},
"1": {
"Servername": "YYY",
"IP-Adresse": "x.x.x.y",
"OS": "Debian 11",
"Plattform": "Linux"
}
}
}
Only for clarification for what I want to achieve
What I want to do later is create a html table that should output something like this.
Example html that I want to create:
<table style="width:50%">
<!-- table header -->
<tr>
<th>Servername</th>
<th>IP</th>
<th>OS</th>
<th>Platform</th>
</tr>
<!-- table rows -->
<tr>
<td>Hostname1</td>
<td>X.X.X.X</td>
<td>Debian</td>
<td>Linux</td>
</tr>
<tr>
<td>Hostname2</td>
<td>X.X.X.Y</td>
<td>Debian</td>
<td>Linux</td>
</tr>
</table>
I already have a template to use.
This will go through my "global" dict with every server and use all of the keys and values that are in there. (hopefully, couldnt test it, because idk how to merge my dicts)
<table style="width:100%">
<!-- table header -->
{% if server_list_dict %}
<tr>
{% for key in server_list_dict[0] %}
<th> {{ key }} </th>
{% endfor %}
</tr>
{% endif %}
<!-- table rows -->
{% for dict_item in server_list_dict %}
<tr>
{% for value in dict_item.values() %}
<td> {{ value }} </td>
{% endfor %}
</tr>
{% endfor %}
</table>
Does anybody know how to merge dicts with the same keys in a complete dict? I couldn’t find anything useful. Thanks everyone in advance!
3
Answers
This is since
gather_facts
module – Gathers facts about remote hosts andset_fact
module – Set host variable(s) and fact(s) are running distributed on the Remote Node(s) and the expected behavior.I understand your question that you like to delegate facts first to one of the hosts, the Control Node (Deployment Host or localhost) where you can than create your file or use your template for further distribution. There, all the information would be aggregated in one data structure (dictionary) already.
An other approach might be to use caching facts via cache plugins.
Documentation
Extract the list of the variables server_list
gives
and create the dictionary
gives
The playbook
gives
gives
you could directly use jinja to create your var as expected: