Marketplace
ansible-proxmox
This skill should be used when automating Proxmox VE with Ansible, creating VMs or templates, managing Proxmox clusters, using community.proxmox collection, or deciding between native modules and CLI commands (pvecm, pveceph, qm).
$ Installer
git clone https://github.com/basher83/lunar-claude /tmp/lunar-claude && cp -r /tmp/lunar-claude/plugins/infrastructure/ansible-workflows/skills/ansible-proxmox ~/.claude/skills/lunar-claude// tip: Run this command in your terminal to install the skill
SKILL.md
name: ansible-proxmox description: > This skill should be used when automating Proxmox VE with Ansible, creating VMs or templates, managing Proxmox clusters, using community.proxmox collection, or deciding between native modules and CLI commands (pvecm, pveceph, qm).
Ansible Proxmox Integration
Expert Proxmox automation using community.proxmox collection with minimal CLI usage.
Module Selection
Prefer Native Modules
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 |
When CLI is Required
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 |
Native Module Examples
Create VM from Template
- 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
Manage Proxmox User
- 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
Configure ACLs
- 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
CLI with Idempotency
When CLI is required, add proper idempotency controls:
Cluster Formation
- 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
API Token Creation
- 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
Authentication Patterns
API Token (Recommended)
# 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
Root Password (Local Operations)
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
Cluster Operations
Idempotent Cluster Status Check
- 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('') }}"
Verify Cluster Health
- 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
CEPH Integration
Initialize CEPH
- 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
Create OSD
- 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
Network Configuration
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
Anti-Patterns
Using CLI When Module Exists
# 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
Missing Idempotency on CLI
# 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
Running on Wrong Host
# 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
Installing the Collection
# 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
Additional Resources
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
Related Skills
- ansible-fundamentals - Core module selection patterns
- ansible-idempotency - Making CLI commands idempotent
- ansible-error-handling - Error recovery for cluster operations
Repository

basher83
Author
basher83/lunar-claude/plugins/infrastructure/ansible-workflows/skills/ansible-proxmox
10
Stars
1
Forks
Updated4d ago
Added1w ago