Tag: automation

  • Fixing Proxmox Terraform Deletes with curl + jq

    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.