← Back to projects

AUTOMATION CASE STUDY

Proxmox Management Platform

I built this tool because routine Proxmox work was creating too many small manual steps. The platform started as an API prototype and became a usable Flask service for VM discovery, snapshots, append-only notes, cleanup, and operator handoff. The most valuable change came after one of my own updates triggered far more snapshots than intended.

Status: Operational Built and Refined: 2026 Type: Internal Tooling Role: Builder / Operator Context: Professional Experience - Sanitized
EVIDENCE AT A GLANCE Python + Flask Proxmox API Dynamic inventory Snapshot safety boundary corrected

The problem was not Proxmox itself. The problem was repeated operator friction.

Common tasks required operators to move between cluster views, identify the correct VM, create or review snapshots, and preserve enough context for the next person. Each action was simple, but the workflow depended on memory and careful manual selection.

I wanted one small interface that made those tasks repeatable without trying to replace the Proxmox management interface. The tool needed to reduce friction, expose the right context, and leave a useful record behind.

The implementation changed as the operational requirement became clearer.

01. FastAPI prototype
I used FastAPI to prove the API calls, VM discovery, and snapshot workflow before spending time on a production-facing interface.

02. Flask transition
The production direction moved to Flask to match the team's preferred application pattern. I kept the useful backend logic and rebuilt the operator-facing workflow around it.

03. Dynamic inventory
Added cluster, VMID, and name selection so operators did not need to manually cross-reference targets before every action.

04. Append-only notes
Added notes that preserve operator context instead of allowing earlier history to be silently overwritten.

05. Cleanup and lifecycle controls
Added deletion and service-management paths after real use exposed the need for safer cleanup and a more complete operating model.

A small web interface sits in front of structured Proxmox API operations.

flowchart TD
  OP[Operator] --> UI[Flask Web Interface]
  UI --> LOGIC[Python Workflow Logic]
  LOGIC --> PVE[Proxmox API]
  PVE --> VM[Virtual Machines]
  LOGIC --> INV[Dynamic Inventory]
  LOGIC --> SNAP[Snapshot Operations]
  LOGIC --> NOTES[Append-Only Notes]
  LOGIC --> CLEAN[Cleanup Controls]
        

One change triggered snapshots across the environment instead of the intended target.

During development, a workflow change caused snapshots to be created for every visible VM. The API call worked exactly as written, which made the failure more important: the problem was my targeting logic and the safety boundary around the action.

I cleaned up the snapshots, corrected the selection path, and added a deletion endpoint so recovery did not depend on manual cleanup through the Proxmox interface. I also treated target visibility and operator confirmation as part of the feature, not UI polish to add later.

What I assumed

I assumed the selected VM context was carried safely into the snapshot action because the correct target appeared in the interface.

What was actually true

The backend operation was able to iterate across the returned inventory. Displaying the right target was not the same as constraining the action.

What I changed

Tightened target selection, improved the cleanup path, and made destructive or wide-impact behavior easier to identify before execution.

What I learned

Automation magnifies targeting mistakes. A fast tool is only useful when scope, confirmation, and rollback are designed into the workflow.

The useful features came directly from operator needs.

VM discovery

Built dynamic VM listing and dropdowns so operators can select systems by cluster, VMID, and name without checking every target manually.

Snapshot workflow

Added snapshot creation for change windows and testing, then tightened the targeting logic after the broad-snapshot incident.

Append-only notes

Preserved operator context as a running history rather than a single editable field that could erase earlier decisions.

Cleanup controls

Added the ability to remove snapshots through the same tool so an error could be corrected without switching interfaces and rebuilding context.

Service lifecycle

Added service scripts and operational controls so the application could be started, stopped, and supported as a service instead of a one-off script.

Interface refinement

Improved layout, selection, and feedback based on actual use. The goal was clarity during an operation, not a decorative dashboard.

I validated the tool against real workflows, including the recovery path.

Successful API responses were not enough. I checked that inventory matched the cluster, that snapshot operations reached the intended VM, that notes were preserved, and that cleanup actions removed the correct objects.

The broad-snapshot failure became part of the validation model. After fixing it, I tested both the normal operation and the correction path because a tool that can create state should also make that state visible and recoverable.

I would design the safety boundary before expanding the feature set.

I would add an explicit preview of the resolved target list before the first snapshot implementation, even when only one VM is expected. I would also separate read-only inventory calls from state-changing actions more clearly in the backend structure.

I would still prototype the API first. Proving the Proxmox interaction before building the interface was the right sequence. The mistake was treating a working API call as a safe operator workflow too early.

The project became a practical internal operations tool and a better lesson in automation safety.

The final platform reduced repeated manual work and demonstrated Proxmox API integration, Python automation, Flask application design, operator-focused interfaces, append-only documentation, and recovery-aware engineering.

More importantly, it changed how I think about automation. The value is not simply making an action faster. The value is making the intended action obvious, constrained, explainable, and recoverable when something goes wrong.