Skip to content

Commit 5453055

Browse files
author
Lukas Burkhard
committed
initial commit
1 parent d7ec50f commit 5453055

File tree

7 files changed

+174
-1
lines changed

7 files changed

+174
-1
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
docs/inventory/
2+
.fact_cache/

README.md

+30-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,31 @@
11
# ansible-inventory-docs
2-
Example of how to use ansible facts to create an overwiew of managed hosts
2+
3+
Example of how to use ansible facts to create an overwiew of managed hosts.
4+
5+
## How-To
6+
7+
Ansible is capable of handling different inventories. The example here uses a default inventory as defined in `ansible.cfg`
8+
using the yaml notation. In this example, `localhost` is assigned to the group *desktops* as an example.
9+
Run the playbook and see what happens:
10+
11+
ansible-playbook inventory_docs.yml
12+
13+
An overview `index.md` with a table of all hosts for the inventory is created as well as a `localhost.md` with all the
14+
details that are available in the facts using a code block for every entry.
15+
16+
Using another inventory is supported and will create another subfolder.
17+
18+
ansible-playbook -i inventories/other.yml inventory_docs.yml
19+
20+
If you are new to ansible, there are a few techniques and features contained in this example:
21+
22+
## Jinja Templates
23+
24+
- usage of a macro to render a value from the facts
25+
- An example of how to access a nested value, e.g. `facts.date_time.tz` using a string notation `date_time.tz`.
26+
- Controlling indentation in template blocks using `-` in order to render table in markdown correctly
27+
- Intermediate variable definitions in templates using `{% set variable=.... %}`
28+
29+
## Yaml-Syntax
30+
31+
- Re-use of static expressions (`docs_folder: &folder "docs/inventory"`)

ansible.cfg

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
[defaults]
2+
inventory=./inventories/hosts.example.yml
3+
log_path=logs/ansible.log
4+
gathering = smart
5+
fact_caching = jsonfile
6+
fact_caching_connection = .fact_cache/
7+
fact_caching_timeout = 86400
8+
remote_tmp = .ansible/tmp
9+
local_tmp = .ansible/tmp
10+
enable_task_debugger = False
11+
interpreter_python = auto_silent
12+
ansible_python_interpreter=/usr/bin/python3
13+
ansible_user = root
14+
15+
;[ssh_connection]
16+
;pipelining = True

inventories/hosts.example.yml

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
---
2+
all:
3+
hosts:
4+
localhost:
5+
ansible_connection: local
6+
7+
children:
8+
desktops:
9+
hosts:
10+
localhost:

inventory_docs.yml

+77
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
- hosts: all
2+
gather_facts: true
3+
vars:
4+
docs_folder: &folder "docs/inventory"
5+
6+
inventory_fn: "{{ inventory_file | basename }}"
7+
inventory_name: "{{ inventory_fn.split('.') | first }}"
8+
9+
inventory_docs: "{{ docs_folder }}/{{ inventory_name }}"
10+
tasks:
11+
- name: ensure directory for inventory {{ inventory_fn }}
12+
file:
13+
path: "{{ inventory_docs }}"
14+
state: directory
15+
delegate_to: 127.0.0.1
16+
17+
- name: render the details
18+
template:
19+
src: "host_detail.md.j2"
20+
dest: "{{ fp }}"
21+
delegate_to: 127.0.0.1
22+
vars:
23+
fp: "{{ inventory_docs }}/{{ inventory_hostname }}.md"
24+
25+
- hosts: localhost
26+
gather_facts: false
27+
vars:
28+
docs_folder: *folder
29+
30+
inventory_fn: "{{ inventory_file | basename }}"
31+
inventory_name: "{{ inventory_fn.split('.') | first }}"
32+
inventory_docs: "{{ docs_folder }}/{{ inventory_name }}"
33+
outfile: "{{ inventory_docs }}/index.md"
34+
35+
filter_group: all
36+
all_hosts: "{{ groups[filter_group] | default('all') }}"
37+
38+
table_fields: &used_fields
39+
- system_vendor
40+
- processor_cores
41+
- memory_mb.swap.total
42+
- memtotal_mb
43+
- memfree_mb
44+
- distribution
45+
- architecture
46+
- bios_date
47+
48+
# Modify the labels of supp
49+
custom_labels:
50+
memtotal_mb: RAM [mb]
51+
distribution: Distro
52+
53+
# Add more to your liking, dotted notation is possible
54+
labels:
55+
architecture: ARCH
56+
bios_date: BIOS DATE
57+
bios_vendor: BIOS VENDOR
58+
board_vendor: BOARD VENDOR
59+
distribution: OS DISTRIBUTION
60+
memfree_mb: RAM FREE
61+
memory_mb.swap.total: SWAP
62+
memtotal_mb: RAM
63+
os_family: OS FAMILY
64+
processor_cores: CPU CORES
65+
processor_count: CPU COUNT
66+
processor_vcpus: VCPUS
67+
product_name: PRODUCT NAME
68+
product_serial: PRODUCT SERIAL
69+
product_version: PRODUCT VERSION
70+
system: SYSTEM
71+
system_vendor: VENDOR
72+
73+
tasks:
74+
- name: render the overview to {{ outfile }}
75+
template:
76+
src: "ansible_host_overview.md.j2"
77+
dest: "{{ outfile }}"

templates/ansible_host_overview.md.j2

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
---
2+
{% macro get_val(facts, key) %}
3+
{%- if facts -%}
4+
{%- if not '.' in key -%}
5+
{{ facts[key] | default('n.a.') }} |
6+
{%- else -%}
7+
{% set attrs = key.split('.') %}
8+
{{ [attrs[0]] | map('extract', facts, attrs[1:]) | first }} |
9+
{%- endif -%}
10+
{%- else -%} - |{%- endif %}
11+
{% endmacro -%}
12+
13+
# Ansible Host Overview
14+
15+
**Inventory**: {{ inventory_fn }}
16+
17+
{% set all_fields = ['NAME'] | union(table_fields) %}
18+
| {%- for field in all_fields %} {{ custom_labels[field] | default(labels[field] | default(field)) }} |
19+
{%- endfor %}
20+
21+
|{% for field in all_fields %} {{ '-' * labels[field] | default(field) | length }} |{%- endfor %}
22+
23+
{% for hostname in all_hosts %}
24+
{% set host_facts = hostvars[hostname]['ansible_facts'] %}
25+
| **{{ hostname }}** | {% for key in table_fields %} {{ get_val(host_facts, key) }}{% endfor %}
26+
27+
{% endfor %}

templates/host_detail.md.j2

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
---
2+
3+
## Details for *{{ inventory_hostname }}*
4+
5+
**Inventory Groups**: {{ group_names | join(', ') }}
6+
7+
{% for section, value in ansible_facts.items() %}
8+
### {{ section.split('_') | map('capitalize') | join(' ') }}
9+
```
10+
{{ value | to_nice_json }}
11+
```
12+
{% endfor %}

0 commit comments

Comments
 (0)