From ansible-workflows
Automates Proxmox VE with Ansible's community.proxmox collection for creating VMs/templates, managing clusters/users/ACLs/storage, preferring native modules over CLI like pvecm/qm.
npx claudepluginhub basher83/lunar-claude --plugin ansible-workflowsThis skill uses the workspace's default tool permissions.
Expert Proxmox automation using community.proxmox collection with minimal CLI usage.
Manages Proxmox VE via REST API: create/clone/start/stop VMs and LXC containers, handle snapshots, backups, storage, templates using curl and jq. For Proxmox infrastructure tasks.
Provides golden rules for Ansible: uv run execution, FQCN modules, idempotency, shell best practices, sensitive task handling, and module selection guidance. Use for playbooks, tasks, ansible-playbook, or collections.
Provides scripts and guidance for operating Sidero Omni Proxmox providers in Talos Kubernetes clusters: check status, restart, view logs, debug registration, create machine classes, configure storage selectors.
Share bugs, ideas, or general feedback.
Expert Proxmox automation using community.proxmox collection with minimal CLI usage.
Use community.proxmox modules when available:
| Operation | Use Module | NOT CLI |
|---|---|---|
| Create VM | community.proxmox.proxmox_kvm | qm create |
| Clone VM | community.proxmox.proxmox_kvm | qm clone |
| Manage users | community.proxmox.proxmox_user | pveum user |
| Manage groups | community.proxmox.proxmox_group | pveum group |
| Manage pools | community.proxmox.proxmox_pool | pveum pool |
| Manage ACLs | community.proxmox.proxmox_acl | pveum acl |
| Storage | community.proxmox.proxmox_storage | pvesm |
Some operations lack native modules:
| Operation | Requires CLI | Reason |
|---|---|---|
| Cluster create | pvecm create | No module exists |
| Cluster join | pvecm add | No module exists |
| CEPH init | pveceph init | Complex workflow |
| CEPH OSD | pveceph osd create | Complex workflow |
- name: Create VM from template
community.proxmox.proxmox_kvm:
api_host: "{{ proxmox_api_host }}"
api_user: "{{ proxmox_api_user }}"
api_token_id: "{{ proxmox_token_id }}"
api_token_secret: "{{ proxmox_token_secret }}"
node: "{{ proxmox_node }}"
vmid: "{{ vm_id }}"
name: "{{ vm_name }}"
clone: "{{ template_name }}"
full: true
storage: local-lvm
memory: "{{ vm_memory | default(4096) }}"
cores: "{{ vm_cores | default(2) }}"
state: present
delegate_to: localhost
- name: Create Terraform user
community.proxmox.proxmox_user:
api_host: "{{ proxmox_api_host }}"
api_user: "root@pam"
api_password: "{{ proxmox_root_password }}"
userid: "terraform@pve"
comment: "Terraform automation user"
groups:
- automation
state: present
no_log: true
delegate_to: localhost
- name: Grant terraform permissions
community.proxmox.proxmox_acl:
api_host: "{{ proxmox_api_host }}"
api_user: "{{ proxmox_api_user }}"
api_token_id: "{{ proxmox_token_id }}"
api_token_secret: "{{ proxmox_token_secret }}"
path: "/"
users:
- terraform@pve
roles:
- Administrator
state: present
delegate_to: localhost
When CLI is required, add proper idempotency controls:
- name: Check existing cluster status
ansible.builtin.command: pvecm status
register: cluster_status
failed_when: false
changed_when: false
- name: Set cluster facts
ansible.builtin.set_fact:
is_cluster_member: "{{ cluster_status.rc == 0 }}"
in_target_cluster: "{{ cluster_name in cluster_status.stdout }}"
- name: Create cluster on primary node
ansible.builtin.command: pvecm create {{ cluster_name }}
when:
- inventory_hostname == groups['proxmox'][0]
- not in_target_cluster
register: cluster_create
changed_when: cluster_create.rc == 0
- name: Join cluster on secondary nodes
ansible.builtin.command: pvecm add {{ hostvars[groups['proxmox'][0]].ansible_host }}
when:
- inventory_hostname != groups['proxmox'][0]
- not is_cluster_member
register: cluster_join
changed_when: cluster_join.rc == 0
- name: Create API token
ansible.builtin.command: >
pveum user token add {{ username }}@pam {{ token_name }}
--privsep 0
register: token_result
changed_when: "'already exists' not in token_result.stderr"
failed_when:
- token_result.rc != 0
- "'already exists' not in token_result.stderr"
no_log: true
# Store token in variables or Infisical
proxmox_api_host: "192.168.1.10"
proxmox_api_user: "terraform@pve"
proxmox_token_id: "automation"
proxmox_token_secret: "{{ lookup('infisical', 'PROXMOX_TOKEN_SECRET') }}"
- name: Create VM
community.proxmox.proxmox_kvm:
api_host: "{{ proxmox_api_host }}"
api_user: "{{ proxmox_api_user }}"
api_token_id: "{{ proxmox_token_id }}"
api_token_secret: "{{ proxmox_token_secret }}"
# ... rest of config
For operations on Proxmox nodes themselves:
- name: Retrieve root password
ansible.builtin.include_tasks: tasks/infisical-secret-lookup.yml
vars:
secret_name: 'PROXMOX_ROOT_PASSWORD'
secret_var_name: 'proxmox_root_password'
- name: Configure via API
community.proxmox.proxmox_user:
api_host: "{{ inventory_hostname }}"
api_user: "root@pam"
api_password: "{{ proxmox_root_password }}"
# ... config
no_log: true
- name: Get cluster status
ansible.builtin.command: pvecm status
register: cluster_status
changed_when: false
failed_when: false
- name: Get cluster nodes
ansible.builtin.command: pvecm nodes
register: cluster_nodes
changed_when: false
failed_when: false
when: cluster_status.rc == 0
- name: Set cluster facts
ansible.builtin.set_fact:
cluster_exists: "{{ cluster_status.rc == 0 }}"
cluster_node_count: "{{ cluster_nodes.stdout_lines | length | default(0) }}"
is_quorate: "{{ 'Quorate: Yes' in cluster_status.stdout | default('') }}"
- name: Verify cluster quorum
ansible.builtin.command: pvecm status
register: cluster_health
changed_when: false
failed_when: "'Quorate: Yes' not in cluster_health.stdout"
- name: Verify expected node count
ansible.builtin.command: pvecm nodes
register: nodes_check
changed_when: false
failed_when: nodes_check.stdout_lines | length != groups['proxmox'] | length
- name: Check if CEPH is initialized
ansible.builtin.command: pveceph status
register: ceph_status
changed_when: false
failed_when: false
- name: Initialize CEPH
ansible.builtin.command: >
pveceph init --network {{ ceph_network }}
when:
- inventory_hostname == groups['proxmox'][0]
- ceph_status.rc != 0
register: ceph_init
changed_when: ceph_init.rc == 0
- name: Check if OSD exists on device
ansible.builtin.command: >
pveceph osd list
register: osd_list
changed_when: false
- name: Create OSD
ansible.builtin.command: >
pveceph osd create {{ item }}
loop: "{{ ceph_osd_devices }}"
when: item not in osd_list.stdout
register: osd_create
changed_when: osd_create.rc == 0
Use community.general.interfaces_file for network config:
- name: Configure VLAN-aware bridge
community.general.interfaces_file:
iface: vmbr1
option: bridge-vlan-aware
value: "yes"
backup: true
state: present
notify: reload network
- name: Set bridge ports
community.general.interfaces_file:
iface: vmbr1
option: bridge-ports
value: "bond0"
backup: true
state: present
notify: reload network
# BAD - Module exists for this
- name: Create user
ansible.builtin.command: pveum user add terraform@pve
# GOOD
- name: Create user
community.proxmox.proxmox_user:
api_host: "{{ proxmox_api_host }}"
api_user: "root@pam"
api_password: "{{ password }}"
userid: "terraform@pve"
state: present
# BAD - Will fail on second run
- name: Create cluster
ansible.builtin.command: pvecm create MyCluster
# GOOD
- name: Check cluster status
ansible.builtin.command: pvecm status
register: cluster_check
changed_when: false
failed_when: false
- name: Create cluster
ansible.builtin.command: pvecm create MyCluster
when: cluster_check.rc != 0
# BAD - API calls from managed node
- name: Create VM
community.proxmox.proxmox_kvm:
api_host: "{{ inventory_hostname }}" # Calling itself
# ...
# GOOD - Delegate API calls to localhost
- name: Create VM
community.proxmox.proxmox_kvm:
api_host: "{{ proxmox_api_host }}"
# ...
delegate_to: localhost
# Install community.proxmox
uv run ansible-galaxy collection install community.proxmox
# Or via requirements.yml
cd ansible
uv run ansible-galaxy collection install -r requirements.yml
For detailed Proxmox automation patterns, consult:
references/ceph-automation.md - CEPH storage deployment and OSD managementreferences/cluster-automation.md - Proxmox cluster creation and node joiningreferences/network-automation.md - VLAN-aware bridges and network configurationreferences/community-proxmox-plugin-index.md - Complete community.proxmox module reference