cfad67a3a1c14182dc4338997e9e4631fef746af
Remove static hosts.yml inventory file and configure pure dynamic inventory discovery using community.libvirt.libvirt plugin. Changes: 1. Removed Static Inventory: - Deleted inventories/development/hosts.yml - All host definitions now come from libvirt dynamic discovery - Complies with CLAUDE.md requirement for dynamic inventories 2. Updated libvirt_kvm.yml Dynamic Inventory: - Changed URI from local to remote: qemu+ssh://grok@grok.home.serneels.xyz/system - Configures automatic VM discovery from grokbox hypervisor - Creates dynamic groups: kvm_guests, running_vms, small_vms, large_vms - Creates keyed groups by state and OS - Extracts IP addresses from guest_info 3. Created Host Variables Override: - inventories/development/host_vars/pihole.yml - inventories/development/host_vars/mymx.yml - inventories/development/host_vars/derp.yml - Override ansible_connection from libvirt_qemu to ssh - Set ansible_host to IP addresses (192.168.122.x) 4. Updated Group Variables: - inventories/development/group_vars/kvm_guests.yml - Added ansible_connection: ssh to force SSH over libvirt - Maintains ProxyJump configuration through grokbox - SSH connection multiplexing settings preserved 5. Added .gitignore: - Exclude stats/ directory from version control - Prevents system_info role output from being committed Dynamic Inventory Discovery: - Automatically discovers VMs: pihole, mymx, derp - Groups by state: running_vms, stopped_vms - Groups by size: small_vms (≤2GB), medium_vms (2-8GB), large_vms (>8GB) - Groups by OS: os_debian, os_unknown - Creates UUID-based groups for unique identification Connection Method: - Discovery: libvirt plugin queries grokbox via SSH - Execution: SSH with ProxyJump through grokbox - Authentication: SSH keys (ansible user) - Network: Private 192.168.122.0/24 via NAT Testing Results: ✅ Dynamic inventory discovers all 3 VMs ✅ Groups created correctly (kvm_guests, running_vms, etc.) ✅ pihole: Connection successful via ProxyJump ⚠️ mymx, derp: SSH key authentication needed (not inventory issue) Benefits: - No manual inventory maintenance required - VMs automatically added/removed based on libvirt state - Dynamic grouping by resource allocation - Centralized management through grokbox - CLAUDE.md compliant (no static inventories in production-like envs) Usage: # List all discovered VMs ansible-inventory -i inventories/development/ --graph # Ping all KVM guests ansible -i inventories/development/ kvm_guests -m ping # Run playbook on running VMs ansible-playbook -i inventories/development/ site.yml --limit running_vms Migration Note: The static inventory (hosts.yml) contained some hosts not managed by libvirt (odin, seed). These external hosts need to be managed via separate dynamic inventory sources or added back if required. Related Documentation: - docs/network-access-patterns.md (ProxyJump configuration) - inventories/production/README.md (dynamic inventory examples) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Ansible Infrastructure Automation
Enterprise-grade Ansible infrastructure with security-first principles, modularity, and scalability.
Quick Start
# Test connectivity with SSH config inventory
ansible all -i plugins/inventory/ssh_config_inventory.py -m ping
# Test connectivity with Libvirt dynamic inventory
ansible running_vms -i plugins/inventory/libvirt_kvm.py -m ping
# Use static development inventory
ansible all -i inventories/development/hosts.yml -m ping
# Run a playbook
ansible-playbook -i inventories/development/hosts.yml site.yml
Project Structure
.
├── README.md # This file
├── CLAUDE.md # Development guidelines and standards
├── ansible.cfg # Ansible configuration
├── site.yml # Master playbook
│
├── inventories/ # Inventory configurations
│ ├── production/ # Production (dynamic only)
│ ├── staging/ # Staging (dynamic only)
│ └── development/ # Development environment
│ ├── hosts.yml # Static inventory
│ ├── libvirt_kvm.yml # Libvirt config
│ └── group_vars/ # Group variables
│ ├── all.yml
│ ├── kvm_guests.yml
│ └── hypervisors.yml
│
├── plugins/ # Custom plugins
│ └── inventory/ # Dynamic inventory scripts
│ ├── ssh_config_inventory.py # SSH config parser
│ └── libvirt_kvm.py # Libvirt/KVM discovery
│
├── roles/ # Ansible roles
├── playbooks/ # Playbooks
├── collections/ # Ansible collections
│
├── docs/ # Documentation
│ ├── inventory.md # Inventory documentation
│ └── [other docs]
│
└── cheatsheets/ # Quick reference guides
└── inventory.md # Inventory cheatsheet
Infrastructure Overview
Current Environment
| Component | Type | Description |
|---|---|---|
| odin | External VPS | Mail server (Debian 13) |
| grokbox | Hypervisor | KVM/libvirt host (physical) |
| pihole | VM Guest | DNS/DHCP server (via grokbox) |
| mymx | VM Guest | Mail server (via grokbox) |
| derp | VM Guest | Development VM (via grokbox) |
| seed | VM Guest | Discovery pending |
Network Architecture
Internet
│
├─── odin (65.108.217.156) ─────────── External VPS
│
└─── grokbox (grok.home.serneels.xyz)
│
└─── virbr0 (192.168.122.0/24) ── NAT Network
│
├─── pihole (192.168.122.12)
├─── mymx (192.168.122.119)
├─── derp (192.168.122.99)
└─── seed (192.168.129.1)
Available Inventory Solutions
1. SSH Config Parser (Dynamic)
Best for: Quick discovery from existing SSH configuration
ansible all -i plugins/inventory/ssh_config_inventory.py --list-hosts
2. Libvirt/KVM Dynamic Inventory
Best for: Real-time VM discovery with state and resource information
ansible running_vms -i plugins/inventory/libvirt_kvm.py -m ping
3. Static YAML Inventory (Development)
Best for: Detailed host metadata and development environments
ansible all -i inventories/development/hosts.yml --list-hosts
Key Features
Security-First Design
- SELinux/AppArmor enforcement
- Automated security updates
- SSH hardening (key-based auth, no root login)
- File integrity monitoring (AIDE)
- System auditing (auditd)
- Secrets management with Ansible Vault
Scalability
- Dynamic inventory for infrastructure discovery
- Fact caching for performance
- Parallel execution with configurable forks
- ProxyJump for nested VM access
- Efficient SSH connection reuse
Modularity & Reusability
- Role-based architecture
- OS-agnostic design (Debian/RHEL families)
- Comprehensive variable management
- Task tagging for selective execution
- Molecule testing framework
Documentation
| Document | Description |
|---|---|
| CLAUDE.md | Complete development guidelines and standards |
| docs/inventory.md | Inventory configuration and usage |
| cheatsheets/inventory.md | Quick reference guide |
Requirements
Control Node
- Python 3.6+
- Ansible 2.10+
- SSH client with ProxyJump support
Managed Nodes
- Python 3.x
- SSH server
ansibleuser with passwordless sudo
Optional Dependencies
# For libvirt dynamic inventory
apt-get install python3-libvirt # Debian/Ubuntu
dnf install python3-libvirt # RHEL/Rocky/Fedora
Configuration
ansible.cfg Example
[defaults]
inventory = ./inventories/development/hosts.yml
roles_path = ./roles
collections_path = ./collections
remote_user = ansible
become = True
become_method = sudo
# Performance
forks = 20
gathering = smart
fact_caching = jsonfile
fact_caching_connection = /tmp/ansible_facts
fact_caching_timeout = 86400
# SSH
host_key_checking = False
ssh_args = -o ControlMaster=auto -o ControlPersist=600s
[inventory]
enable_plugins = yaml, ini, script, auto
[privilege_escalation]
become = True
become_method = sudo
become_user = root
become_ask_pass = False
Common Tasks
Test Connectivity
# All hosts
ansible all -i <inventory> -m ping
# Specific group
ansible kvm_guests -i <inventory> -m ping
# With verbose output
ansible all -i <inventory> -m ping -vvv
Gather Facts
ansible all -i <inventory> -m setup
Run Ad-Hoc Commands
# Check uptime
ansible all -i <inventory> -m shell -a "uptime"
# Check disk usage
ansible all -i <inventory> -m shell -a "df -h"
# List running VMs on hypervisor
ansible hypervisors -i <inventory> -m shell -a "virsh list --all"
Execute Playbooks
# Full run
ansible-playbook -i <inventory> site.yml
# Check mode (dry-run)
ansible-playbook -i <inventory> site.yml --check
# Limit to group
ansible-playbook -i <inventory> site.yml --limit kvm_guests
# With tags
ansible-playbook -i <inventory> site.yml --tags "install,configure"
Development Guidelines
Please refer to CLAUDE.md for complete development guidelines including:
- Security requirements
- Role development standards
- Testing procedures
- Documentation requirements
- LVM partitioning schema
- Package management
- And much more...
Troubleshooting
Connection Issues
# Test SSH connectivity
ssh -J grokbox ansible@192.168.122.12
# Test with verbose Ansible
ansible pihole -i <inventory> -m ping -vvv
# Check SSH config
cat ~/.ssh/config
Inventory Issues
# Validate inventory
ansible-inventory -i <inventory> --list
# Check specific host
ansible-inventory -i <inventory> --host <hostname>
# Graph structure
ansible-inventory -i <inventory> --graph
Python/Libvirt Issues
# Check Python version
ansible all -i <inventory> -m setup -a "filter=ansible_python_version"
# Install libvirt support
apt-get install python3-libvirt # Debian/Ubuntu
dnf install python3-libvirt # RHEL/Rocky
# Test libvirt connection
virsh -c qemu+ssh://grok@grok.home.serneels.xyz/system list
Contributing
- Follow guidelines in CLAUDE.md
- Use feature branches for development
- Test roles with Molecule
- Update documentation
- Create pull request for review
Security
- Never commit secrets to version control
- Use Ansible Vault for sensitive data
- Rotate SSH keys every 90-180 days
- Regular security audits with Lynis/OpenSCAP
- Keep systems updated with automatic security patches
Support
- Documentation: docs/
- Cheatsheets: cheatsheets/
- Guidelines: CLAUDE.md
Project Version: 1.0.0 Last Updated: 2025-11-10 Maintainer: Ansible Infrastructure Team
Description
Languages
Jinja
57.7%
Python
39.5%
Shell
2.8%