Ansible CMDB — Generate Host Inventory Reports

Introduction

ansible-cmdb transforms Ansible fact-gathering output into browsable HTML reports, CSV files, and SQL databases. Instead of running ad-hoc commands to check what's running where, generate a complete inventory report: OS versions, IP addresses, memory, disk, installed packages — all in a searchable web page. It's infrastructure documentation that builds itself.

Installation

# pip install
pip install ansible-cmdb

# Debian/Ubuntu
apt-get install ansible-cmdb

# From source
git clone https://github.com/fboender/ansible-cmdb.git
cd ansible-cmdb
pip install .

# Verify
ansible-cmdb --version

Quick Start

# Step 1: Gather facts from all hosts
ansible -m setup --tree /tmp/facts all

# Step 2: Generate HTML report
ansible-cmdb /tmp/facts > cmdb.html

# Open in browser
xdg-open cmdb.html  # Linux
open cmdb.html       # macOS

That's it — two commands to a complete infrastructure report.

Gather Facts

# All hosts
ansible -m setup --tree /tmp/facts all

# Specific group
ansible -m setup --tree /tmp/facts webservers

# With custom inventory
ansible -i inventory/production -m setup --tree /tmp/facts all

# Limit to specific hosts
ansible -m setup --tree /tmp/facts --limit "web01,web02,db01" all

Each host produces a JSON file in the output directory:

/tmp/facts/
├── web01.example.com
├── web02.example.com
├── db01.example.com
└── lb01.example.com

Output Formats

HTML (Default)

# Full interactive HTML report
ansible-cmdb /tmp/facts > report.html

# With custom columns
ansible-cmdb -c name,os,ip,mem,cpus /tmp/facts > report.html

CSV

# CSV for spreadsheets
ansible-cmdb -t csv /tmp/facts > inventory.csv

# Import into Excel/Google Sheets for analysis

Markdown

# Markdown table
ansible-cmdb -t markdown /tmp/facts > inventory.md

SQL

# SQL INSERT statements
ansible-cmdb -t sql /tmp/facts > inventory.sql

# Import into database
sqlite3 cmdb.db < inventory.sql

JSON

# JSON output
ansible-cmdb -t json /tmp/facts > inventory.json

Custom Columns

# Select specific columns
ansible-cmdb -c name,os,ip,mem,cpus,disk /tmp/facts > report.html

# Available columns:
# name, fqdn, groups, os, ip, mac, arch,
# mem, cpus, disk, virt_type, vcpus,
# kernel, python_version, timestamp

Enrich with Inventory Data

# Include group and variable information
ansible-cmdb -i inventory/production /tmp/facts > report.html

# Multiple inventory sources
ansible-cmdb -i inventory/production -i inventory/staging /tmp/facts > report.html

Automate with Playbook

---
- name: Generate CMDB report
  hosts: all
  gather_facts: true

  tasks:
    - name: Save facts to file
      ansible.builtin.copy:
        content: "{{ ansible_facts | to_nice_json }}"
        dest: "/tmp/facts/{{ inventory_hostname }}"
      delegate_to: localhost

- name: Build report
  hosts: localhost
  connection: local
  gather_facts: false

  tasks:
    - name: Generate HTML report
      ansible.builtin.command:
        cmd: ansible-cmdb /tmp/facts
      register: cmdb_output

    - name: Write report
      ansible.builtin.copy:
        content: "{{ cmdb_output.stdout }}"
        dest: /var/www/html/cmdb/index.html

    - name: Generate CSV
      ansible.builtin.command:
        cmd: ansible-cmdb -t csv /tmp/facts
      register: csv_output

    - name: Write CSV
      ansible.builtin.copy:
        content: "{{ csv_output.stdout }}"
        dest: /var/www/html/cmdb/inventory.csv

Schedule Regular Reports

# Cron job to regenerate weekly
- name: Schedule CMDB generation
  ansible.builtin.cron:
    name: "Generate CMDB report"
    minute: "0"
    hour: "6"
    weekday: "1"
    job: >
      ansible -m setup --tree /tmp/facts all &&
      ansible-cmdb /tmp/facts > /var/www/html/cmdb/index.html
    user: ansible

Custom Templates

# List available templates
ansible-cmdb --templates-list

# Use a specific template
ansible-cmdb -t html_fancy /tmp/facts > report.html
ansible-cmdb -t html_fancy_split /tmp/facts -p /var/www/html/cmdb/

# html_fancy_split creates per-host pages for large inventories

What the Report Shows

SectionData
HostnameFQDN, short name
OSDistribution, version, kernel
HardwareCPUs, memory, architecture
NetworkIP addresses, MAC, interfaces
StorageDisk sizes, mount points
GroupsAnsible inventory groups
VirtualizationType (kvm, docker, physical)
PythonVersion installed
TimestampWhen facts were gathered

Troubleshooting

IssueSolution
"No facts found"Run ansible -m setup --tree /tmp/facts all first
Empty reportCheck /tmp/facts/ has JSON files
Missing hostsHost may be unreachable; check ansible all -m ping
Large inventory slowUse html_fancy_split template for per-host pages
Facts staleRe-run fact gathering; check timestamps in report
Custom facts missingEnsure /etc/ansible/facts.d/ files exist on targets

Alternatives

ToolStrengthvs ansible-cmdb
AWX/AAPFull UI, RBAC, schedulingHeavier; needs infrastructure
Ansible Facts cachingBuilt-in, no extra toolNo report generation
NetboxNetwork-focused CMDBMore complex; separate system
Custom scriptsFully flexibleMore development effort

Best Practices

  1. Schedule weekly regeneration — stale data is worse than no data
  2. Use html_fancy_split for 100+ hosts — single HTML gets heavy
  3. Store facts in git — track infrastructure changes over time
  4. Include inventory data — -i inventory adds group context
  5. Serve via internal web server — make reports accessible to the team
  6. Generate CSV for management — non-technical stakeholders prefer spreadsheets

Conclusion

ansible-cmdb turns your existing Ansible fact-gathering into a self-updating infrastructure database. Two commands — gather facts, generate report — give you a searchable HTML page of every host, its OS, hardware, network, and groups. Schedule it weekly, serve it internally, and your infrastructure documentation stays current without manual effort.