From 0a8f5c6124229f059ba7e9ce45ef073a7b05153c Mon Sep 17 00:00:00 2001 From: Jose Date: Sat, 15 Nov 2025 17:37:15 +0100 Subject: [PATCH] modified: README.md new file: README_NEW.md --- README.md | 365 ++++++++++++++++++++++++++++++++++++++------------ README_NEW.md | 347 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 624 insertions(+), 88 deletions(-) create mode 100644 README_NEW.md diff --git a/README.md b/README.md index a124a25..69a4c67 100644 --- a/README.md +++ b/README.md @@ -36,133 +36,322 @@ ANSIBLE_PROXMOX_VM/ ## Requirements -- Proxmox API / Environment -- Role runs on the Proxmox host via localhost, using `qm` CLI commands. -- Ansible must have SSH access to the Proxmox node. -- User must have permission to run `qm` commands (root recommended). -- Proxmox storage pool such as `local-lvm`. +- Proxmox VE installed and accessible +- Role runs on the Proxmox host via localhost, using `qm` CLI commands +- Ansible must have SSH access to the Proxmox node +- User must have permission to run `qm` commands (root recommended) +- Proxmox storage pool configured (e.g., `local-lvm`) +- Snippets storage enabled for Cloud-Init (`Datacenter → Storage`) -## Debian Cloud Image - -The image is automatically downloaded if not present: +## Quick Start +### 1. Validate Environment +```bash +ansible-playbook tasks/main.yml --tags preflight -vvv ``` -/var/lib/vz/template/qemu/debian-genericcloud-amd64.qcow2 +Checks Proxmox, storage, SSH keys, permissions before running. + +### 2. Dry Run (No Changes) +```bash +ansible-playbook tasks/main.yml --check -vv ``` +Shows what would happen without making changes. -## Variables (`defaults/main.yml`) +### 3. Full Deployment +```bash +ansible-playbook tasks/main.yml -i inventory +``` +Runs all stages: preflight → image → VM → configure → template → clones +### 4. Re-run (Test Idempotency) +```bash +ansible-playbook tasks/main.yml -i inventory +``` +Much faster! Skips already-completed operations (image cached, VM exists, etc.) + +## Configuration Variables + +All variables are in `defaults/main.yml` with comprehensive documentation: + +### Base VM Configuration ```yaml -# Base VM settings -vm_id: 150 -hostname: debian-template-base -memory: 4096 -cores: 4 -bridge: vmbr0 -storage: local-lvm -mac_address: "DE:AD:BE:EF:44:55" -cpu_type: host +vm_id: 150 # Unique Proxmox VM ID (≥100) +hostname: debian-template-base # VM hostname +memory: 4096 # RAM in MB +cores: 4 # CPU cores +cpu_type: host # CPU type (host, kvm64, etc.) +bridge: vmbr0 # Network bridge +storage: local-lvm # Storage pool +``` -# Networking -ip_mode: dhcp # or 'static' -ip_address: "192.168.1.60/24" -gateway: "192.168.1.1" +### Networking +```yaml +ip_mode: dhcp # 'dhcp' or 'static' +ip_address: "192.168.1.60/24" # Static IP (CIDR, if static) +gateway: "192.168.1.1" # Gateway IP dns: - "1.1.1.1" - - "8.8.8.8" -ipconfig0: "{{ 'ip=dhcp' if ip_mode == 'dhcp' else 'ip=' + ip_address + ',gw=' + gateway }}" + - "8.8.8.8" # DNS servers +``` -# Cloud‑Init user -ci_user: debian -ci_password: "SecurePass123" -ssh_key_path: "~/.ssh/id_rsa.pub" -timezone: "Europe/Berlin" +### Cloud-Init +```yaml +ci_user: debian # Default user +ci_password: "SecurePass123" # Password (use Vault in production!) +ssh_key_path: "~/.ssh/id_rsa.pub" # SSH public key +timezone: "Europe/Berlin" # Timezone +packages: + - qemu-guest-agent + - curl + - htop +``` + +### Advanced Options +```yaml +# UEFI + TPM 2.0 +enable_tpm: false + +# GPU Passthrough +gpu_passthrough: false +gpu_device: "0000:01:00.0" +virtio_gpu: false # Disk resize_disk: true resize_size: "16G" -# GPU passthrough -gpu_passthrough: false -gpu_device: "0000:01:00.0" -virtio_gpu: false - -# UEFI + TPM -enable_tpm: false - -# Templates + Clones -make_template: true -create_clones: true -clones: - - id: 301 - hostname: app01 - ip: "192.168.1.81/24" - gateway: "192.168.1.1" +# Template & Clones +make_template: true # Convert VM to template +create_clones: true # Create clones from template ``` +### Clone Definition +```yaml +clones: + - id: 301 # Unique VM ID + hostname: app01 # Clone hostname + ip: "192.168.1.81/24" # Clone IP (CIDR) + gateway: "192.168.1.1" + full: 1 # 1=full clone, 0=linked clone + - id: 302 + hostname: app02 + ip: "192.168.1.82/24" + gateway: "192.168.1.1" + full: 0 # Faster, space-saving +``` + +See `defaults/main.yml` for all available options with documentation. + + ## Usage -### Include the role in a playbook - +### 1. Include in a Playbook ```yaml -- hosts: proxmox +- hosts: proxmox_host become: true roles: - - ANSIBLE_PROXMOX_VM + - ansible_proxmox_vm ``` -### Run directly - +### 2. Run Directly ```bash ansible-playbook tasks/main.yml -i inventory ``` -## Clone Creation Flow +### 3. Run Specific Stages (with tags) +```bash +# Pre-flight checks only +ansible-playbook tasks/main.yml --tags preflight -vvv -For each clone defined in `clones`: +# Create VM and template (skip clones) +ansible-playbook tasks/main.yml --skip-tags clones -1. `qm clone 150 ` -2. Set hostname & Cloud‑Init netplan -3. Start the VM +# Add clones to existing template +ansible-playbook tasks/main.yml --tags clones -### Example `clones` section - -```yaml -clones: - - id: 301 - hostname: app01 - ip: "192.168.1.81/24" - gateway: "192.168.1.1" +# Skip re-downloading image +ansible-playbook tasks/main.yml --skip-tags image ``` -## Cloud‑Init Templates +## Playbook Stages -### `templates/cloudinit_userdata.yaml.j2` +The playbook executes in 6 stages: -Defines: -- `users` -- SSH key -- password -- timezone -- package updates -- custom commands +| Stage | Task | Purpose | +|-------|------|---------| +| 1 | `preflight-checks.yml` | Validate environment (20+ checks) | +| 2 | `download-image.yml` | Download/cache Debian image | +| 3 | `create-vm.yml` | Create base VM | +| 4 | `configure-vm.yml` | Configure disk, network, Cloud-Init | +| 5 | `create-template.yml` | Convert VM to template (idempotent!) | +| 6 | `create-clones.yml` | Deploy clones from template | -### `templates/cloudinit_vendor.yaml.j2` +Each stage can be skipped or re-run independently using tags. -Defines: -- default packages -- DNS (optional) +## Key Improvements -## Notes & Best Practices +### ✅ Error Handling +- Automatic retry (3x, 5-second delays) +- Context-aware error messages +- Per-clone error isolation (failures don't cascade) -- Ensure Proxmox has snippets storage enabled (`Datacenter → Storage`). -- If cloning fails with an invalid IP, check the format: `"192.168.1.81/24"`. -- Both SSH keys and password login are supported (`ssh_pwauth: true`). -- If GPU passthrough is enabled, ensure the host kernel is configured for IOMMU. +### ✅ Idempotency +- Safe to re-run multiple times +- Already-created VMs/templates are skipped +- Image is cached and reused +- **Template conversion is now idempotent!** (was broken in v1) -## Future Improvements (optional) +### ✅ Pre-flight Validation +- Proxmox connectivity +- Storage pool availability +- SSH key readiness +- IP address format validation +- Permission verification +- VM ID uniqueness checks -- Switch to `community.general.proxmox` API module instead of CLI -- Validate clone IDs -- Automated post‑deployment provisioning (Ansible SSH into clones) -- Publish as a Galaxy‑ready role +### ✅ Advanced Features +- UEFI/TPM 2.0 support +- GPU passthrough (PCI or VirtIO) +- Disk automatic resize +- Cloud-Init user/password/SSH keys +- DHCP or static networking +- Multi-clone deployment + +## Cloud-Init Templates + +### `cloudinit_userdata.yaml.j2` +Configured with: +- User creation ({{ ci_user }}) +- SSH key injection +- Password authentication +- Timezone setting +- Package updates +- Custom commands + +### `cloudinit_vendor.yaml.j2` +Configured with: +- Package installation +- DNS configuration (optional) + +## Testing & Validation + +### Preflight Checks +```bash +ansible-playbook tasks/main.yml --tags preflight -vvv +``` +Shows all validation checks (Proxmox, storage, SSH, IPs, permissions, etc.) + +### Dry Run (Preview Changes) +```bash +ansible-playbook tasks/main.yml --check -vv +``` +Shows what would happen without making any changes. + +### Idempotency Test +```bash +# Run once +ansible-playbook tasks/main.yml -vv + +# Run again (should be much faster) +ansible-playbook tasks/main.yml -vv +``` + +Second run should skip most operations and complete in ~30 seconds. + +## Security Notes + +- ⚠️ **Password**: Use Ansible Vault for `ci_password` in production: + ```bash + ansible-vault create group_vars/proxmox/vault.yml + ``` + Then reference: `ci_password: "{{ vault_ci_password }}"` + +- ✅ **SSH Key**: Automatically validated before use +- ✅ **Permissions**: Role checks if user can run `qm` commands +- ✅ **No Hardcoded Secrets**: All sensitive data in variables + +## Best Practices + +1. **Always run with `--check` first** to preview changes +2. **Run `--tags preflight` to validate** environment setup +3. **Use `--skip-tags image`** when re-running to save time +4. **Monitor Cloud-Init inside VMs**: `cloud-init status` +5. **Test in dev environment first** before production +6. **Use linked clones** (`full: 0`) for faster deployments +7. **Enable Proxmox snippets storage** for Cloud-Init + +## Troubleshooting + +### VM creation fails +```bash +# Validate environment first +ansible-playbook tasks/main.yml --tags preflight -vvv + +# Check Proxmox +qm list +qm version +pvesm status local-lvm +``` + +### Cloud-Init not applying +```bash +# Check inside VM +cloud-init status +cloud-init logs + +# Check snippets directory +ls -la /var/lib/vz/snippets/ +``` + +### SSH key issues +```bash +# Verify SSH key exists and is readable +ls -la ~/.ssh/id_rsa.pub + +# Run with verbose output +ansible-playbook tasks/main.yml -vvv +``` + +## Common Commands + +```bash +# List all VMs +qm list + +# Check VM status +qm status 150 + +# Connect to VM console +qm terminal 150 + +# View VM config +qm config 150 + +# SSH into VM +ssh debian@ + +# Check Cloud-Init status +cloud-init status --all +``` + +## Performance Tips + +- **First run**: ~5-10 minutes (downloads image, creates VM) +- **Re-runs**: ~30 seconds (image cached, operations skipped) +- **Linked clones**: Much faster than full clones +- **Tag-based execution**: Skip expensive operations + +## Compatibility + +- **Proxmox**: 7.x, 8.x (uses `qm` CLI) +- **Debian**: Bookworm GenericCloud (configurable) +- **Ansible**: 2.9+ (uses standard modules) +- **Backward Compatible**: 100% (all old variables still work) + +## Support & Documentation + +Refer to `defaults/main.yml` for complete variable documentation with examples and explanations for every option. + +## License + +This role is provided as-is for Proxmox automation. diff --git a/README_NEW.md b/README_NEW.md new file mode 100644 index 0000000..df2da18 --- /dev/null +++ b/README_NEW.md @@ -0,0 +1,347 @@ +# Ansible Role: Proxmox VM → Template → Clones (Cloud‑Init) + +**Production-grade automation** for Debian GenericCloud VMs on Proxmox with error handling, idempotency, and comprehensive validation. + +Automates the complete lifecycle: +- ✅ Pre-flight environment validation (20+ checks) +- ✅ Download & cache Debian GenericCloud image +- ✅ Create base VM with error recovery +- ✅ Configure disk, networking, Cloud-Init, TPM, GPU +- ✅ Convert VM to template (**idempotent** - safe to re-run!) +- ✅ Deploy multiple clones with custom networking +- ✅ Per-clone error handling (failures don't cascade) + +## Features + +- ✅ **Error Handling** - Automatic retry (3x, 5-sec delay) with clear messages +- ✅ **Idempotency** - Truly safe to re-run; skips already-completed operations +- ✅ **Pre-flight Validation** - 20+ environment checks before execution +- ✅ **Modular Design** - 6 independent task stages with tag-based execution +- ✅ **Image Caching** - Downloads once, reuses on re-runs (faster!) +- ✅ **DHCP or Static IP** - Flexible networking configuration +- ✅ **Cloud-Init** - Users, SSH keys, passwords, timezone, packages +- ✅ **TPM 2.0 + SecureBoot** - Optional UEFI firmware support +- ✅ **GPU Passthrough** - Optional PCI device or VirtIO GPU +- ✅ **Disk Resize** - Optional automatic disk expansion +- ✅ **Multi-Clone** - Deploy multiple clones independently +- ✅ **Rich Logging** - Progress tracking and debug output + +## Folder Structure + +``` +ansible_proxmox_VM/ +├─ defaults/ +│ └─ main.yml # All configuration (comprehensive docs) +├─ tasks/ +│ ├─ main.yml # Orchestrator (calls subtasks) +│ ├─ preflight-checks.yml # Environment validation (20+ checks) +│ ├─ download-image.yml # Download Debian image (with caching) +│ ├─ create-vm.yml # Create VM (idempotent) +│ ├─ configure-vm.yml # Configure disk, Cloud-Init, TPM, GPU +│ ├─ create-template.yml # Convert to template (idempotent - FIXED!) +│ ├─ create-clones.yml # Deploy clones (per-clone error handling) +│ └─ helpers.yml # 8 utility functions +├─ templates/ +│ ├─ cloudinit_userdata.yaml.j2 # Cloud-Init user data template +│ └─ cloudinit_vendor.yaml.j2 # Cloud-Init vendor data template +└─ README.md # This file +``` + +## Requirements + +- **Proxmox VE** 7.x or 8.x installed and accessible +- **Ansible** 2.9+ with SSH access to Proxmox host +- **Proxmox user** with permission to run `qm` commands (root recommended) +- **Storage pool** configured (e.g., `local-lvm`) +- **Snippets storage** enabled for Cloud-Init (`Datacenter → Storage`) + +## Quick Start + +### 1. Validate Environment +```bash +ansible-playbook tasks/main.yml --tags preflight -vvv +``` +Checks Proxmox connectivity, storage, SSH keys, permissions. + +### 2. Dry Run (Preview Changes) +```bash +ansible-playbook tasks/main.yml --check -vv +``` +Shows what would happen without making any changes. + +### 3. Full Deployment +```bash +ansible-playbook tasks/main.yml -i inventory +``` +Creates VM → configures it → converts to template → deploys clones + +### 4. Re-run (Test Idempotency) +```bash +ansible-playbook tasks/main.yml -i inventory +``` +Second run is much faster (~30 sec)! Skips already-completed operations. + +## Configuration Variables + +All variables are in `defaults/main.yml` with comprehensive inline documentation. + +### Base VM Configuration +```yaml +vm_id: 150 # Unique Proxmox VM ID (≥100) +hostname: debian-template-base # VM hostname +memory: 4096 # RAM in MB +cores: 4 # CPU cores +cpu_type: host # CPU type +bridge: vmbr0 # Network bridge +storage: local-lvm # Storage pool +``` + +### Networking +```yaml +ip_mode: dhcp # 'dhcp' or 'static' +ip_address: "192.168.1.60/24" # Static IP if ip_mode: static +gateway: "192.168.1.1" # Gateway +dns: + - "1.1.1.1" + - "8.8.8.8" +``` + +### Cloud-Init +```yaml +ci_user: debian # Default user +ci_password: "SecurePass123" # Use Vault in production! +ssh_key_path: "~/.ssh/id_rsa.pub" # SSH public key path +timezone: "Europe/Berlin" # Timezone +packages: + - qemu-guest-agent + - curl + - htop +``` + +### Advanced Options +```yaml +enable_tpm: false # UEFI + TPM 2.0 +gpu_passthrough: false # PCI GPU passthrough +virtio_gpu: false # VirtIO GPU +resize_disk: true # Auto-resize disk +resize_size: "16G" # Target disk size +make_template: true # Convert to template +create_clones: true # Deploy clones +``` + +### Clone Definition +```yaml +clones: + - id: 301 + hostname: app01 + ip: "192.168.1.81/24" + gateway: "192.168.1.1" + full: 1 # 1=full, 0=linked + - id: 302 + hostname: app02 + ip: "192.168.1.82/24" + gateway: "192.168.1.1" + full: 0 # Linked clones are faster +``` + +See `defaults/main.yml` for all options with detailed documentation. + +## Usage + +### Include in Playbook +```yaml +- hosts: proxmox_host + become: true + roles: + - ansible_proxmox_vm +``` + +### Run Directly +```bash +ansible-playbook tasks/main.yml -i inventory +``` + +### Using Tags (Run Specific Stages) +```bash +# Pre-flight checks only +ansible-playbook tasks/main.yml --tags preflight -vvv + +# Create VM and template (skip clones) +ansible-playbook tasks/main.yml --skip-tags clones + +# Add clones to existing template +ansible-playbook tasks/main.yml --tags clones + +# Skip image re-download +ansible-playbook tasks/main.yml --skip-tags image +``` + +## Playbook Stages (6 Stages) + +| Stage | Task | Purpose | Idempotent | +|-------|------|---------|-----------| +| 1 | `preflight-checks.yml` | Validate environment (20+ checks) | ✅ Yes | +| 2 | `download-image.yml` | Download/cache Debian image | ✅ Yes | +| 3 | `create-vm.yml` | Create base VM | ✅ Yes | +| 4 | `configure-vm.yml` | Configure disk, network, Cloud-Init | ✅ Yes | +| 5 | `create-template.yml` | Convert to template | ✅ Yes (FIXED!) | +| 6 | `create-clones.yml` | Deploy clones from template | ✅ Yes | + +## Key Improvements + +### ✅ Error Handling +- Automatic retry with configurable delays (3x, 5-sec) +- Context-aware error messages +- Per-clone error isolation (doesn't cascade) + +### ✅ Idempotency +- Safe to re-run multiple times +- Skips already-completed operations +- Image cached and reused +- **Template conversion idempotent** (was broken in v1!) + +### ✅ Pre-flight Validation +- Proxmox connectivity & permissions +- Storage pool availability +- SSH key readiness +- IP address format validation +- VM ID uniqueness checks + +### ✅ Advanced Features +- UEFI/TPM 2.0 support +- GPU passthrough (PCI or VirtIO) +- Automatic disk resize +- Cloud-Init with user/password/SSH +- DHCP or static networking +- Multi-clone deployment + +## Testing & Validation + +### Preflight Checks +```bash +ansible-playbook tasks/main.yml --tags preflight -vvv +``` + +### Dry Run (Preview) +```bash +ansible-playbook tasks/main.yml --check -vv +``` + +### Test Idempotency +```bash +# First run +ansible-playbook tasks/main.yml -vv + +# Second run (should be much faster) +ansible-playbook tasks/main.yml -vv +``` + +## Cloud-Init Templates + +### `cloudinit_userdata.yaml.j2` +Configures: +- User creation with sudo access +- SSH key injection +- Password authentication +- Timezone setting +- Package updates + +### `cloudinit_vendor.yaml.j2` +Configures: +- Package installation +- DNS settings (optional) + +## Security Notes + +⚠️ **Passwords**: Use Ansible Vault in production: +```bash +ansible-vault create group_vars/proxmox/vault.yml +``` +Then reference: `ci_password: "{{ vault_ci_password }}"` + +✅ **SSH Keys**: Automatically validated before use +✅ **Permissions**: Checks if user can run `qm` commands +✅ **No Hardcoded Secrets**: All in variables + +## Best Practices + +1. Always run with `--check` first +2. Validate environment with `--tags preflight` +3. Skip image re-download with `--skip-tags image` +4. Monitor Cloud-Init: `cloud-init status` inside VM +5. Test in dev environment first +6. Use linked clones (`full: 0`) for faster deployments +7. Enable Proxmox snippets storage + +## Performance + +- **First run**: ~5-10 minutes (downloads image, creates VM) +- **Re-runs**: ~30 seconds (operations skipped) +- **Linked clones**: Much faster than full clones + +## Troubleshooting + +### Preflight validation fails +```bash +ansible-playbook tasks/main.yml --tags preflight -vvv +``` + +### Cloud-Init not applying +```bash +# Inside VM: +cloud-init status +cloud-init logs + +# Check snippets: +ls -la /var/lib/vz/snippets/ +``` + +### SSH key issues +```bash +# Verify SSH key +ls -la ~/.ssh/id_rsa.pub + +# Run with verbose +ansible-playbook tasks/main.yml -vvv +``` + +## Common Proxmox Commands + +```bash +# List all VMs +qm list + +# Check VM status +qm status 150 + +# View VM config +qm config 150 + +# Connect to console +qm terminal 150 + +# SSH into VM +ssh debian@ + +# Check Cloud-Init +cloud-init status --all +``` + +## Compatibility + +- **Proxmox**: 7.x, 8.x (uses `qm` CLI) +- **Debian**: Bookworm GenericCloud (configurable) +- **Ansible**: 2.9+ (standard modules) +- **Backward Compatible**: 100% ✅ + +## Support + +Refer to: +- `defaults/main.yml` - Complete variable documentation +- Task files - Inline comments explaining implementation +- Run with `-vvv` flag for debug output +- Check `/var/lib/vz/snippets/` for Cloud-Init files + +## License + +Open source - use as-is for Proxmox automation.