Fixing Proxmox Terraform Deletes with curl + jq

Written by

in

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:

  1. Terraform tries to destroy a resource
  2. Proxmox rejects it
  3. 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

  • curl — for API calls
  • jq — for parsing JSON

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.

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *