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
This commit is contained in:
380
cheatsheets/deploy-debian-lvm-netinst.md
Normal file
380
cheatsheets/deploy-debian-lvm-netinst.md
Normal file
@@ -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@<VM_IP>
|
||||
|
||||
# Add to ~/.ssh/config
|
||||
Host debian-lvm
|
||||
HostName <VM_IP>
|
||||
User ansible
|
||||
ProxyJump grokbox
|
||||
StrictHostKeyChecking accept-new
|
||||
```
|
||||
|
||||
### Verify LVM Configuration
|
||||
```bash
|
||||
# SSH to VM
|
||||
ssh -J grokbox ansible@<VM_IP>
|
||||
|
||||
# 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@<VM_IP>
|
||||
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@<VM_IP> "dpkg -l | grep lvm2"
|
||||
|
||||
# Check if VG exists
|
||||
ssh ansible@<VM_IP> "sudo vgs"
|
||||
|
||||
# Manual LVM setup (if needed)
|
||||
ssh ansible@<VM_IP> "sudo pvcreate /dev/vda2"
|
||||
ssh ansible@<VM_IP> "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@<VM_IP>`
|
||||
- [ ] 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
|
||||
286
cheatsheets/deploy-debian12-vm.md
Normal file
286
cheatsheets/deploy-debian12-vm.md
Normal file
@@ -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@<VM_IP>
|
||||
|
||||
# Direct SSH (from grokbox)
|
||||
ssh ansible@<VM_IP>
|
||||
```
|
||||
|
||||
### 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_IP>
|
||||
```
|
||||
|
||||
### 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@<VM_IP>
|
||||
|
||||
# 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@<VM_IP>`
|
||||
- [ ] 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
|
||||
411
cheatsheets/deploy-linux-vm-lvm.md
Normal file
411
cheatsheets/deploy-linux-vm-lvm.md
Normal file
@@ -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 <vm_name>"
|
||||
```
|
||||
|
||||
### Access VM
|
||||
```bash
|
||||
ssh -J grokbox ansible@<VM_IP>
|
||||
```
|
||||
|
||||
### Verify LVM Configuration
|
||||
```bash
|
||||
# Check LVM status
|
||||
ssh -J grokbox ansible@<VM_IP> "sudo pvs && sudo vgs && sudo lvs"
|
||||
|
||||
# Check disk layout
|
||||
ssh -J grokbox ansible@<VM_IP> "lsblk"
|
||||
|
||||
# View fstab
|
||||
ssh -J grokbox ansible@<VM_IP> "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@<VM_IP> "sudo reboot"
|
||||
|
||||
# Wait ~1 minute, then verify mounts
|
||||
ssh -J grokbox ansible@<VM_IP> "df -h"
|
||||
```
|
||||
|
||||
After reboot, verify all LVM volumes are mounted:
|
||||
```bash
|
||||
ssh -J grokbox ansible@<VM_IP> "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@<VM_IP> "sudo lvextend -L +5G /dev/vg_system/lv_var"
|
||||
ssh ansible@<VM_IP> "sudo resize2fs /dev/vg_system/lv_var"
|
||||
|
||||
# Use all remaining free space
|
||||
ssh ansible@<VM_IP> "sudo lvextend -l +100%FREE /dev/vg_system/lv_var"
|
||||
ssh ansible@<VM_IP> "sudo resize2fs /dev/vg_system/lv_var"
|
||||
```
|
||||
|
||||
### Create New Logical Volume
|
||||
```bash
|
||||
ssh ansible@<VM_IP> "sudo lvcreate -L 5G -n lv_app vg_system"
|
||||
ssh ansible@<VM_IP> "sudo mkfs.ext4 /dev/vg_system/lv_app"
|
||||
ssh ansible@<VM_IP> "sudo mkdir -p /opt/app"
|
||||
ssh ansible@<VM_IP> "sudo mount /dev/vg_system/lv_app /opt/app"
|
||||
|
||||
# Add to fstab
|
||||
ssh ansible@<VM_IP> "echo '/dev/vg_system/lv_app /opt/app ext4 defaults 0 2' | sudo tee -a /etc/fstab"
|
||||
```
|
||||
|
||||
### LVM Snapshots
|
||||
```bash
|
||||
# Create snapshot
|
||||
ssh ansible@<VM_IP> "sudo lvcreate -L 2G -s -n lv_var_snapshot /dev/vg_system/lv_var"
|
||||
|
||||
# Mount snapshot
|
||||
ssh ansible@<VM_IP> "sudo mkdir -p /mnt/snapshot"
|
||||
ssh ansible@<VM_IP> "sudo mount /dev/vg_system/lv_var_snapshot /mnt/snapshot"
|
||||
|
||||
# Remove snapshot
|
||||
ssh ansible@<VM_IP> "sudo umount /mnt/snapshot"
|
||||
ssh ansible@<VM_IP> "sudo lvremove /dev/vg_system/lv_var_snapshot"
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### LVM Configuration Failed
|
||||
```bash
|
||||
# Check if second disk is attached
|
||||
ssh grokbox "virsh domblklist <vm_name>"
|
||||
|
||||
# Check disk visibility on VM
|
||||
ssh ansible@<VM_IP> "lsblk"
|
||||
|
||||
# Manually run LVM setup
|
||||
ssh ansible@<VM_IP> "sudo pvcreate /dev/vdb"
|
||||
ssh ansible@<VM_IP> "sudo vgcreate vg_system /dev/vdb"
|
||||
```
|
||||
|
||||
### Mounts Not Active After Reboot
|
||||
```bash
|
||||
# Check fstab entries
|
||||
ssh ansible@<VM_IP> "cat /etc/fstab | grep vg_system"
|
||||
|
||||
# Manually mount all
|
||||
ssh ansible@<VM_IP> "sudo mount -a"
|
||||
|
||||
# Check for errors
|
||||
ssh ansible@<VM_IP> "dmesg | tail -30"
|
||||
```
|
||||
|
||||
### Data Migration Issues
|
||||
```bash
|
||||
# Check data was copied
|
||||
ssh ansible@<VM_IP> "sudo du -sh /var"
|
||||
ssh ansible@<VM_IP> "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@<VM_IP> "getenforce"
|
||||
|
||||
# View denials
|
||||
ssh ansible@<VM_IP> "sudo ausearch -m avc -ts recent"
|
||||
|
||||
# Relabel filesystem
|
||||
ssh ansible@<VM_IP> "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 <vm_name>"
|
||||
ssh grokbox "virsh shutdown <vm_name>"
|
||||
ssh grokbox "virsh destroy <vm_name>"
|
||||
|
||||
# Status
|
||||
ssh grokbox "virsh dominfo <vm_name>"
|
||||
ssh grokbox "virsh list --all"
|
||||
|
||||
# Console
|
||||
ssh grokbox "virsh console <vm_name>"
|
||||
|
||||
# Delete
|
||||
ssh grokbox "virsh destroy <vm_name>"
|
||||
ssh grokbox "virsh undefine <vm_name> --remove-all-storage"
|
||||
```
|
||||
|
||||
## Validation Checklist
|
||||
|
||||
After deployment and reboot:
|
||||
|
||||
- [ ] VM running: `virsh list | grep <vm_name>`
|
||||
- [ ] IP assigned: `virsh domifaddr <vm_name>`
|
||||
- [ ] SSH accessible: `ssh -J grokbox ansible@<VM_IP>`
|
||||
- [ ] 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/<vm_name>.qcow2`
|
||||
- VM LVM disk: `/var/lib/libvirt/images/<vm_name>-lvm.qcow2`
|
||||
- Cloud-init ISO: `/var/lib/libvirt/images/<vm_name>-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
|
||||
287
cheatsheets/deploy-linux-vm-role.md
Normal file
287
cheatsheets/deploy-linux-vm-role.md
Normal file
@@ -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 <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
|
||||
```bash
|
||||
# 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
|
||||
```bash
|
||||
# Check GSSAPI disabled
|
||||
ssh -J grokbox ansible@<VM_IP> "sudo sshd -T | grep -i gssapi"
|
||||
|
||||
# Should show:
|
||||
# gssapiauthentication no
|
||||
# gssapicleanupcredentials no
|
||||
```
|
||||
|
||||
### Check Security Features
|
||||
```bash
|
||||
# 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
|
||||
|
||||
```bash
|
||||
# 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
|
||||
```bash
|
||||
# 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
|
||||
```bash
|
||||
# Get VM IP
|
||||
virsh domifaddr <vm_name>
|
||||
|
||||
# Check network
|
||||
virsh net-list
|
||||
virsh net-dhcp-leases default
|
||||
```
|
||||
|
||||
### LVM Issues
|
||||
```bash
|
||||
# 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`
|
||||
502
cheatsheets/deploy-linux-vm.md
Normal file
502
cheatsheets/deploy-linux-vm.md
Normal file
@@ -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 <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
|
||||
|
||||
```bash
|
||||
# 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
|
||||
```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 <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)
|
||||
```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 <port>
|
||||
|
||||
# RHEL/SUSE
|
||||
sudo firewall-cmd --list-all
|
||||
sudo firewall-cmd --permanent --add-service=<service>
|
||||
sudo firewall-cmd --reload
|
||||
```
|
||||
|
||||
### Package Manager Issues
|
||||
|
||||
```bash
|
||||
# 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:
|
||||
```bash
|
||||
# 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:
|
||||
|
||||
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/<cache_name>
|
||||
```
|
||||
|
||||
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 <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 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/<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:
|
||||
```bash
|
||||
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`
|
||||
212
cheatsheets/inventory.md
Normal file
212
cheatsheets/inventory.md
Normal file
@@ -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 <inventory> --list
|
||||
|
||||
# Show as graph
|
||||
ansible-inventory -i <inventory> --graph
|
||||
|
||||
# Specific host details
|
||||
ansible-inventory -i <inventory> --host <hostname>
|
||||
```
|
||||
|
||||
### Test Connectivity
|
||||
```bash
|
||||
# Ping all hosts
|
||||
ansible all -i <inventory> -m ping
|
||||
|
||||
# Ping specific group
|
||||
ansible kvm_guests -i <inventory> -m ping
|
||||
|
||||
# Verbose output
|
||||
ansible all -i <inventory> -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 <inventory> --limit kvm_guests site.yml
|
||||
|
||||
# Limit to specific host
|
||||
ansible-playbook -i <inventory> --limit pihole site.yml
|
||||
|
||||
# Multiple limits
|
||||
ansible-playbook -i <inventory> --limit "dns_servers:mail_servers" site.yml
|
||||
```
|
||||
|
||||
## Variable Precedence
|
||||
|
||||
From lowest to highest:
|
||||
1. `group_vars/all.yml`
|
||||
2. `group_vars/<group_name>.yml`
|
||||
3. `host_vars/<hostname>.yml`
|
||||
4. Playbook vars
|
||||
5. Extra vars (`-e`)
|
||||
|
||||
## Debugging
|
||||
|
||||
### Validate Inventory
|
||||
```bash
|
||||
# Syntax check
|
||||
ansible-inventory -i <inventory> --list > /dev/null
|
||||
|
||||
# YAML validation
|
||||
yamllint inventories/development/hosts.yml
|
||||
```
|
||||
|
||||
### Connection Test
|
||||
```bash
|
||||
# Test SSH connectivity
|
||||
ansible all -i <inventory> -m ping -vvv
|
||||
|
||||
# Check Python interpreter
|
||||
ansible all -i <inventory> -m setup -a "filter=ansible_python_version"
|
||||
|
||||
# Verify become/sudo
|
||||
ansible all -i <inventory> -m shell -a "whoami" --become
|
||||
```
|
||||
|
||||
### View Effective Variables
|
||||
```bash
|
||||
# All variables for a host
|
||||
ansible-inventory -i <inventory> --host <hostname> --yaml
|
||||
|
||||
# Specific variable
|
||||
ansible <hostname> -i <inventory> -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 <inventory> -m ping
|
||||
|
||||
# Gather facts
|
||||
ansible all -i <inventory> -m setup --tree /tmp/facts
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**See also:** `/opt/ansible/docs/inventory.md` for complete documentation
|
||||
413
cheatsheets/test-deploy-linux-vm-role.md
Normal file
413
cheatsheets/test-deploy-linux-vm-role.md
Normal file
@@ -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@<VM_IP>
|
||||
```
|
||||
|
||||
### Verify LVM Configuration
|
||||
```bash
|
||||
# Check LVM status
|
||||
ssh -J grokbox ansible@<VM_IP> "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@<VM_IP> "sudo sshd -T | grep -i gssapi"
|
||||
|
||||
# Expected output:
|
||||
# gssapiauthentication no
|
||||
# gssapicleanupcredentials no
|
||||
```
|
||||
|
||||
### Verify Security Features
|
||||
```bash
|
||||
# Check firewall (Debian)
|
||||
ssh -J grokbox ansible@<VM_IP> "sudo ufw status"
|
||||
|
||||
# Check SELinux (RHEL - if testing RHEL family)
|
||||
ssh -J grokbox ansible@<VM_IP> "getenforce"
|
||||
# Expected: Enforcing
|
||||
```
|
||||
|
||||
### Reboot and Verify LVM Mounts
|
||||
```bash
|
||||
# Reboot test VM
|
||||
ssh -J grokbox ansible@<VM_IP> "sudo reboot"
|
||||
|
||||
# Wait ~1 minute, then verify all mounts
|
||||
ssh -J grokbox ansible@<VM_IP> "df -h && lsblk"
|
||||
|
||||
# Check all LVM volumes are mounted
|
||||
ssh -J grokbox ansible@<VM_IP> "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@<VM_IP>`
|
||||
|
||||
### 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@<VM_IP> "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@<VM_IP>
|
||||
|
||||
# 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@<VM_IP> "ls -la /etc/ssh/sshd_config.d/"
|
||||
|
||||
# View security config
|
||||
ssh -J grokbox ansible@<VM_IP> "cat /etc/ssh/sshd_config.d/99-security.conf"
|
||||
|
||||
# Restart SSH service
|
||||
ssh -J grokbox ansible@<VM_IP> "sudo systemctl restart sshd"
|
||||
|
||||
# Test again
|
||||
ssh -J grokbox ansible@<VM_IP> "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
|
||||
Reference in New Issue
Block a user