kitchen-proxmox
A Test Kitchen driver for Proxmox VE. Creates and destroys VMs by cloning templates via the Proxmox REST API.
Requirements
- Chef Workstation (provides Ruby, Test Kitchen, and all dependencies)
- Proxmox VE 7+ with API token authentication
- A VM template to clone (with
qemu-guest-agentinstalled for IP detection)
Installation
chef exec gem install kitchen-proxmox
Configuration
Add the driver to your .kitchen.yml:
driver:
name: proxmox
proxmox_url: https://proxmox.example.com:8006
proxmox_token_id: kitchen@pam!kitchen-token
proxmox_token_secret: 00000000-0000-0000-0000-000000000000
node: pve
template_id: 9000
Cluster-Aware Configuration
For multi-node clusters, the driver can auto-select a node and resolve templates by name:
driver:
name: proxmox
proxmox_url:
- https://pve1.example.com:8006
- https://pve2.example.com:8006
proxmox_token_id: kitchen@pam!kitchen-token
proxmox_token_secret: 00000000-0000-0000-0000-000000000000
template_name: ubuntu-2204-cloud
This configuration:
- Tries
pve1first; if unreachable, fails over topve2 - Auto-selects the node with the most free memory
- Resolves
ubuntu-2204-cloudto the template's VMID at runtime
To avoid committing secrets, you can use ERB to inject them from environment variables. Test Kitchen processes .kitchen.yml as ERB before parsing the YAML:
driver:
name: proxmox
proxmox_url: https://proxmox.example.com:8006
proxmox_token_id: <%= ENV['PROXMOX_TOKEN_ID'] %>
proxmox_token_secret: <%= ENV['PROXMOX_TOKEN_SECRET'] %>
node: pve
template_id: 9000
Then export the variables before running Kitchen:
export PROXMOX_TOKEN_ID='kitchen@pam!kitchen-token'
export PROXMOX_TOKEN_SECRET='00000000-0000-0000-0000-000000000000'
kitchen converge
You can also put the exports in a .envrc (if using direnv) or a .env file sourced by your shell. Add these files to .gitignore so secrets are never committed.
Required Settings
| Key | Description |
|---|---|
proxmox_url |
Proxmox API URL (String or Array for failover) |
proxmox_token_id |
API token ID (user@realm!token-name) |
proxmox_token_secret |
API token secret (UUID) |
Node Selection
| Key | Default | Description |
|---|---|---|
node |
nil |
Pin to a specific Proxmox node (bypasses auto-selection) |
node_pool |
nil |
Restrict auto-selection to these node names (Array) |
When node is omitted, the driver queries the cluster and selects the online node with the most free memory.
Template Selection
| Key | Default | Description |
|---|---|---|
template_id |
nil |
VM ID of the template to clone |
template_name |
nil |
Template name to resolve (mutually exclusive with template_id) |
Set one of template_id or template_name. When using template_name, the driver resolves the name to a VMID via the cluster API, preferring a template on the target node.
Optional Settings
| Key | Default | Description |
|---|---|---|
ssl_verify |
true |
Verify TLS certificates |
connect_timeout |
10 |
Per-URL connection timeout in seconds |
pool |
nil |
Proxmox resource pool |
vm_name_prefix |
kitchen- |
Prefix for generated VM names |
cpus |
1 |
Number of CPU cores |
memory |
1024 |
Memory in MB |
storage |
nil |
Target storage for the clone |
network_bridge |
vmbr0 |
Network bridge for the VM |
clone_timeout |
300 |
Seconds to wait for clone task |
start_timeout |
300 |
Seconds to wait for VM start |
ip_wait_timeout |
120 |
Seconds to wait for guest IP |
Proxmox Setup
Create a Role
- Go to Datacenter → Permissions → Roles and click Create.
- Name the role (e.g.
KitchenDriver). - Select these privileges:
VM.Allocate,VM.Clone,VM.Audit,VM.PowerMgmtVM.Config.CPU,VM.Config.Memory,VM.Config.Disk,VM.Config.NetworkDatastore.AllocateSpace,Datastore.AuditPool.Allocate(only if you use thepoolconfig option)
- Click Create.
Create a User (optional)
You can use an existing user or create a dedicated one:
- Go to Datacenter → Permissions → Users and click Add.
- Set User name (e.g.
kitchen), Realm topamorpve, and a password. - Click Add.
Create an API Token
- Go to Datacenter → Permissions → API Tokens and click Add.
- Select the user, set a Token ID (e.g.
kitchen-token). - Uncheck "Privilege Separation" — the token inherits the user's permissions.
- Click Add and copy the displayed secret. It is shown only once.
The resulting token ID for .kitchen.yml is kitchen@pam!kitchen-token.
Assign Permissions
- Go to Datacenter → Permissions and click Add → User Permission.
- Set Path to
/(or scope to/vmsand/storageas needed). - Select the user and the
KitchenDriverrole. - Check Propagate.
- Click Add.
Template
The template VM must have qemu-guest-agent installed and enabled. The driver uses the guest agent to detect the VM's IP address after boot.
Development
make spec # run tests
make style # run rubocop
make # run both
make install # build and install the gem
License
Apache-2.0