From 5ba666dfbf1d3aa485a10f3d179215205c755333 Mon Sep 17 00:00:00 2001 From: Infrastructure Team Date: Mon, 10 Nov 2025 22:52:11 +0100 Subject: [PATCH] Add quick reference cheatsheets for all playbooks Cheatsheets created: - deploy-debian12-vm.md - Basic Debian 12 deployment reference - deploy-debian-lvm-netinst.md - Network installer with native LVM - deploy-linux-vm.md - Multi-distribution quick reference - deploy-linux-vm-lvm.md - Multi-distro with post-config LVM - deploy-linux-vm-role.md - Role-based deployment guide - test-deploy-linux-vm-role.md - Testing and validation procedures Each cheatsheet includes: - Quick deployment commands - Variable reference tables - Tag-based execution examples - Post-deployment verification steps - LVM management commands (where applicable) - Troubleshooting procedures - Security validation steps - VM management commands --- cheatsheets/deploy-debian-lvm-netinst.md | 380 +++++++++++++++++ cheatsheets/deploy-debian12-vm.md | 286 +++++++++++++ cheatsheets/deploy-linux-vm-lvm.md | 411 +++++++++++++++++++ cheatsheets/deploy-linux-vm-role.md | 287 +++++++++++++ cheatsheets/deploy-linux-vm.md | 502 +++++++++++++++++++++++ cheatsheets/inventory.md | 212 ++++++++++ cheatsheets/test-deploy-linux-vm-role.md | 413 +++++++++++++++++++ 7 files changed, 2491 insertions(+) create mode 100644 cheatsheets/deploy-debian-lvm-netinst.md create mode 100644 cheatsheets/deploy-debian12-vm.md create mode 100644 cheatsheets/deploy-linux-vm-lvm.md create mode 100644 cheatsheets/deploy-linux-vm-role.md create mode 100644 cheatsheets/deploy-linux-vm.md create mode 100644 cheatsheets/inventory.md create mode 100644 cheatsheets/test-deploy-linux-vm-role.md diff --git a/cheatsheets/deploy-debian-lvm-netinst.md b/cheatsheets/deploy-debian-lvm-netinst.md new file mode 100644 index 0000000..509027b --- /dev/null +++ b/cheatsheets/deploy-debian-lvm-netinst.md @@ -0,0 +1,380 @@ +# Deploy Debian with LVM Network Installer - Quick Reference + +## Playbook +`plays/deploy-debian-lvm-netinst.yml` + +## Description +Advanced Debian deployment using network installer (netinst) with full LVM configuration. This playbook creates a VM with proper LVM partitioning per CLAUDE.md requirements using preseed for unattended installation. + +## Quick Deployment + +### Basic Usage +```bash +ansible-playbook plays/deploy-debian-lvm-netinst.yml +``` + +### Custom Configuration +```bash +ansible-playbook plays/deploy-debian-lvm-netinst.yml \ + -e "vm_name=debian-lvm-server" \ + -e "vm_hostname=db-server" \ + -e "vm_vcpus=4" \ + -e "vm_memory_mb=8192" \ + -e "vm_disk_size_gb=100" +``` + +## Variables + +| Variable | Default | Description | +|----------|---------|-------------| +| `vm_name` | debian-lvm-guest | VM name in libvirt | +| `vm_hostname` | debian-lvm | VM hostname | +| `vm_domain` | localdomain | Domain name | +| `vm_vcpus` | 2 | Number of vCPUs | +| `vm_memory_mb` | 4096 | RAM in MB (needs 4GB for installer) | +| `vm_disk_size_gb` | 50 | Disk size in GB | +| `vm_network` | default | Libvirt network | +| `debian_version` | 12 | Debian version (11 or 12) | +| `debian_mirror` | deb.debian.org | Debian mirror URL | + +## LVM Configuration (CLAUDE.md Compliant) + +This playbook creates the following LVM layout: + +``` +Physical Volume: /dev/vda2 +Volume Group: vg_system + +Logical Volumes: +├── lv_root 8G / +├── lv_opt 3G /opt +├── lv_tmp 1G /tmp (noexec,nosuid,nodev) +├── lv_home 2G /home +├── lv_var 5G /var +├── lv_var_log 2G /var/log +├── lv_var_tmp 5G /var/tmp (noexec,nosuid,nodev) +├── lv_var_audit 1G /var/log/audit +└── lv_swap 2G swap + +Separate partition: +└── /dev/vda1 2G /boot (ext4) +``` + +## Tag-Based Execution + +```bash +# Pre-flight checks only +ansible-playbook plays/deploy-debian-lvm-netinst.yml --tags preflight + +# Download netinst ISO only +ansible-playbook plays/deploy-debian-lvm-netinst.yml --tags download + +# Generate preseed configuration only +ansible-playbook plays/deploy-debian-lvm-netinst.yml --tags preseed + +# Deploy VM (assumes ISO downloaded) +ansible-playbook plays/deploy-debian-lvm-netinst.yml --tags deploy + +# Validation only +ansible-playbook plays/deploy-debian-lvm-netinst.yml --tags validate +``` + +### Available Tags +- `preflight` - Pre-flight validation +- `install` - Install required packages +- `download` - Download Debian netinst ISO +- `preseed` - Generate preseed configuration +- `storage` - Create VM disk +- `deploy` - Deploy and start VM +- `validate` - Post-installation validation +- `cleanup` - Remove temporary files + +## Installation Process + +### Timeline +1. **Download ISO**: ~5 minutes (depending on connection) +2. **VM Creation**: ~1 minute +3. **OS Installation**: ~15-20 minutes (unattended) +4. **Total Time**: ~20-25 minutes + +### Monitoring Installation +```bash +# Watch VM console during installation +ssh grokbox "virsh console debian-lvm-guest" + +# Check VM status +ssh grokbox "virsh list --all" + +# Monitor from VNC (if available) +ssh grokbox "virsh vncdisplay debian-lvm-guest" +``` + +## Post-Installation + +### Wait for Completion +The installation is fully unattended. Wait for: +- Playbook to complete (deployment task will wait 20 minutes) +- VM to reboot automatically +- SSH service to become available + +### Get VM Information +```bash +# Get VM IP +ssh grokbox "virsh domifaddr debian-lvm-guest" + +# VM details +ssh grokbox "virsh dominfo debian-lvm-guest" +``` + +### Access VM +```bash +# SSH via ProxyJump +ssh -J grokbox ansible@ + +# Add to ~/.ssh/config +Host debian-lvm + HostName + User ansible + ProxyJump grokbox + StrictHostKeyChecking accept-new +``` + +### Verify LVM Configuration +```bash +# SSH to VM +ssh -J grokbox ansible@ + +# Check physical volumes +sudo pvs + +# Check volume groups +sudo vgs + +# Check logical volumes +sudo lvs + +# Check mounts +df -h +lsblk + +# Verify fstab +cat /etc/fstab +``` + +Expected output: +``` +NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS +vda 252:0 0 50G 0 disk +├─vda1 252:1 0 2G 0 part /boot +└─vda2 252:2 0 48G 0 part + ├─vg_system-lv_root 254:0 0 8G 0 lvm / + ├─vg_system-lv_opt 254:1 0 3G 0 lvm /opt + ├─vg_system-lv_tmp 254:2 0 1G 0 lvm /tmp + ├─vg_system-lv_home 254:3 0 2G 0 lvm /home + ├─vg_system-lv_var 254:4 0 5G 0 lvm /var + ├─vg_system-lv_var_log 254:5 0 2G 0 lvm /var/log + ├─vg_system-lv_var_tmp 254:6 0 5G 0 lvm /var/tmp + ├─vg_system-lv_var_audit 254:7 0 1G 0 lvm /var/log/audit + └─vg_system-lv_swap 254:8 0 2G 0 lvm [SWAP] +``` + +## Security Features + +### Preseed Configuration Includes +- Minimal installation (no desktop environment) +- Automatic partitioning with LVM +- Security hardening: + - SSH server installed + - Root password set (change after deployment!) + - ansible user with sudo access + - SSH key authentication configured + - UFW firewall enabled + - Automatic security updates + +### Post-Installation Security Tasks +```bash +# Change root password +ssh -J grokbox ansible@ +sudo passwd root + +# Verify SSH configuration +sudo cat /etc/ssh/sshd_config | grep -E 'PermitRoot|PasswordAuth' + +# Check firewall +sudo ufw status verbose + +# Verify automatic updates +sudo dpkg -l | grep unattended-upgrades +``` + +## LVM Management + +### Extend Logical Volumes +```bash +# Extend lv_var by 5GB +sudo lvextend -L +5G /dev/vg_system/lv_var +sudo resize2fs /dev/vg_system/lv_var + +# Extend lv_var to use all free space +sudo lvextend -l +100%FREE /dev/vg_system/lv_var +sudo resize2fs /dev/vg_system/lv_var +``` + +### Create New Logical Volumes +```bash +# Create new LV for application data +sudo lvcreate -L 10G -n lv_app_data vg_system +sudo mkfs.ext4 /dev/vg_system/lv_app_data +sudo mkdir -p /opt/appdata +sudo mount /dev/vg_system/lv_app_data /opt/appdata + +# Add to fstab +echo "/dev/vg_system/lv_app_data /opt/appdata ext4 defaults 0 2" | sudo tee -a /etc/fstab +``` + +### LVM Snapshots +```bash +# Create snapshot of lv_root +sudo lvcreate -L 2G -s -n lv_root_snapshot /dev/vg_system/lv_root + +# Mount snapshot +sudo mkdir -p /mnt/snapshot +sudo mount /dev/vg_system/lv_root_snapshot /mnt/snapshot + +# Remove snapshot +sudo umount /mnt/snapshot +sudo lvremove /dev/vg_system/lv_root_snapshot +``` + +## Troubleshooting + +### Installation Hangs +```bash +# Connect to console +ssh grokbox "virsh console debian-lvm-guest" + +# Check VM is running +ssh grokbox "virsh list" + +# Restart VM if needed +ssh grokbox "virsh reboot debian-lvm-guest" +``` + +### No IP After Installation +```bash +# Check DHCP +ssh grokbox "virsh net-dhcp-leases default" + +# Restart network on VM (via console) +ssh grokbox "virsh console debian-lvm-guest" +# Login and run: +sudo systemctl restart networking +``` + +### Preseed Issues +```bash +# Check preseed file syntax +ssh grokbox "debconf-set-selections -c /tmp/preseed.cfg" + +# Re-generate preseed +ansible-playbook plays/deploy-debian-lvm-netinst.yml --tags preseed + +# View generated preseed +ssh grokbox "cat /tmp/preseed-debian-lvm-guest.cfg" +``` + +### LVM Not Configured +If LVM is not properly configured after installation: + +```bash +# Check if LVM packages are installed +ssh ansible@ "dpkg -l | grep lvm2" + +# Check if VG exists +ssh ansible@ "sudo vgs" + +# Manual LVM setup (if needed) +ssh ansible@ "sudo pvcreate /dev/vda2" +ssh ansible@ "sudo vgcreate vg_system /dev/vda2" +``` + +## Advantages Over Cloud Images + +### Why Use Network Installer? +1. **Full LVM Support**: Proper LVM partitioning from installation +2. **CLAUDE.md Compliance**: Meets all partitioning requirements +3. **Flexibility**: Complete control over partitioning +4. **Production Ready**: Standard Debian installation process +5. **Latest Packages**: Always installs latest packages during install + +### Disadvantages +1. **Longer Deployment**: 15-20 minutes vs 2-3 minutes for cloud images +2. **More Complex**: Requires preseed configuration +3. **Network Dependent**: Requires network access during installation + +## VM Management + +### Start/Stop/Restart +```bash +ssh grokbox "virsh start debian-lvm-guest" +ssh grokbox "virsh shutdown debian-lvm-guest" +ssh grokbox "virsh reboot debian-lvm-guest" +ssh grokbox "virsh destroy debian-lvm-guest" # Force stop +``` + +### Delete VM +```bash +ssh grokbox "virsh destroy debian-lvm-guest" +ssh grokbox "virsh undefine debian-lvm-guest --remove-all-storage" +``` + +## Validation Checklist + +After deployment: + +- [ ] VM running: `virsh list | grep debian-lvm` +- [ ] IP assigned: `virsh domifaddr debian-lvm-guest` +- [ ] SSH accessible: `ssh -J grokbox ansible@` +- [ ] LVM configured: `sudo vgs && sudo lvs` +- [ ] All partitions mounted: `df -h` +- [ ] Firewall enabled: `sudo ufw status` +- [ ] Security updates configured: `sudo unattended-upgrades --dry-run` +- [ ] Swap active: `free -h | grep Swap` + +## Important Files + +### On Hypervisor (grokbox) +- Netinst ISO: `/var/lib/libvirt/images/debian-12.0.0-amd64-netinst.iso` +- VM disk: `/var/lib/libvirt/images/debian-lvm-guest.qcow2` +- Preseed config: `/tmp/preseed-debian-lvm-guest.cfg` +- VM config: `/etc/libvirt/qemu/debian-lvm-guest.xml` + +### On Guest VM +- LVM config: `/etc/lvm/lvm.conf` +- Fstab: `/etc/fstab` +- Installed packages: `/var/log/installer/` + +## Comparison with Other Playbooks + +| Feature | deploy-debian12-vm.yml | deploy-debian-lvm-netinst.yml | deploy-linux-vm-role | +|---------|------------------------|-------------------------------|---------------------| +| LVM Support | ❌ No | ✅ Yes (native) | ✅ Yes (post-config) | +| Deployment Time | 2-3 min | 15-20 min | 2-3 min + LVM setup | +| Multi-distro | ❌ No | ❌ No | ✅ Yes | +| CLAUDE.md LVM | ❌ No | ✅ Yes | ✅ Yes | +| Complexity | Low | Medium | High | + +## Related Documentation + +- Playbook: `plays/deploy-debian-lvm-netinst.yml` +- CLAUDE.md: LVM requirements and specifications +- Debian Preseed: https://wiki.debian.org/DebianInstaller/Preseed +- LVM Guide: https://wiki.debian.org/LVM + +## Support + +For issues: +- Check installation logs: `/var/log/installer/` on VM +- Review preseed: `/tmp/preseed-debian-lvm-guest.cfg` on hypervisor +- Monitor console: `virsh console debian-lvm-guest` +- Consult CLAUDE.md for LVM specifications diff --git a/cheatsheets/deploy-debian12-vm.md b/cheatsheets/deploy-debian12-vm.md new file mode 100644 index 0000000..1bf13e9 --- /dev/null +++ b/cheatsheets/deploy-debian12-vm.md @@ -0,0 +1,286 @@ +# Debian 12 VM Deployment Cheatsheet + +## Quick Deployment + +### Basic Deployment +```bash +# Deploy VM with default settings +ansible-playbook plays/deploy-debian12-vm.yml + +# Deploy with custom VM name +ansible-playbook plays/deploy-debian12-vm.yml -e "vm_name=myvm" +``` + +### Custom Configuration +```bash +# Deploy with custom resources +ansible-playbook plays/deploy-debian12-vm.yml \ + -e "vm_name=custom-vm" \ + -e "vm_vcpus=4" \ + -e "vm_memory_mb=4096" \ + -e "vm_disk_size_gb=50" + +# Deploy with custom network +ansible-playbook plays/deploy-debian12-vm.yml \ + -e "vm_name=web-server" \ + -e "vm_network=default" \ + -e "vm_hostname=webserver" \ + -e "vm_domain=example.com" +``` + +## Tag-Based Execution + +### Selective Deployment Steps +```bash +# Pre-flight checks only +ansible-playbook plays/deploy-debian12-vm.yml -t preflight,validate + +# Download image only +ansible-playbook plays/deploy-debian12-vm.yml -t download + +# Verify image checksum +ansible-playbook plays/deploy-debian12-vm.yml -t verify + +# Create storage only +ansible-playbook plays/deploy-debian12-vm.yml -t storage + +# Generate cloud-init config only +ansible-playbook plays/deploy-debian12-vm.yml -t cloud-init + +# Deploy VM (skip download if image exists) +ansible-playbook plays/deploy-debian12-vm.yml -t deploy + +# Validation only +ansible-playbook plays/deploy-debian12-vm.yml -t validate + +# Cleanup temporary files +ansible-playbook plays/deploy-debian12-vm.yml -t cleanup +``` + +### Debug Mode +```bash +# Show console output (use with caution) +ansible-playbook plays/deploy-debian12-vm.yml -t debug +``` + +## Common Variables + +| Variable | Default | Description | +|----------|---------|-------------| +| `vm_name` | debian12-guest | VM name in libvirt | +| `vm_hostname` | debian12 | VM hostname | +| `vm_domain` | localdomain | Domain name | +| `vm_vcpus` | 2 | Number of vCPUs | +| `vm_memory_mb` | 2048 | RAM in MB | +| `vm_disk_size_gb` | 20 | Disk size in GB | +| `vm_network` | default | Libvirt network | +| `vm_bridge` | virbr0 | Bridge interface | +| `ansible_user_ssh_key` | (predefined) | SSH public key for ansible user | + +## Post-Deployment + +### Access the VM +```bash +# Get VM IP address +virsh domifaddr debian12-guest + +# SSH to VM via ProxyJump +ssh -J grokbox ansible@ + +# Direct SSH (from grokbox) +ssh ansible@ +``` + +### VM Management +```bash +# Start VM +virsh start debian12-guest + +# Stop VM +virsh shutdown debian12-guest + +# Force stop VM +virsh destroy debian12-guest + +# Remove VM +virsh undefine debian12-guest --remove-all-storage + +# VM status +virsh dominfo debian12-guest + +# List all VMs +virsh list --all + +# VM console access +virsh console debian12-guest +``` + +### Add to Inventory + +Add the deployed VM to your Ansible inventory: + +```yaml +# inventories/development/hosts.yml +kvm_guests: + children: + development: + hosts: + debian12-guest: + ansible_host: 192.168.122.XX + ansible_user: ansible + ansible_ssh_common_args: '-o ProxyJump=grokbox -o StrictHostKeyChecking=accept-new' + host_description: "Debian 12 Development VM" + host_role: development + vm_vcpus: 2 + vm_memory_mb: 2048 +``` + +## Troubleshooting + +### Check Cloud-Init Status +```bash +# On the VM +cloud-init status +cloud-init status --wait +cloud-init status --long + +# View cloud-init logs +cat /var/log/cloud-init.log +cat /var/log/cloud-init-output.log +``` + +### Network Issues +```bash +# Check VM network interface +virsh domiflist debian12-guest + +# Check VM IP +virsh domifaddr debian12-guest + +# Check network connectivity from grokbox +ping +``` + +### VM Console Access +```bash +# Connect to serial console +virsh console debian12-guest + +# Disconnect: Ctrl + ] +``` + +### Storage Issues +```bash +# Check VM disk +virsh domblklist debian12-guest + +# Check disk usage on hypervisor +qemu-img info /var/lib/libvirt/images/debian12-guest.qcow2 + +# Resize disk (if needed, after deployment) +qemu-img resize /var/lib/libvirt/images/debian12-guest.qcow2 +10G +``` + +### VM Won't Start +```bash +# Check libvirt logs +journalctl -u libvirtd -f + +# Check VM XML configuration +virsh dumpxml debian12-guest + +# Validate VM configuration +virt-xml-validate /etc/libvirt/qemu/debian12-guest.xml +``` + +### SSH Connection Issues +```bash +# Test SSH connectivity +ssh -vvv -J grokbox ansible@ + +# Check SSH service on VM (via console) +virsh console debian12-guest +# Then: systemctl status ssh +``` + +## Security Features + +The deployed VM includes: + +- ✅ Ansible user with passwordless sudo +- ✅ SSH key-based authentication only +- ✅ Root login disabled via SSH +- ✅ UFW firewall enabled (SSH allowed) +- ✅ Automatic security updates configured +- ✅ Audit daemon (auditd) enabled +- ✅ Time synchronization (chrony) +- ✅ Essential security packages installed +- ✅ AIDE for file integrity monitoring +- ✅ Secure SSH configuration + +## Package List + +### Essential Packages +- sudo, vim, htop, tmux +- curl, wget, rsync, git +- python3, python3-pip +- jq, bc + +### Security Packages +- aide (file integrity) +- auditd (system auditing) +- ufw (firewall) +- unattended-upgrades + +### System Packages +- chrony (time sync) +- lvm2 (storage management) +- cloud-guest-utils +- parted + +## Validation Checklist + +After deployment, verify: + +- [ ] VM is running: `virsh list` +- [ ] VM has IP address: `virsh domifaddr debian12-guest` +- [ ] SSH accessible: `ssh -J grokbox ansible@` +- [ ] Cloud-init completed: `cloud-init status` +- [ ] Security updates enabled: `systemctl status unattended-upgrades` +- [ ] Firewall enabled: `sudo ufw status` +- [ ] Time sync working: `chronyc tracking` +- [ ] Audit daemon running: `systemctl status auditd` + +## Next Steps + +1. Add VM to Ansible inventory +2. Run configuration management roles +3. Configure application-specific settings +4. Set up monitoring and logging +5. Configure backups +6. Document VM purpose and services + +## Quick Reference + +### Deployment Flow +1. **Preflight** → Check if VM exists, validate virtualization +2. **Install** → Install required packages on hypervisor +3. **Download** → Download Debian 12 cloud image +4. **Storage** → Create VM disk from cloud image +5. **Cloud-Init** → Generate cloud-init configuration +6. **Deploy** → Create and start VM +7. **Validate** → Verify SSH connectivity and system status +8. **Cleanup** → Remove temporary files + +### Important Paths +- VM Disk: `/var/lib/libvirt/images/debian12-guest.qcow2` +- Cloud-Init ISO: `/var/lib/libvirt/images/debian12-guest-cloud-init.iso` +- Base Image: `/var/lib/libvirt/images/debian-12-generic-amd64.qcow2` +- VM Config: `/etc/libvirt/qemu/debian12-guest.xml` + +### Support +For issues or questions: +- Check `/var/log/cloud-init.log` on VM +- Check `journalctl -u libvirtd` on hypervisor +- Review playbook documentation: `plays/deploy-debian12-vm.yml` +- Consult CLAUDE.md for infrastructure guidelines diff --git a/cheatsheets/deploy-linux-vm-lvm.md b/cheatsheets/deploy-linux-vm-lvm.md new file mode 100644 index 0000000..445b850 --- /dev/null +++ b/cheatsheets/deploy-linux-vm-lvm.md @@ -0,0 +1,411 @@ +# Deploy Linux VM with Post-Config LVM - Quick Reference + +## Playbook +`plays/deploy-linux-vm-lvm.yml` + +## Description +Multi-distribution Linux VM deployment with post-installation LVM configuration. This playbook deploys a VM using cloud images and then configures LVM on a second disk to meet CLAUDE.md requirements. + +## Quick Deployment + +### Debian 12 with LVM +```bash +ansible-playbook plays/deploy-linux-vm-lvm.yml \ + -e "os_distribution=debian-12" \ + -e "vm_name=debian-lvm" +``` + +### Ubuntu 22.04 with LVM +```bash +ansible-playbook plays/deploy-linux-vm-lvm.yml \ + -e "os_distribution=ubuntu-22.04" \ + -e "vm_name=ubuntu-lvm" +``` + +### AlmaLinux 9 with LVM +```bash +ansible-playbook plays/deploy-linux-vm-lvm.yml \ + -e "os_distribution=almalinux-9" \ + -e "vm_name=alma-lvm" +``` + +### Custom Resources +```bash +ansible-playbook plays/deploy-linux-vm-lvm.yml \ + -e "os_distribution=rocky-9" \ + -e "vm_name=prod-server" \ + -e "vm_vcpus=8" \ + -e "vm_memory_mb=16384" \ + -e "vm_disk_size_gb=100" +``` + +## Supported Distributions + +### Debian Family +- `debian-11`, `debian-12` +- `ubuntu-20.04`, `ubuntu-22.04`, `ubuntu-24.04` + +### RHEL Family +- `rhel-8`, `rhel-9` (manual download required) +- `centos-stream-8`, `centos-stream-9` +- `rocky-8`, `rocky-9` +- `almalinux-8`, `almalinux-9` + +### SUSE Family +- `sles-15` (manual download required) +- `opensuse-leap-15.5`, `opensuse-leap-15.6` + +## LVM Configuration + +This playbook creates a **30GB secondary disk** (`/dev/vdb`) with LVM: + +``` +Physical Volume: /dev/vdb (30GB) +Volume Group: vg_system + +Logical Volumes (CLAUDE.md compliant): +├── lv_opt 3G /opt +├── lv_tmp 1G /tmp (noexec,nosuid,nodev) +├── lv_home 2G /home +├── lv_var 5G /var +├── lv_var_log 2G /var/log +├── lv_var_tmp 5G /var/tmp (noexec,nosuid,nodev) +├── lv_var_audit 1G /var/log/audit +└── lv_swap 2G swap + +Primary disk (/dev/vda): OS installation (unchanged) +``` + +## Variables + +| Variable | Default | Description | +|----------|---------|-------------| +| `os_distribution` | **REQUIRED** | Distribution identifier | +| `vm_name` | linux-guest | VM name | +| `vm_hostname` | linux-vm | VM hostname | +| `vm_vcpus` | 2 | Number of vCPUs | +| `vm_memory_mb` | 2048 | RAM in MB | +| `vm_disk_size_gb` | 20 | Primary disk size | +| `lvm_disk_size_gb` | 30 | LVM disk size | +| `lvm_vg_name` | vg_system | Volume group name | +| `lvm_pv_device` | /dev/vdb | Physical volume device | + +## Tag-Based Execution + +```bash +# Pre-flight checks +ansible-playbook plays/deploy-linux-vm-lvm.yml --tags preflight + +# Deploy VM only (no LVM) +ansible-playbook plays/deploy-linux-vm-lvm.yml --skip-tags lvm + +# Configure LVM only (existing VM) +ansible-playbook plays/deploy-linux-vm-lvm.yml \ + -e "vm_ip=192.168.122.50" \ + --tags lvm + +# Full deployment +ansible-playbook plays/deploy-linux-vm-lvm.yml +``` + +### Available Tags +- `preflight`, `validate` - Pre-flight validation +- `install` - Install hypervisor packages +- `download`, `verify` - Download and verify cloud images +- `storage` - Create VM disks (including LVM disk) +- `cloud-init` - Generate cloud-init configuration +- `deploy` - Deploy and start VM +- `lvm` - Configure LVM on deployed VM +- `post-deploy` - Post-deployment tasks +- `cleanup` - Remove temporary files + +## Deployment Process + +### Stage 1: VM Deployment (~2-3 minutes) +1. Download cloud image (if not cached) +2. Create primary disk from cloud image +3. Create secondary 30GB disk for LVM +4. Generate cloud-init configuration +5. Deploy VM with both disks attached +6. Wait for VM to boot + +### Stage 2: LVM Configuration (~3-5 minutes) +1. Install LVM packages on VM +2. Create physical volume on /dev/vdb +3. Create volume group vg_system +4. Create logical volumes +5. Format filesystems +6. Copy existing data to LVM volumes +7. Update /etc/fstab +8. **Reboot required to activate** + +### Total Time: ~5-8 minutes + +## Post-Deployment + +### Get VM IP +```bash +ssh grokbox "virsh domifaddr " +``` + +### Access VM +```bash +ssh -J grokbox ansible@ +``` + +### Verify LVM Configuration +```bash +# Check LVM status +ssh -J grokbox ansible@ "sudo pvs && sudo vgs && sudo lvs" + +# Check disk layout +ssh -J grokbox ansible@ "lsblk" + +# View fstab +ssh -J grokbox ansible@ "cat /etc/fstab" +``` + +Expected lsblk output: +``` +NAME SIZE TYPE MOUNTPOINTS +vda 20G disk +├─vda1 19.9G part / +└─vda14 4M part +vdb 30G disk +├─vg_system-lv_opt 3G lvm /opt +├─vg_system-lv_tmp 1G lvm /tmp +├─vg_system-lv_home 2G lvm /home +├─vg_system-lv_var 5G lvm /var +├─vg_system-lv_var_log 2G lvm /var/log +├─vg_system-lv_var_tmp 5G lvm /var/tmp +├─vg_system-lv_var_audit 1G lvm /var/log/audit +└─vg_system-lv_swap 2G lvm [SWAP] +``` + +### Reboot to Activate LVM Mounts +```bash +# IMPORTANT: Reboot required! +ssh -J grokbox ansible@ "sudo reboot" + +# Wait ~1 minute, then verify mounts +ssh -J grokbox ansible@ "df -h" +``` + +After reboot, verify all LVM volumes are mounted: +```bash +ssh -J grokbox ansible@ "df -h | grep vg_system" +``` + +## Distribution-Specific Features + +### Debian/Ubuntu +- Package manager: `apt` +- Firewall: `ufw` (enabled with SSH allowed) +- Security: AppArmor enabled +- Auto-updates: `unattended-upgrades` +- User group: `sudo` + +### RHEL/AlmaLinux/Rocky +- Package manager: `dnf` +- Firewall: `firewalld` (enabled with SSH allowed) +- Security: SELinux enforcing +- Auto-updates: `dnf-automatic` +- User group: `wheel` + +### SUSE/openSUSE +- Package manager: `zypper` +- Firewall: `firewalld` +- User group: `wheel` + +## LVM Management + +### Extend Logical Volumes +```bash +# Extend lv_var by 5GB +ssh ansible@ "sudo lvextend -L +5G /dev/vg_system/lv_var" +ssh ansible@ "sudo resize2fs /dev/vg_system/lv_var" + +# Use all remaining free space +ssh ansible@ "sudo lvextend -l +100%FREE /dev/vg_system/lv_var" +ssh ansible@ "sudo resize2fs /dev/vg_system/lv_var" +``` + +### Create New Logical Volume +```bash +ssh ansible@ "sudo lvcreate -L 5G -n lv_app vg_system" +ssh ansible@ "sudo mkfs.ext4 /dev/vg_system/lv_app" +ssh ansible@ "sudo mkdir -p /opt/app" +ssh ansible@ "sudo mount /dev/vg_system/lv_app /opt/app" + +# Add to fstab +ssh ansible@ "echo '/dev/vg_system/lv_app /opt/app ext4 defaults 0 2' | sudo tee -a /etc/fstab" +``` + +### LVM Snapshots +```bash +# Create snapshot +ssh ansible@ "sudo lvcreate -L 2G -s -n lv_var_snapshot /dev/vg_system/lv_var" + +# Mount snapshot +ssh ansible@ "sudo mkdir -p /mnt/snapshot" +ssh ansible@ "sudo mount /dev/vg_system/lv_var_snapshot /mnt/snapshot" + +# Remove snapshot +ssh ansible@ "sudo umount /mnt/snapshot" +ssh ansible@ "sudo lvremove /dev/vg_system/lv_var_snapshot" +``` + +## Troubleshooting + +### LVM Configuration Failed +```bash +# Check if second disk is attached +ssh grokbox "virsh domblklist " + +# Check disk visibility on VM +ssh ansible@ "lsblk" + +# Manually run LVM setup +ssh ansible@ "sudo pvcreate /dev/vdb" +ssh ansible@ "sudo vgcreate vg_system /dev/vdb" +``` + +### Mounts Not Active After Reboot +```bash +# Check fstab entries +ssh ansible@ "cat /etc/fstab | grep vg_system" + +# Manually mount all +ssh ansible@ "sudo mount -a" + +# Check for errors +ssh ansible@ "dmesg | tail -30" +``` + +### Data Migration Issues +```bash +# Check data was copied +ssh ansible@ "sudo du -sh /var" +ssh ansible@ "sudo du -sh /opt" + +# If data missing, restore from rsync backup +# (Data should be preserved on original locations until reboot) +``` + +### SELinux Issues (RHEL Family) +```bash +# Check SELinux status +ssh ansible@ "getenforce" + +# View denials +ssh ansible@ "sudo ausearch -m avc -ts recent" + +# Relabel filesystem +ssh ansible@ "sudo restorecon -R /opt /tmp /home /var" +``` + +## Security Features + +All deployed VMs include: + +✅ **Authentication** +- ansible user with passwordless sudo +- SSH key-based authentication only +- Root login disabled via SSH + +✅ **Firewall** (enabled and configured) +- Debian/Ubuntu: UFW +- RHEL/SUSE: firewalld + +✅ **Automatic Updates** +- Debian/Ubuntu: unattended-upgrades +- RHEL: dnf-automatic +- Security updates only, no auto-reboot + +✅ **Security Hardening** +- RHEL: SELinux enforcing +- Debian: AppArmor enabled +- Audit daemon enabled +- Time synchronization (chrony) + +✅ **Essential Packages** +- System tools: vim, htop, tmux +- Network: curl, wget, rsync +- Development: git, python3 +- Security: aide, auditd +- Storage: lvm2, parted + +## VM Management + +```bash +# Start/Stop +ssh grokbox "virsh start " +ssh grokbox "virsh shutdown " +ssh grokbox "virsh destroy " + +# Status +ssh grokbox "virsh dominfo " +ssh grokbox "virsh list --all" + +# Console +ssh grokbox "virsh console " + +# Delete +ssh grokbox "virsh destroy " +ssh grokbox "virsh undefine --remove-all-storage" +``` + +## Validation Checklist + +After deployment and reboot: + +- [ ] VM running: `virsh list | grep ` +- [ ] IP assigned: `virsh domifaddr ` +- [ ] SSH accessible: `ssh -J grokbox ansible@` +- [ ] Cloud-init complete: `cloud-init status` +- [ ] LVM configured: `sudo vgs && sudo lvs` +- [ ] All volumes mounted: `df -h | grep vg_system` +- [ ] Firewall enabled: `sudo ufw status` or `sudo firewall-cmd --state` +- [ ] SELinux enforcing (RHEL): `getenforce` +- [ ] Swap active: `free -h | grep Swap` + +## Comparison with Other Playbooks + +| Feature | deploy-debian12-vm | deploy-debian-lvm-netinst | deploy-linux-vm-lvm | deploy_linux_vm role | +|---------|-------------------|---------------------------|---------------------|---------------------| +| Multi-distro | ❌ No | ❌ No | ✅ Yes | ✅ Yes | +| LVM Support | ❌ No | ✅ Yes (native) | ✅ Yes (post-config) | ✅ Yes (post-config) | +| Deploy Time | 2-3 min | 15-20 min | 5-8 min | 5-8 min | +| CLAUDE.md LVM | ❌ No | ✅ Yes | ✅ Yes | ✅ Yes | +| Reboot Required | No | No | Yes | Yes | +| Modular | No | No | No | Yes | + +## Important Files + +### On Hypervisor (grokbox) +- Cloud images: `/var/lib/libvirt/images/*.qcow2` +- VM primary disk: `/var/lib/libvirt/images/.qcow2` +- VM LVM disk: `/var/lib/libvirt/images/-lvm.qcow2` +- Cloud-init ISO: `/var/lib/libvirt/images/-cloud-init.iso` + +### On Guest VM +- SSH config: `/etc/ssh/sshd_config.d/99-security.conf` +- Sudoers: `/etc/sudoers.d/ansible` +- Fstab: `/etc/fstab` (LVM mounts) +- LVM config: `/etc/lvm/lvm.conf` + +## Related Documentation + +- Playbook: `plays/deploy-linux-vm-lvm.yml` +- Role (recommended): `roles/deploy_linux_vm/` +- Multi-distro without LVM: `plays/deploy-linux-vm.yml` +- Debian native LVM: `plays/deploy-debian-lvm-netinst.yml` +- CLAUDE.md: LVM specifications + +## Support + +For issues or questions: +- Check playbook output during LVM configuration +- View `/var/log/cloud-init-output.log` on VM +- Consult CLAUDE.md for LVM requirements +- Use role version for advanced features diff --git a/cheatsheets/deploy-linux-vm-role.md b/cheatsheets/deploy-linux-vm-role.md new file mode 100644 index 0000000..1d7390f --- /dev/null +++ b/cheatsheets/deploy-linux-vm-role.md @@ -0,0 +1,287 @@ +# Deploy Linux VM Role - Quick Reference + +## Quick Deployment + +### Basic Usage + +```bash +# Deploy Debian 12 VM +ansible-playbook -i inventories/production site.yml \ + -e "deploy_linux_vm_name=test-vm" \ + -e "deploy_linux_vm_os_distribution=debian-12" + +# Deploy Ubuntu 22.04 VM with LVM +ansible-playbook -i inventories/production site.yml \ + -e "deploy_linux_vm_name=ubuntu-vm" \ + -e "deploy_linux_vm_os_distribution=ubuntu-22.04" \ + -e "deploy_linux_vm_use_lvm=true" + +# Deploy AlmaLinux 9 with custom resources +ansible-playbook -i inventories/production site.yml \ + -e "deploy_linux_vm_name=alma-vm" \ + -e "deploy_linux_vm_os_distribution=almalinux-9" \ + -e "deploy_linux_vm_vcpus=4" \ + -e "deploy_linux_vm_memory_mb=8192" \ + -e "deploy_linux_vm_disk_size_gb=50" +``` + +### Distribution Identifiers + +``` +Debian: debian-11, debian-12 +Ubuntu: ubuntu-20.04, ubuntu-22.04, ubuntu-24.04 +RHEL: rhel-8, rhel-9 (manual download) +CentOS: centos-stream-8, centos-stream-9 +Rocky: rocky-8, rocky-9 +AlmaLinux: almalinux-8, almalinux-9 +SLES: sles-15 (manual download) +openSUSE: opensuse-leap-15.5, opensuse-leap-15.6 +``` + +## Tag-Based Execution + +```bash +# Pre-flight checks only +ansible-playbook site.yml --tags validate,preflight + +# Download images only +ansible-playbook site.yml --tags download,verify + +# Deploy without LVM +ansible-playbook site.yml --skip-tags lvm + +# Configure LVM only (existing VM) +ansible-playbook site.yml --tags lvm,post-deploy + +# Full deployment +ansible-playbook site.yml +``` + +## Common Variables + +### VM Configuration +```yaml +deploy_linux_vm_name: "myvm" # VM name +deploy_linux_vm_hostname: "myhost" # Hostname +deploy_linux_vm_vcpus: 2 # CPU cores +deploy_linux_vm_memory_mb: 2048 # RAM in MB +deploy_linux_vm_disk_size_gb: 30 # Disk size +``` + +### LVM Configuration +```yaml +deploy_linux_vm_use_lvm: true # Enable LVM +deploy_linux_vm_lvm_vg_name: "vg_system" # VG name +deploy_linux_vm_lvm_pv_device: "/dev/vdb" # PV device +``` + +### Security Settings +```yaml +deploy_linux_vm_ssh_gssapi_authentication: "no" # GSSAPI disabled +deploy_linux_vm_enable_firewall: true # Firewall on +deploy_linux_vm_enable_selinux: true # SELinux (RHEL) +deploy_linux_vm_enable_automatic_updates: true # Auto updates +``` + +## Example Playbooks + +### Minimal Playbook +```yaml +--- +- hosts: grokbox + become: yes + roles: + - deploy_linux_vm + vars: + deploy_linux_vm_name: "test-vm" + deploy_linux_vm_os_distribution: "debian-12" +``` + +### Production Playbook with LVM +```yaml +--- +- hosts: grokbox + become: yes + roles: + - deploy_linux_vm + vars: + deploy_linux_vm_name: "prod-db" + deploy_linux_vm_hostname: "postgres01" + deploy_linux_vm_domain: "prod.local" + deploy_linux_vm_os_distribution: "almalinux-9" + deploy_linux_vm_vcpus: 8 + deploy_linux_vm_memory_mb: 16384 + deploy_linux_vm_disk_size_gb: 100 + deploy_linux_vm_use_lvm: true +``` + +## Post-Deployment + +### Access VM +```bash +# Get VM IP +ssh grokbox "virsh domifaddr " + +# SSH to VM +ssh -J grokbox ansible@ + +# Or add to ~/.ssh/config +Host myvm + HostName + User ansible + ProxyJump grokbox +``` + +### Verify LVM +```bash +# Check LVM status +ssh -J grokbox ansible@ "sudo vgs && sudo lvs" + +# Check mounts (after reboot) +ssh -J grokbox ansible@ "df -h && lsblk" + +# Reboot VM to activate LVM mounts +ssh -J grokbox ansible@ "sudo reboot" +``` + +### Verify SSH Hardening +```bash +# Check GSSAPI disabled +ssh -J grokbox ansible@ "sudo sshd -T | grep -i gssapi" + +# Should show: +# gssapiauthentication no +# gssapicleanupcredentials no +``` + +### Check Security Features +```bash +# Debian/Ubuntu - UFW status +ssh -J grokbox ansible@ "sudo ufw status" + +# RHEL/Alma - Firewall and SELinux +ssh -J grokbox ansible@ "sudo firewall-cmd --list-all && getenforce" + +# Check automatic updates +ssh -J grokbox ansible@ "systemctl status unattended-upgrades" # Debian +ssh -J grokbox ansible@ "systemctl status dnf-automatic.timer" # RHEL +``` + +## VM Management + +```bash +# Start/Stop/Status +virsh start +virsh shutdown +virsh destroy +virsh dominfo + +# List VMs +virsh list --all + +# Console access +virsh console + +# Delete VM +virsh destroy +virsh undefine --remove-all-storage +``` + +## Troubleshooting + +### Cloud-Init +```bash +# Check status +ssh -J grokbox ansible@ "cloud-init status --wait" + +# View logs +ssh -J grokbox ansible@ "tail -f /var/log/cloud-init-output.log" +``` + +### Network +```bash +# Get VM IP +virsh domifaddr + +# Check network +virsh net-list +virsh net-dhcp-leases default +``` + +### LVM Issues +```bash +# Check LVM configuration +ssh -J grokbox ansible@ "sudo pvs && sudo vgs && sudo lvs" + +# Check fstab +ssh -J grokbox ansible@ "cat /etc/fstab" + +# Manually mount if needed +ssh -J grokbox ansible@ "sudo mount -a" +``` + +## LVM Volume Layout (CLAUDE.md) + +``` +Volume Group: vg_system (30GB on /dev/vdb) +├── lv_opt 3G /opt +├── lv_tmp 1G /tmp (noexec,nosuid,nodev) +├── lv_home 2G /home +├── lv_var 5G /var +├── lv_var_log 2G /var/log +├── lv_var_tmp 5G /var/tmp (noexec,nosuid,nodev) +├── lv_var_audit 1G /var/log/audit +└── lv_swap 2G swap +``` + +## SSH Security Settings + +``` +PermitRootLogin: no +PasswordAuthentication: no +GSSAPIAuthentication: no ← DISABLED per requirements +GSSAPICleanupCredentials: no ← DISABLED per requirements +MaxAuthTries: 3 +ClientAliveInterval: 300 +Key-based authentication only +``` + +## Essential Packages Installed + +- System: vim, htop, tmux, jq, bc +- Network: curl, wget, rsync +- Dev: git, python3, python3-pip +- Security: aide, auditd, chrony +- Storage: lvm2, parted + +## Important Files + +### On Hypervisor +- Cloud images: `/var/lib/libvirt/images/*.qcow2` +- VM disk: `/var/lib/libvirt/images/.qcow2` +- LVM disk: `/var/lib/libvirt/images/-lvm.qcow2` + +### On Guest VM +- SSH config: `/etc/ssh/sshd_config.d/99-security.conf` +- Sudoers: `/etc/sudoers.d/ansible` +- Fstab: `/etc/fstab` +- Cloud-init log: `/var/log/cloud-init-output.log` + +## Quick Validation Checklist + +After deployment: + +- [ ] VM running: `virsh list | grep ` +- [ ] IP assigned: `virsh domifaddr ` +- [ ] SSH accessible: `ssh -J grokbox ansible@` +- [ ] Cloud-init done: `cloud-init status` +- [ ] Firewall active: `sudo ufw status` or `sudo firewall-cmd --state` +- [ ] LVM configured: `sudo vgs` (if LVM enabled) +- [ ] GSSAPI disabled: `sudo sshd -T | grep gssapi` +- [ ] Reboot for LVM: `sudo reboot` (then verify mounts) + +## Support + +- Role README: `roles/deploy_linux_vm/README.md` +- Documentation: `docs/linux-vm-deployment.md` +- Guidelines: `CLAUDE.md` diff --git a/cheatsheets/deploy-linux-vm.md b/cheatsheets/deploy-linux-vm.md new file mode 100644 index 0000000..3aa2ddc --- /dev/null +++ b/cheatsheets/deploy-linux-vm.md @@ -0,0 +1,502 @@ +# Multi-Distribution Linux VM Deployment Cheatsheet + +## Supported Distributions + +### Debian Family +- Debian 11 (Bullseye) +- Debian 12 (Bookworm) +- Ubuntu 20.04 LTS (Focal) +- Ubuntu 22.04 LTS (Jammy) +- Ubuntu 24.04 LTS (Noble) + +### RHEL Family +- RHEL 8, 9 (requires subscription) +- CentOS Stream 8, 9 +- Rocky Linux 8, 9 +- AlmaLinux 8, 9 + +### SUSE Family +- SLES 15 (requires subscription) +- openSUSE Leap 15.5, 15.6 + +## Quick Deployment + +### Debian/Ubuntu + +```bash +# Debian 12 +ansible-playbook plays/deploy-linux-vm.yml \ + -e "os_distribution=debian-12" \ + -e "vm_name=debian12-vm" + +# Ubuntu 22.04 LTS +ansible-playbook plays/deploy-linux-vm.yml \ + -e "os_distribution=ubuntu-22.04" \ + -e "vm_name=ubuntu22-vm" + +# Ubuntu 24.04 LTS +ansible-playbook plays/deploy-linux-vm.yml \ + -e "os_distribution=ubuntu-24.04" \ + -e "vm_name=ubuntu24-vm" +``` + +### RHEL Family + +```bash +# CentOS Stream 9 +ansible-playbook plays/deploy-linux-vm.yml \ + -e "os_distribution=centos-stream-9" \ + -e "vm_name=centos9-vm" + +# Rocky Linux 9 +ansible-playbook plays/deploy-linux-vm.yml \ + -e "os_distribution=rocky-9" \ + -e "vm_name=rocky9-vm" + +# AlmaLinux 9 +ansible-playbook plays/deploy-linux-vm.yml \ + -e "os_distribution=almalinux-9" \ + -e "vm_name=alma9-vm" +``` + +### SUSE Family + +```bash +# openSUSE Leap 15.6 +ansible-playbook plays/deploy-linux-vm.yml \ + -e "os_distribution=opensuse-leap-15.6" \ + -e "vm_name=opensuse-vm" +``` + +## Custom Resource Allocation + +```bash +# High-performance VM +ansible-playbook plays/deploy-linux-vm.yml \ + -e "os_distribution=rocky-9" \ + -e "vm_name=app-server" \ + -e "vm_vcpus=8" \ + -e "vm_memory_mb=16384" \ + -e "vm_disk_size_gb=100" + +# Development VM +ansible-playbook plays/deploy-linux-vm.yml \ + -e "os_distribution=ubuntu-22.04" \ + -e "vm_name=dev-box" \ + -e "vm_vcpus=4" \ + -e "vm_memory_mb=8192" \ + -e "vm_disk_size_gb=50" + +# Minimal VM +ansible-playbook plays/deploy-linux-vm.yml \ + -e "os_distribution=debian-12" \ + -e "vm_name=test-vm" \ + -e "vm_vcpus=1" \ + -e "vm_memory_mb=1024" \ + -e "vm_disk_size_gb=10" +``` + +## Custom Configuration + +```bash +# Custom hostname and domain +ansible-playbook plays/deploy-linux-vm.yml \ + -e "os_distribution=centos-stream-9" \ + -e "vm_name=web-server" \ + -e "vm_hostname=webserver01" \ + -e "vm_domain=production.local" + +# Custom SSH key +ansible-playbook plays/deploy-linux-vm.yml \ + -e "os_distribution=ubuntu-24.04" \ + -e "vm_name=secure-vm" \ + -e "ansible_user_ssh_key='ssh-ed25519 AAAA...'" + +# Custom network +ansible-playbook plays/deploy-linux-vm.yml \ + -e "os_distribution=rocky-9" \ + -e "vm_name=isolated-vm" \ + -e "vm_network=isolated" \ + -e "vm_bridge=virbr1" +``` + +## Tag-Based Execution + +```bash +# Pre-flight checks only +ansible-playbook plays/deploy-linux-vm.yml \ + -e "os_distribution=debian-12" \ + -t preflight,validate + +# Download and verify image only +ansible-playbook plays/deploy-linux-vm.yml \ + -e "os_distribution=ubuntu-22.04" \ + -t download,verify + +# Create storage only +ansible-playbook plays/deploy-linux-vm.yml \ + -e "os_distribution=rocky-9" \ + -e "vm_name=myvm" \ + -t storage + +# Generate cloud-init config only +ansible-playbook plays/deploy-linux-vm.yml \ + -e "os_distribution=centos-stream-9" \ + -e "vm_name=myvm" \ + -t cloud-init + +# Deploy VM (assumes image downloaded) +ansible-playbook plays/deploy-linux-vm.yml \ + -e "os_distribution=almalinux-9" \ + -e "vm_name=myvm" \ + -t deploy + +# Validation only +ansible-playbook plays/deploy-linux-vm.yml \ + -e "os_distribution=debian-12" \ + -e "vm_name=myvm" \ + -t validate + +# Cleanup temporary files +ansible-playbook plays/deploy-linux-vm.yml \ + -e "os_distribution=ubuntu-24.04" \ + -e "vm_name=myvm" \ + -t cleanup +``` + +## Required Variables + +| Variable | Required | Default | Description | +|----------|----------|---------|-------------| +| `os_distribution` | **YES** | debian-12 | Distribution identifier | +| `vm_name` | No | linux-guest | VM name in libvirt | +| `vm_hostname` | No | linux-vm | VM hostname | +| `vm_domain` | No | localdomain | Domain name | +| `vm_vcpus` | No | 2 | Number of vCPUs | +| `vm_memory_mb` | No | 2048 | RAM in MB | +| `vm_disk_size_gb` | No | 20 | Disk size in GB | +| `vm_network` | No | default | Libvirt network | +| `ansible_user_ssh_key` | No | (predefined) | SSH public key | + +## Distribution Identifiers + +``` +Debian: + - debian-11 + - debian-12 + +Ubuntu: + - ubuntu-20.04 + - ubuntu-22.04 + - ubuntu-24.04 + +RHEL Family: + - rhel-8 (manual download) + - rhel-9 (manual download) + - centos-stream-8 + - centos-stream-9 + - rocky-8 + - rocky-9 + - almalinux-8 + - almalinux-9 + +SUSE Family: + - sles-15 (manual download) + - opensuse-leap-15.5 + - opensuse-leap-15.6 +``` + +## Distribution-Specific Features + +### Debian/Ubuntu +- Package Manager: `apt` +- Firewall: `ufw` +- Automatic Updates: `unattended-upgrades` +- User Group: `sudo` + +### RHEL/CentOS/Rocky/Alma +- Package Manager: `dnf` +- Firewall: `firewalld` +- Automatic Updates: `dnf-automatic` +- SELinux: Enforcing mode +- User Group: `wheel` + +### SUSE/openSUSE +- Package Manager: `zypper` +- Firewall: `firewalld` +- User Group: `wheel` + +## Common Use Cases + +### Deploy Database Server (Rocky Linux) +```bash +ansible-playbook plays/deploy-linux-vm.yml \ + -e "os_distribution=rocky-9" \ + -e "vm_name=db-server" \ + -e "vm_hostname=postgres01" \ + -e "vm_vcpus=4" \ + -e "vm_memory_mb=8192" \ + -e "vm_disk_size_gb=100" +``` + +### Deploy Web Server (Ubuntu) +```bash +ansible-playbook plays/deploy-linux-vm.yml \ + -e "os_distribution=ubuntu-22.04" \ + -e "vm_name=web-server" \ + -e "vm_hostname=nginx01" \ + -e "vm_vcpus=2" \ + -e "vm_memory_mb=4096" \ + -e "vm_disk_size_gb=40" +``` + +### Deploy Container Host (CentOS Stream) +```bash +ansible-playbook plays/deploy-linux-vm.yml \ + -e "os_distribution=centos-stream-9" \ + -e "vm_name=container-host" \ + -e "vm_hostname=podman01" \ + -e "vm_vcpus=6" \ + -e "vm_memory_mb=12288" \ + -e "vm_disk_size_gb=80" +``` + +### Deploy Development VM (Debian) +```bash +ansible-playbook plays/deploy-linux-vm.yml \ + -e "os_distribution=debian-12" \ + -e "vm_name=dev-vm" \ + -e "vm_hostname=devbox" \ + -e "vm_vcpus=4" \ + -e "vm_memory_mb=8192" \ + -e "vm_disk_size_gb=50" +``` + +## Post-Deployment + +### Access VM + +```bash +# Get VM IP +ssh grokbox "virsh domifaddr " + +# SSH to VM +ssh -J grokbox ansible@ + +# Add to ~/.ssh/config +Host myvm + HostName + User ansible + ProxyJump grokbox + StrictHostKeyChecking accept-new +``` + +### VM Management + +```bash +# Start/Stop +virsh start +virsh shutdown +virsh destroy + +# Status +virsh dominfo +virsh list --all + +# Autostart +virsh autostart +virsh autostart --disable + +# Console access +virsh console +``` + +## Troubleshooting + +### Cloud-Init Status +```bash +# On VM +cloud-init status +cloud-init status --wait +cloud-init status --long + +# Logs +tail -f /var/log/cloud-init-output.log +journalctl -u cloud-init +``` + +### Network Issues +```bash +# Check IP assignment +virsh domifaddr + +# Check libvirt network +virsh net-list +virsh net-dhcp-leases default + +# Restart network (on hypervisor) +virsh net-destroy default +virsh net-start default +``` + +### SELinux Issues (RHEL Family) +```bash +# Check status +getenforce + +# View denials +ausearch -m avc -ts recent + +# Generate policy +audit2allow -a +``` + +### Firewall Issues + +```bash +# Debian/Ubuntu +sudo ufw status verbose +sudo ufw allow + +# RHEL/SUSE +sudo firewall-cmd --list-all +sudo firewall-cmd --permanent --add-service= +sudo firewall-cmd --reload +``` + +### Package Manager Issues + +```bash +# Debian/Ubuntu +sudo apt update +sudo apt upgrade +sudo apt-cache search + +# RHEL/CentOS/Rocky/Alma +sudo dnf check-update +sudo dnf upgrade +sudo dnf search + +# SUSE/openSUSE +sudo zypper refresh +sudo zypper update +sudo zypper search +``` + +## Image Cache Location + +All downloaded cloud images are cached at: +``` +/var/lib/libvirt/images/--*-amd64.qcow2 +``` + +To update cached images: +```bash +# Remove old image +ssh grokbox "rm /var/lib/libvirt/images/.qcow2" + +# Re-run playbook to download latest +ansible-playbook plays/deploy-linux-vm.yml \ + -e "os_distribution=" \ + -t download,verify +``` + +## Manual Download (RHEL/SLES) + +For distributions requiring subscriptions: + +1. **RHEL**: Download from Red Hat Customer Portal + - Location: https://access.redhat.com/downloads/ + - Product: Red Hat Enterprise Linux + - Type: KVM Guest Image + +2. **SLES**: Download from SUSE Customer Center + - Location: https://scc.suse.com/ + - Product: SUSE Linux Enterprise Server + - Type: Cloud Image + +3. Place downloaded image at: + ``` + /var/lib/libvirt/images/ + ``` + +4. Run deployment playbook normally + +## Security Features + +All deployed VMs include: + +✅ **User Management** +- ansible user with passwordless sudo +- SSH key-based authentication only +- Root login disabled via SSH + +✅ **Firewall** (enabled and configured) +- Debian/Ubuntu: UFW +- RHEL/SUSE: firewalld + +✅ **Automatic Updates** +- Debian/Ubuntu: unattended-upgrades +- RHEL: dnf-automatic +- Security updates only, no auto-reboot + +✅ **Security Hardening** +- RHEL: SELinux enforcing +- Audit daemon enabled +- Secure SSH configuration +- Time synchronization (chrony) + +✅ **Essential Packages** +- System tools: vim, htop, tmux +- Network tools: curl, wget, rsync +- Development: git, python3 +- Security: aide, auditd + +## Validation Checklist + +After deployment: + +- [ ] VM running: `virsh list | grep ` +- [ ] IP assigned: `virsh domifaddr ` +- [ ] SSH accessible: `ssh -J grokbox ansible@` +- [ ] Cloud-init complete: `cloud-init status` +- [ ] Firewall enabled: `sudo ufw status` or `sudo firewall-cmd --state` +- [ ] Updates configured: Check respective service +- [ ] SELinux enforcing (RHEL): `getenforce` +- [ ] Time sync: `chronyc tracking` +- [ ] Audit daemon: `systemctl status auditd` + +## Quick Reference + +### Deployment Workflow +1. **Validate** → Check distribution and VM name +2. **Install** → Install required packages on hypervisor +3. **Download** → Download distribution cloud image +4. **Verify** → Validate image checksums +5. **Storage** → Create VM disk from cloud image +6. **Cloud-Init** → Generate configuration for OS family +7. **Deploy** → Create and start VM with virt-install +8. **Validate** → Verify SSH and system status +9. **Cleanup** → Remove temporary files + +### Important Paths +- Cloud Images: `/var/lib/libvirt/images/*.qcow2` +- VM Disks: `/var/lib/libvirt/images/.qcow2` +- Cloud-Init ISO: `/var/lib/libvirt/images/-cloud-init.iso` +- VM Config: `/etc/libvirt/qemu/.xml` + +### Emergency Access + +If SSH fails, use console: +```bash +virsh console + +# Login as root with password: ChangeMe123! +# (Change this immediately!) +``` + +## Support + +- Documentation: `docs/linux-vm-deployment.md` +- Playbook: `plays/deploy-linux-vm.yml` +- Guidelines: `CLAUDE.md` diff --git a/cheatsheets/inventory.md b/cheatsheets/inventory.md new file mode 100644 index 0000000..593af41 --- /dev/null +++ b/cheatsheets/inventory.md @@ -0,0 +1,212 @@ +# Inventory Cheatsheet + +Quick reference for Ansible inventory management. + +## Quick Commands + +### List Hosts +```bash +# Static inventory +ansible all -i inventories/development/hosts.yml --list-hosts + +# SSH config dynamic +ansible all -i plugins/inventory/ssh_config_inventory.py --list-hosts + +# Libvirt dynamic +ansible all -i plugins/inventory/libvirt_kvm.py --list-hosts +``` + +### View Inventory Structure +```bash +# List all groups and hosts +ansible-inventory -i --list + +# Show as graph +ansible-inventory -i --graph + +# Specific host details +ansible-inventory -i --host +``` + +### Test Connectivity +```bash +# Ping all hosts +ansible all -i -m ping + +# Ping specific group +ansible kvm_guests -i -m ping + +# Verbose output +ansible all -i -m ping -vvv +``` + +## Inventory Locations + +| Inventory | Path | Type | +|-----------|------|------| +| Static Dev | `inventories/development/hosts.yml` | Static YAML | +| SSH Parser | `plugins/inventory/ssh_config_inventory.py` | Dynamic Script | +| Libvirt | `plugins/inventory/libvirt_kvm.py` | Dynamic Script | + +## Common Groups + +| Group | Description | Inventory | +|-------|-------------|-----------| +| `all` | All hosts | All | +| `external_hosts` | Public-facing hosts | All | +| `hypervisors` | KVM hypervisors | All | +| `kvm_guests` | All VMs | All | +| `running_vms` | Running VMs only | Libvirt | +| `dns_servers` | DNS/DHCP servers | All | +| `mail_servers` | Mail servers | All | +| `development` | Dev/test hosts | All | + +## Dynamic Inventory Usage + +### SSH Config Parser +```bash +# List inventory +python3 plugins/inventory/ssh_config_inventory.py --list + +# Host details +python3 plugins/inventory/ssh_config_inventory.py --host pihole + +# Use with ansible +ansible all -i plugins/inventory/ssh_config_inventory.py -m ping +``` + +### Libvirt Dynamic +```bash +# Set environment +export LIBVIRT_DEFAULT_URI="qemu+ssh://grok@grok.home.serneels.xyz/system" +export LIBVIRT_HYPERVISOR_NAME="grokbox" + +# List VMs +python3 plugins/inventory/libvirt_kvm.py --list + +# Use with ansible +ansible running_vms -i plugins/inventory/libvirt_kvm.py -m setup +``` + +## Playbook Execution + +### Single Inventory +```bash +ansible-playbook -i inventories/development/hosts.yml site.yml +``` + +### Multiple Inventories +```bash +ansible-playbook \ + -i inventories/development/hosts.yml \ + -i plugins/inventory/libvirt_kvm.py \ + site.yml +``` + +### With Limits +```bash +# Limit to specific group +ansible-playbook -i --limit kvm_guests site.yml + +# Limit to specific host +ansible-playbook -i --limit pihole site.yml + +# Multiple limits +ansible-playbook -i --limit "dns_servers:mail_servers" site.yml +``` + +## Variable Precedence + +From lowest to highest: +1. `group_vars/all.yml` +2. `group_vars/.yml` +3. `host_vars/.yml` +4. Playbook vars +5. Extra vars (`-e`) + +## Debugging + +### Validate Inventory +```bash +# Syntax check +ansible-inventory -i --list > /dev/null + +# YAML validation +yamllint inventories/development/hosts.yml +``` + +### Connection Test +```bash +# Test SSH connectivity +ansible all -i -m ping -vvv + +# Check Python interpreter +ansible all -i -m setup -a "filter=ansible_python_version" + +# Verify become/sudo +ansible all -i -m shell -a "whoami" --become +``` + +### View Effective Variables +```bash +# All variables for a host +ansible-inventory -i --host --yaml + +# Specific variable +ansible -i -m debug -a "var=ansible_user" +``` + +## Common Issues + +### SSH Config Parser +**Issue:** Hosts missing +**Fix:** Check `~/.ssh/config` syntax and permissions + +### Libvirt Dynamic +**Issue:** `python3-libvirt` not found +**Fix:** `apt-get install python3-libvirt` (Debian) or `dnf install python3-libvirt` (RHEL) + +**Issue:** Connection failed +**Fix:** Test SSH: `ssh grok@grok.home.serneels.xyz` + +### Static Inventory +**Issue:** YAML errors +**Fix:** Check indentation, validate with `yamllint` + +**Issue:** Variables not applied +**Fix:** Check file naming in `group_vars/` matches group name + +## Performance Tips + +```ini +# ansible.cfg +[defaults] +forks = 20 +gathering = smart +fact_caching = jsonfile +fact_caching_timeout = 86400 +``` + +```bash +# SSH connection reuse (~/.ssh/config) +Host * + ControlMaster auto + ControlPersist 600s +``` + +## Quick Setup + +```bash +# Create inventory structure +mkdir -p inventories/{production,staging,development}/{group_vars,host_vars} + +# Test connectivity +ansible all -i -m ping + +# Gather facts +ansible all -i -m setup --tree /tmp/facts +``` + +--- + +**See also:** `/opt/ansible/docs/inventory.md` for complete documentation diff --git a/cheatsheets/test-deploy-linux-vm-role.md b/cheatsheets/test-deploy-linux-vm-role.md new file mode 100644 index 0000000..5ebfa0e --- /dev/null +++ b/cheatsheets/test-deploy-linux-vm-role.md @@ -0,0 +1,413 @@ +# Test Deploy Linux VM Role - Quick Reference + +## Playbook +`plays/test-deploy-linux-vm-role.yml` + +## Description +Test playbook for the `deploy_linux_vm` role. Deploys a Debian 12 test VM with full LVM configuration and SSH hardening (GSSAPI disabled) to validate role functionality. + +## Quick Test + +### Run Full Test +```bash +ansible-playbook plays/test-deploy-linux-vm-role.yml +``` + +### Test with Different Distribution +```bash +# Test with Ubuntu +ansible-playbook plays/test-deploy-linux-vm-role.yml \ + -e "deploy_linux_vm_os_distribution=ubuntu-22.04" + +# Test with AlmaLinux +ansible-playbook plays/test-deploy-linux-vm-role.yml \ + -e "deploy_linux_vm_os_distribution=almalinux-9" +``` + +### Test with Custom Resources +```bash +ansible-playbook plays/test-deploy-linux-vm-role.yml \ + -e "deploy_linux_vm_vcpus=4" \ + -e "deploy_linux_vm_memory_mb=4096" +``` + +## Test Configuration + +### Default Test Settings +```yaml +VM Name: test-lvm-vm +Hostname: test-lvm +Distribution: debian-12 +vCPUs: 2 +Memory: 2048 MB +Disk: 20 GB +LVM: Enabled (30GB on /dev/vdb) +``` + +### Features Being Tested +✅ LVM configuration (CLAUDE.md compliant) +✅ SSH hardening (GSSAPI disabled) +✅ Multi-distribution support +✅ Security features (Firewall, SELinux/AppArmor, Audit) +✅ Automatic updates +✅ Cloud-init provisioning + +## Test Execution Flow + +### 1. Pre-flight Validation +- Checks if test VM already exists +- Validates distribution support +- Verifies virtualization capabilities + +### 2. VM Deployment (~2-3 minutes) +- Downloads cloud image (if not cached) +- Creates primary disk (20GB) +- Creates LVM disk (30GB on /dev/vdb) +- Generates cloud-init with security hardening +- Deploys VM with both disks + +### 3. LVM Configuration (~3-5 minutes) +- Installs LVM packages +- Creates vg_system volume group +- Creates 8 logical volumes +- Formats filesystems +- Migrates existing data +- Updates /etc/fstab + +### 4. Validation +- Verifies VM is running +- Checks SSH connectivity +- Validates LVM configuration +- Confirms security features + +### Total Test Time: ~5-8 minutes + +## Post-Test Verification + +### Get Test VM Information +```bash +# Get IP address +ssh grokbox "virsh domifaddr test-lvm-vm" + +# SSH to test VM +ssh -J grokbox ansible@ +``` + +### Verify LVM Configuration +```bash +# Check LVM status +ssh -J grokbox ansible@ "sudo pvs && sudo vgs && sudo lvs" + +# Expected output: +# VG: vg_system +# PV: /dev/vdb (30.00g) +# LVs: lv_opt, lv_tmp, lv_home, lv_var, lv_var_log, lv_var_tmp, lv_var_audit, lv_swap +``` + +### Verify SSH Hardening +```bash +# Check GSSAPI is disabled +ssh -J grokbox ansible@ "sudo sshd -T | grep -i gssapi" + +# Expected output: +# gssapiauthentication no +# gssapicleanupcredentials no +``` + +### Verify Security Features +```bash +# Check firewall (Debian) +ssh -J grokbox ansible@ "sudo ufw status" + +# Check SELinux (RHEL - if testing RHEL family) +ssh -J grokbox ansible@ "getenforce" +# Expected: Enforcing +``` + +### Reboot and Verify LVM Mounts +```bash +# Reboot test VM +ssh -J grokbox ansible@ "sudo reboot" + +# Wait ~1 minute, then verify all mounts +ssh -J grokbox ansible@ "df -h && lsblk" + +# Check all LVM volumes are mounted +ssh -J grokbox ansible@ "mount | grep vg_system" +``` + +## Tag-Based Testing + +### Test Specific Components +```bash +# Test pre-flight validation only +ansible-playbook plays/test-deploy-linux-vm-role.yml --tags validate,preflight + +# Test VM deployment only (skip LVM) +ansible-playbook plays/test-deploy-linux-vm-role.yml --skip-tags lvm + +# Test LVM configuration only (if VM exists) +ansible-playbook plays/test-deploy-linux-vm-role.yml --tags lvm,post-deploy + +# Test cloud-init generation only +ansible-playbook plays/test-deploy-linux-vm-role.yml --tags cloud-init +``` + +## Test Validation Checklist + +Complete this checklist to validate test success: + +### Basic Functionality +- [ ] Playbook completes without errors +- [ ] VM created: `virsh list | grep test-lvm-vm` +- [ ] IP assigned: `virsh domifaddr test-lvm-vm` +- [ ] SSH accessible: `ssh -J grokbox ansible@` + +### LVM Configuration +- [ ] Physical volume exists: `sudo pvs` shows /dev/vdb +- [ ] Volume group created: `sudo vgs` shows vg_system +- [ ] All 8 LVs created: `sudo lvs` shows all volumes +- [ ] Filesystems formatted: `lsblk -f` shows ext4/swap +- [ ] Fstab updated: `cat /etc/fstab | grep vg_system` +- [ ] After reboot, all mounted: `df -h | grep vg_system` + +### SSH Security +- [ ] GSSAPI disabled: `sudo sshd -T | grep gssapiauthentication` shows "no" +- [ ] GSSAPI cleanup disabled: `sudo sshd -T | grep gssapicleanupcredentials` shows "no" +- [ ] Root login disabled: `sudo sshd -T | grep permitrootlogin` shows "no" +- [ ] Password auth disabled: `sudo sshd -T | grep passwordauthentication` shows "no" +- [ ] Key-based auth works: SSH connection successful + +### Security Features +- [ ] Firewall enabled: `sudo ufw status` (Debian) or `sudo firewall-cmd --state` (RHEL) +- [ ] Audit daemon running: `systemctl status auditd` +- [ ] Time sync active: `chronyc tracking` +- [ ] SELinux enforcing (RHEL): `getenforce` shows "Enforcing" + +### System Health +- [ ] Cloud-init complete: `cloud-init status` shows "done" +- [ ] System updated: Package updates applied during cloud-init +- [ ] No errors in logs: Check `/var/log/cloud-init-output.log` +- [ ] Swap active: `free -h | grep Swap` shows non-zero + +## Cleanup After Testing + +### Delete Test VM +```bash +# Stop and remove test VM +ssh grokbox "virsh destroy test-lvm-vm" +ssh grokbox "virsh undefine test-lvm-vm --remove-all-storage" + +# Verify removal +ssh grokbox "virsh list --all | grep test-lvm-vm" +# Should return nothing +``` + +### Clean Test Files +```bash +# On hypervisor, remove any temporary files +ssh grokbox "rm -f /tmp/cloud-init-test-lvm-vm/*" +ssh grokbox "rm -f /tmp/*-CHECKSUM" +``` + +## Testing Different Distributions + +### Test Debian Family +```bash +# Debian 12 +ansible-playbook plays/test-deploy-linux-vm-role.yml \ + -e "deploy_linux_vm_os_distribution=debian-12" \ + -e "deploy_linux_vm_name=test-debian12" + +# Ubuntu 22.04 +ansible-playbook plays/test-deploy-linux-vm-role.yml \ + -e "deploy_linux_vm_os_distribution=ubuntu-22.04" \ + -e "deploy_linux_vm_name=test-ubuntu22" +``` + +### Test RHEL Family +```bash +# AlmaLinux 9 +ansible-playbook plays/test-deploy-linux-vm-role.yml \ + -e "deploy_linux_vm_os_distribution=almalinux-9" \ + -e "deploy_linux_vm_name=test-alma9" + +# Rocky Linux 9 +ansible-playbook plays/test-deploy-linux-vm-role.yml \ + -e "deploy_linux_vm_os_distribution=rocky-9" \ + -e "deploy_linux_vm_name=test-rocky9" +``` + +## Troubleshooting Tests + +### Test Fails at Pre-flight +```bash +# Check if test VM already exists +ssh grokbox "virsh list --all | grep test-lvm-vm" + +# If exists, delete it +ssh grokbox "virsh destroy test-lvm-vm" +ssh grokbox "virsh undefine test-lvm-vm --remove-all-storage" + +# Re-run test +ansible-playbook plays/test-deploy-linux-vm-role.yml +``` + +### LVM Configuration Fails +```bash +# Check if second disk is attached +ssh grokbox "virsh domblklist test-lvm-vm" + +# Should show both: +# - test-lvm-vm.qcow2 (primary) +# - test-lvm-vm-lvm.qcow2 (LVM disk) + +# Verify disk visibility on VM +ssh -J grokbox ansible@ "lsblk" +# Should show vda (20G) and vdb (30G) +``` + +### SSH Connection Issues +```bash +# Check VM is running +ssh grokbox "virsh list | grep test-lvm-vm" + +# Get IP again +ssh grokbox "virsh domifaddr test-lvm-vm" + +# Test with verbose SSH +ssh -vvv -J grokbox ansible@ + +# Check SSH service on VM (via console) +ssh grokbox "virsh console test-lvm-vm" +``` + +### GSSAPI Still Enabled +```bash +# Check SSH config file was created +ssh -J grokbox ansible@ "ls -la /etc/ssh/sshd_config.d/" + +# View security config +ssh -J grokbox ansible@ "cat /etc/ssh/sshd_config.d/99-security.conf" + +# Restart SSH service +ssh -J grokbox ansible@ "sudo systemctl restart sshd" + +# Test again +ssh -J grokbox ansible@ "sudo sshd -T | grep gssapi" +``` + +## Continuous Testing + +### Automated Test Suite +Create a test script for continuous validation: + +```bash +#!/bin/bash +# test-role.sh + +DISTRIBUTIONS=( + "debian-12" + "ubuntu-22.04" + "almalinux-9" + "rocky-9" +) + +for distro in "${DISTRIBUTIONS[@]}"; do + echo "Testing $distro..." + + ansible-playbook plays/test-deploy-linux-vm-role.yml \ + -e "deploy_linux_vm_os_distribution=$distro" \ + -e "deploy_linux_vm_name=test-$distro" + + if [ $? -eq 0 ]; then + echo "✅ $distro test PASSED" + # Cleanup + ssh grokbox "virsh destroy test-$distro && virsh undefine test-$distro --remove-all-storage" + else + echo "❌ $distro test FAILED" + exit 1 + fi +done + +echo "All tests completed successfully!" +``` + +## Expected Test Output + +Successful test execution should show: + +``` +PLAY [Test Deploy Linux VM Role] *********************************** + +TASK [Gathering Facts] ********************************************* +ok: [grokbox] + +... + +TASK [deploy_linux_vm : Display LVM configuration summary] ******** +ok: [grokbox] => { + "msg": [ + "=== LVM Configuration Complete ===", + "Volume Group: vg_system", + "Physical Volume: /dev/vdb (30GB)", + "Logical Volumes: 8", + "", + "⚠️ IMPORTANT: VM needs reboot to use new mounts", + "After reboot, LVM volumes will be mounted automatically" + ] +} + +TASK [Display test completion message] ***************************** +ok: [grokbox] => { + "msg": [ + "╔════════════════════════════════════════════════════════════════╗", + "║ Role Test Completed Successfully ║", + "╚════════════════════════════════════════════════════════════════╝", + "", + "VM deployed with:", + " ✓ LVM Configuration (CLAUDE.md compliant)", + " ✓ SSH Hardening (GSSAPI disabled)", + " ✓ Security Features (Firewall, Audit, Auto-updates)", + " ✓ Multi-distribution support", + "", + "Next steps:", + " 1. SSH to VM: ssh -J grokbox ansible@192.168.122.X", + " 2. Verify GSSAPI: sudo sshd -T | grep -i gssapi", + " 3. Check LVM: sudo vgs && sudo lvs", + " 4. Reboot for LVM: sudo reboot", + " 5. After reboot verify: df -h && lsblk" + ] +} + +PLAY RECAP ********************************************************* +grokbox: ok=X changed=Y unreachable=0 failed=0 skipped=Z +``` + +## Test Documentation + +This test validates: + +1. **Role Structure**: Proper task organization and variable handling +2. **Multi-Distribution**: Works across Debian, Ubuntu, RHEL families +3. **LVM Implementation**: Creates CLAUDE.md compliant LVM layout +4. **SSH Security**: GSSAPI disabled, key-only authentication +5. **Security Hardening**: Firewall, SELinux/AppArmor, audit daemon +6. **Cloud-Init**: Proper provisioning and package installation +7. **Idempotency**: Can be re-run without errors + +## Related Documentation + +- Role README: `roles/deploy_linux_vm/README.md` +- Role cheatsheet: `cheatsheets/deploy-linux-vm-role.md` +- CLAUDE.md: Infrastructure requirements +- Test playbook: `plays/test-deploy-linux-vm-role.yml` + +## Support + +For test failures: +- Check playbook output for specific error messages +- Review role tasks: `roles/deploy_linux_vm/tasks/` +- Check VM logs: `/var/log/cloud-init-output.log` +- Verify hypervisor resources: disk space, memory +- Consult role README for detailed troubleshooting