Files
2025-11-30 08:47:38 +08:00

4.4 KiB

Ansible Proxmox Gotchas

Common issues when using Ansible with Proxmox VE.

1. Token ID Format

Wrong:

api_token_id: mytoken

Correct:

api_token_id: mytoken  # Just the token name, NOT user@realm!tokenname

The module combines api_user and api_token_id internally.

2. VMID Required for Most Operations

Unlike Terraform, you must always specify vmid:

# Won't auto-generate VMID
- name: Create VM
  community.general.proxmox_kvm:
    # ... auth ...
    vmid: 300  # REQUIRED - no auto-assignment
    name: myvm

To find next available VMID:

- name: Get cluster resources
  ansible.builtin.uri:
    url: "https://{{ proxmox_api_host }}:8006/api2/json/cluster/resources"
    headers:
      Authorization: "PVEAPIToken={{ proxmox_api_user }}!{{ proxmox_api_token_id }}={{ proxmox_api_token_secret }}"
    validate_certs: false
  register: resources

- name: Calculate next VMID
  ansible.builtin.set_fact:
    next_vmid: "{{ (resources.json.data | selectattr('vmid', 'defined') | map(attribute='vmid') | max) + 1 }}"

3. Node Parameter Required

Must specify which node to operate on:

- name: Create VM
  community.general.proxmox_kvm:
    # ... auth ...
    node: joseph  # REQUIRED - which Proxmox node
    vmid: 300

4. Clone vs Create

Cloning requires different parameters than creating:

# CLONE from template
- name: Clone VM
  community.general.proxmox_kvm:
    # ... auth ...
    node: joseph
    vmid: 300
    name: myvm
    clone: tmpl-ubuntu-2404-standard  # Template name or VMID
    full: true

# CREATE new (less common)
- name: Create VM
  community.general.proxmox_kvm:
    # ... auth ...
    node: joseph
    vmid: 300
    name: myvm
    ostype: l26
    scsihw: virtio-scsi-pci
    bootdisk: scsi0
    scsi:
      scsi0: 'local-lvm:32,format=raw'

5. Async Operations

Large operations (clone, snapshot) can timeout. Use async:

- name: Clone large VM
  community.general.proxmox_kvm:
    # ... auth ...
    clone: large-template
    vmid: 300
    timeout: 600  # Module timeout
  async: 900      # Ansible async timeout
  poll: 10        # Check every 10 seconds

6. State Idempotency

state: present doesn't update existing VMs:

# This WON'T change cores on existing VM
- name: Create/update VM
  community.general.proxmox_kvm:
    # ... auth ...
    vmid: 300
    cores: 4      # Ignored if VM exists
    state: present

To modify existing VMs, use proxmox_kvm with update: true (Ansible 2.14+) or use the API directly.

7. Network Interface Format (LXC)

LXC containers use a specific JSON-like string format:

# WRONG
netif:
  net0:
    bridge: vmbr0
    ip: dhcp

# CORRECT
netif: '{"net0":"name=eth0,bridge=vmbr0,ip=dhcp"}'

# Multiple interfaces
netif: '{"net0":"name=eth0,bridge=vmbr0,ip=dhcp","net1":"name=eth1,bridge=vmbr12,ip=dhcp"}'

8. Disk Resize Only Grows

proxmox_disk resize only increases size:

# This adds 20G to current size
- name: Grow disk
  community.general.proxmox_disk:
    # ... auth ...
    vmid: 300
    disk: scsi0
    size: +20G     # Relative increase
    state: resized

# NOT possible to shrink

9. Template vs VM States

Templates don't support all states:

# Can't start a template
- name: Start template
  community.general.proxmox_kvm:
    vmid: 100
    state: started  # FAILS - templates can't run

Convert template to VM first if needed.

10. Collection Version Matters

Module parameters change between versions. Check installed version:

ansible-galaxy collection list | grep community.general

Update if needed:

ansible-galaxy collection install community.general --upgrade

11. Cloud-Init Not Supported

Unlike Terraform's Proxmox provider, the Ansible modules have limited cloud-init support. For cloud-init VMs:

  1. Clone template with cloud-init already configured
  2. Use API calls to set cloud-init parameters
  3. Or configure post-boot with Ansible
# Workaround: Use URI module for cloud-init config
- name: Set cloud-init IP
  ansible.builtin.uri:
    url: "https://{{ proxmox_api_host }}:8006/api2/json/nodes/{{ node }}/qemu/{{ vmid }}/config"
    method: PUT
    headers:
      Authorization: "PVEAPIToken={{ proxmox_api_user }}!{{ proxmox_api_token_id }}={{ proxmox_api_token_secret }}"
    body_format: form-urlencoded
    body:
      ipconfig0: "ip=192.168.1.100/24,gw=192.168.1.1"
      ciuser: ubuntu
    validate_certs: false