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
11 KiB
11 KiB
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
# 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
# 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
# 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
# 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
# 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
# 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)
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)
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)
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)
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
# Get VM IP
ssh grokbox "virsh domifaddr <vm_name>"
# SSH to VM
ssh -J grokbox ansible@<VM_IP>
# Add to ~/.ssh/config
Host myvm
HostName <VM_IP>
User ansible
ProxyJump grokbox
StrictHostKeyChecking accept-new
VM Management
# Start/Stop
virsh start <vm_name>
virsh shutdown <vm_name>
virsh destroy <vm_name>
# Status
virsh dominfo <vm_name>
virsh list --all
# Autostart
virsh autostart <vm_name>
virsh autostart <vm_name> --disable
# Console access
virsh console <vm_name>
Troubleshooting
Cloud-Init Status
# 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
# Check IP assignment
virsh domifaddr <vm_name>
# 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)
# Check status
getenforce
# View denials
ausearch -m avc -ts recent
# Generate policy
audit2allow -a
Firewall Issues
# Debian/Ubuntu
sudo ufw status verbose
sudo ufw allow <port>
# RHEL/SUSE
sudo firewall-cmd --list-all
sudo firewall-cmd --permanent --add-service=<service>
sudo firewall-cmd --reload
Package Manager Issues
# Debian/Ubuntu
sudo apt update
sudo apt upgrade
sudo apt-cache search <package>
# RHEL/CentOS/Rocky/Alma
sudo dnf check-update
sudo dnf upgrade
sudo dnf search <package>
# SUSE/openSUSE
sudo zypper refresh
sudo zypper update
sudo zypper search <package>
Image Cache Location
All downloaded cloud images are cached at:
/var/lib/libvirt/images/<distribution>-<version>-*-amd64.qcow2
To update cached images:
# Remove old image
ssh grokbox "rm /var/lib/libvirt/images/<image-name>.qcow2"
# Re-run playbook to download latest
ansible-playbook plays/deploy-linux-vm.yml \
-e "os_distribution=<distro>" \
-t download,verify
Manual Download (RHEL/SLES)
For distributions requiring subscriptions:
-
RHEL: Download from Red Hat Customer Portal
- Location: https://access.redhat.com/downloads/
- Product: Red Hat Enterprise Linux
- Type: KVM Guest Image
-
SLES: Download from SUSE Customer Center
- Location: https://scc.suse.com/
- Product: SUSE Linux Enterprise Server
- Type: Cloud Image
-
Place downloaded image at:
/var/lib/libvirt/images/<cache_name> -
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 <vm_name> - IP assigned:
virsh domifaddr <vm_name> - SSH accessible:
ssh -J grokbox ansible@<IP> - Cloud-init complete:
cloud-init status - Firewall enabled:
sudo ufw statusorsudo 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
- Validate → Check distribution and VM name
- Install → Install required packages on hypervisor
- Download → Download distribution cloud image
- Verify → Validate image checksums
- Storage → Create VM disk from cloud image
- Cloud-Init → Generate configuration for OS family
- Deploy → Create and start VM with virt-install
- Validate → Verify SSH and system status
- Cleanup → Remove temporary files
Important Paths
- Cloud Images:
/var/lib/libvirt/images/*.qcow2 - VM Disks:
/var/lib/libvirt/images/<vm_name>.qcow2 - Cloud-Init ISO:
/var/lib/libvirt/images/<vm_name>-cloud-init.iso - VM Config:
/etc/libvirt/qemu/<vm_name>.xml
Emergency Access
If SSH fails, use console:
virsh console <vm_name>
# 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