modified: README.md
new file: README_NEW.md
This commit is contained in:
365
README.md
365
README.md
@@ -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 }}"
|
```
|
||||||
|
|
||||||
# Cloud‑Init 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 & Cloud‑Init 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"
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Cloud‑Init 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 post‑deployment provisioning (Ansible SSH into clones)
|
- GPU passthrough (PCI or VirtIO)
|
||||||
- Publish as a Galaxy‑ready 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
347
README_NEW.md
Normal file
@@ -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@<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.
|
||||||
Reference in New Issue
Block a user