modified: README.md

new file:   README_NEW.md
This commit is contained in:
2025-11-15 17:37:15 +01:00
parent f62750fe2f
commit 0a8f5c6124
2 changed files with 624 additions and 88 deletions

365
README.md
View File

@@ -36,133 +36,322 @@ ANSIBLE_PROXMOX_VM/
## Requirements ## Requirements
- Proxmox API / Environment - Proxmox VE installed and accessible
- Role runs on the Proxmox host via localhost, using `qm` CLI commands. - Role runs on the Proxmox host via localhost, using `qm` CLI commands
- Ansible must have SSH access to the Proxmox node. - Ansible must have SSH access to the Proxmox node
- User must have permission to run `qm` commands (root recommended). - User must have permission to run `qm` commands (root recommended)
- Proxmox storage pool such as `local-lvm`. - Proxmox storage pool configured (e.g., `local-lvm`)
- Snippets storage enabled for Cloud-Init (`Datacenter → Storage`)
## Debian Cloud Image ## Quick Start
The image is automatically downloaded if not present:
### 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 ```yaml
# Base VM settings vm_id: 150 # Unique Proxmox VM ID (≥100)
vm_id: 150 hostname: debian-template-base # VM hostname
hostname: debian-template-base memory: 4096 # RAM in MB
memory: 4096 cores: 4 # CPU cores
cores: 4 cpu_type: host # CPU type (host, kvm64, etc.)
bridge: vmbr0 bridge: vmbr0 # Network bridge
storage: local-lvm storage: local-lvm # Storage pool
mac_address: "DE:AD:BE:EF:44:55" ```
cpu_type: host
# Networking ### Networking
ip_mode: dhcp # or 'static' ```yaml
ip_address: "192.168.1.60/24" ip_mode: dhcp # 'dhcp' or 'static'
gateway: "192.168.1.1" ip_address: "192.168.1.60/24" # Static IP (CIDR, if static)
gateway: "192.168.1.1" # Gateway IP
dns: dns:
- "1.1.1.1" - "1.1.1.1"
- "8.8.8.8" - "8.8.8.8" # DNS servers
ipconfig0: "{{ 'ip=dhcp' if ip_mode == 'dhcp' else 'ip=' + ip_address + ',gw=' + gateway }}" ```
# CloudInit user ### Cloud-Init
ci_user: debian ```yaml
ci_password: "SecurePass123" ci_user: debian # Default user
ssh_key_path: "~/.ssh/id_rsa.pub" ci_password: "SecurePass123" # Password (use Vault in production!)
timezone: "Europe/Berlin" 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 # Disk
resize_disk: true resize_disk: true
resize_size: "16G" resize_size: "16G"
# GPU passthrough # Template & Clones
gpu_passthrough: false make_template: true # Convert VM to template
gpu_device: "0000:01:00.0" create_clones: true # Create clones from template
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"
``` ```
### 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 ## Usage
### Include the role in a playbook ### 1. Include in a Playbook
```yaml ```yaml
- hosts: proxmox - hosts: proxmox_host
become: true become: true
roles: roles:
- ANSIBLE_PROXMOX_VM - ansible_proxmox_vm
``` ```
### Run directly ### 2. Run Directly
```bash ```bash
ansible-playbook tasks/main.yml -i inventory 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 <clone_id>` # Add clones to existing template
2. Set hostname & CloudInit netplan ansible-playbook tasks/main.yml --tags clones
3. Start the VM
### Example `clones` section # Skip re-downloading image
ansible-playbook tasks/main.yml --skip-tags image
```yaml
clones:
- id: 301
hostname: app01
ip: "192.168.1.81/24"
gateway: "192.168.1.1"
``` ```
## CloudInit Templates ## Playbook Stages
### `templates/cloudinit_userdata.yaml.j2` The playbook executes in 6 stages:
Defines: | Stage | Task | Purpose |
- `users` |-------|------|---------|
- SSH key | 1 | `preflight-checks.yml` | Validate environment (20+ checks) |
- password | 2 | `download-image.yml` | Download/cache Debian image |
- timezone | 3 | `create-vm.yml` | Create base VM |
- package updates | 4 | `configure-vm.yml` | Configure disk, network, Cloud-Init |
- custom commands | 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: ## Key Improvements
- default packages
- DNS (optional)
## 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`). ### ✅ Idempotency
- If cloning fails with an invalid IP, check the format: `"192.168.1.81/24"`. - Safe to re-run multiple times
- Both SSH keys and password login are supported (`ssh_pwauth: true`). - Already-created VMs/templates are skipped
- If GPU passthrough is enabled, ensure the host kernel is configured for IOMMU. - 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 ### ✅ Advanced Features
- Validate clone IDs - UEFI/TPM 2.0 support
- Automated postdeployment provisioning (Ansible SSH into clones) - GPU passthrough (PCI or VirtIO)
- Publish as a Galaxyready role - 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@<vm-ip>
# 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.

347
README_NEW.md Normal file
View File

@@ -0,0 +1,347 @@
# Ansible Role: Proxmox VM → Template → Clones (CloudInit)
**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@<vm-ip>
# 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.