Files
infra-automation/cheatsheets/deploy-linux-vm-role.md
Infrastructure Team 5ba666dfbf 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
2025-11-10 22:52:11 +01:00

6.7 KiB

Deploy Linux VM Role - Quick Reference

Quick Deployment

Basic Usage

# 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

# 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

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

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

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

---
- 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

---
- 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

# Get VM IP
ssh grokbox "virsh domifaddr <vm_name>"

# SSH to VM
ssh -J grokbox ansible@<VM_IP>

# Or add to ~/.ssh/config
Host myvm
    HostName <VM_IP>
    User ansible
    ProxyJump grokbox

Verify LVM

# Check LVM status
ssh -J grokbox ansible@<VM_IP> "sudo vgs && sudo lvs"

# Check mounts (after reboot)
ssh -J grokbox ansible@<VM_IP> "df -h && lsblk"

# Reboot VM to activate LVM mounts
ssh -J grokbox ansible@<VM_IP> "sudo reboot"

Verify SSH Hardening

# Check GSSAPI disabled
ssh -J grokbox ansible@<VM_IP> "sudo sshd -T | grep -i gssapi"

# Should show:
# gssapiauthentication no
# gssapicleanupcredentials no

Check Security Features

# Debian/Ubuntu - UFW status
ssh -J grokbox ansible@<VM_IP> "sudo ufw status"

# RHEL/Alma - Firewall and SELinux
ssh -J grokbox ansible@<VM_IP> "sudo firewall-cmd --list-all && getenforce"

# Check automatic updates
ssh -J grokbox ansible@<VM_IP> "systemctl status unattended-upgrades"  # Debian
ssh -J grokbox ansible@<VM_IP> "systemctl status dnf-automatic.timer"  # RHEL

VM Management

# Start/Stop/Status
virsh start <vm_name>
virsh shutdown <vm_name>
virsh destroy <vm_name>
virsh dominfo <vm_name>

# List VMs
virsh list --all

# Console access
virsh console <vm_name>

# Delete VM
virsh destroy <vm_name>
virsh undefine <vm_name> --remove-all-storage

Troubleshooting

Cloud-Init

# Check status
ssh -J grokbox ansible@<VM_IP> "cloud-init status --wait"

# View logs
ssh -J grokbox ansible@<VM_IP> "tail -f /var/log/cloud-init-output.log"

Network

# Get VM IP
virsh domifaddr <vm_name>

# Check network
virsh net-list
virsh net-dhcp-leases default

LVM Issues

# Check LVM configuration
ssh -J grokbox ansible@<VM_IP> "sudo pvs && sudo vgs && sudo lvs"

# Check fstab
ssh -J grokbox ansible@<VM_IP> "cat /etc/fstab"

# Manually mount if needed
ssh -J grokbox ansible@<VM_IP> "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/<vm_name>.qcow2
  • LVM disk: /var/lib/libvirt/images/<vm_name>-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 <vm_name>
  • IP assigned: virsh domifaddr <vm_name>
  • SSH accessible: ssh -J grokbox ansible@<VM_IP>
  • 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