When I started automating my homelab using Terraform + Proxmox, everything worked great… until it didn’t.
The problem
In a push-based deployment (via GitHub Actions), I hit a blocker: the Proxmox Terraform provider cannot delete a running VM or container.
That means:
- Terraform tries to destroy a resource
- Proxmox rejects it
- Pipeline fails ❌
So the fix is simple in theory: check if the VM is running → stop it → then delete it.
But Terraform doesn’t handle this natively — so I built a small workaround using curl and jq.
What you need
Proxmox API access
You’ll need a Proxmox API token. The relevant docs:
Set your environment variables (Windows example):
setx TF_VAR_proxmox_api_url "https://YOUR-IP:8006/api2/json"
setx TF_VAR_proxmox_api_token_id "user@pam!token"
setx TF_VAR_proxmox_api_token_secret "your-secret"
Quick environment variable reference (Windows)
# Temporary
set MY_VAR=HelloWorld
echo %MY_VAR%
# Persistent
setx MY_VAR "HelloWorld"
# System-wide
setx /m MY_VAR "HelloWorld"
The fix
We query the VM status using the Proxmox API:
curl -sk -H "Authorization: PVEAPIToken=USER!TOKEN=SECRET" \
https://IP:8006/api2/json/nodes/NODE/qemu/VMID/status/current
Then extract the state with jq:
jq -r '.data.status'
Putting it together
STATUS=$(curl -sk -H "$PVE_AUTH" \
"${PVE_API}/nodes/${PVE_NODE}/qemu/${VMID}/status/current" \
| jq -r '.data.status')
if [ "$STATUS" = "running" ]; then
echo "Stopping VM $VMID..."
curl -sk -X POST -H "$PVE_AUTH" \
"${PVE_API}/nodes/${PVE_NODE}/qemu/${VMID}/status/stop"
fi
Now Terraform can safely destroy the VM after this runs.
Leave a Reply