All posts
Tech Insights

From Git to VM – how we build self-service with Proxmox and Crossplane

Proxmox, Crossplane and GitOps as the foundation for self-service on your own infrastructure. Read about Petter's PoC, what works today and the next steps.

Petter LarssonAuthorPetter Larsson·
From Git to VM – how we build self-service with Proxmox and Crossplane

Can virtual machines be ordered through self-service and managed as declaratively as resources in Kubernetes?

In traditional virtualisation environments, a new VM often requires several manual steps. It works, but as more teams need infrastructure it becomes hard to keep configurations consistent, review changes and know what is actually deployed.

I wanted to explore how we can give development teams a more cloud-like experience on their own infrastructure: declaring what they need themselves and letting the platform handle provisioning.

The goal was to reduce manual handling and give development teams faster access to standardised infrastructure, without the organisation having to change virtualisation platform.

The result was a proof of concept (PoC) with Proxmox, Crossplane and GitOps.

How infrastructure is consumed makes a difference

A VM is easy to create.

The challenge comes when the same thing has to be done again and again, by different people and for different needs. Small differences in manual routines can produce environments that are hard to recreate and maintain. For development teams that means waiting; for the IT organisation, more hands-on work and weaker traceability.

The goal was to give Proxmox a more standardised interface, much like the declarative APIs we are already used to in Kubernetes: describe what you want, let a control plane handle how it is created and follow the result.

The solution: Kubernetes as the control plane for Proxmox

I used Proxmox VE on bare metal as the infrastructure layer and set up a small K3s cluster in a separate management VM. Crossplane runs in K3s and, through a Proxmox provider, talks to the Proxmox API to create and manage VMs.

To make the solution more useful, I also created a simplified VirtualMachine API with Crossplane XRDs and Compositions. Anyone who needs a VM should be able to declare a standardised resource instead of knowing every detail of Proxmox. Behind the API, the platform translates desired state into the right provisioning. The machines start from a shared VM template with cloud-init, giving a consistent starting point with network configuration, users and SSH key.

That is the core of Platform Engineering in this project: the platform team maintains the implementation and the shared standards, while development teams use a simpler interface to get the infrastructure they need.

From need to virtual machine: describe the need in Git, review the change, the platform provisions with Flux and Crossplane, cloud-init initialises the machine
From need to virtual machine: describe the need in Git, review the change, the platform provisions with Flux and Crossplane, cloud-init initialises the machine

From a Git change to a running VM

Flux CD synchronises configuration and VM definitions from Git to K3s. Crossplane reads the VirtualMachine resource, applies its Composition and lets the Proxmox provider call the Proxmox API. The virtual machine is then created or updated.

Git → Flux CD → K3s/Crossplane → Proxmox provider → Proxmox API → VM

Self-service starts here with Git and an API. A user with the right access can add a VM definition, have the change reviewed according to the team's way of working and let the platform provision it. A portal can later offer a form on top of the same flow.

Git provides version history and the ability to review changes. Crossplane meanwhile works with reconciliation: the control plane compares desired state with actual state and tries to correct drift. That makes the infrastructure more reproducible and easier to follow than a series of individual manual actions.

Technical overview of declarative VM provisioning with Proxmox and Crossplane: Git, Flux CD, Crossplane, Proxmox provider, Kyverno and observability with Prometheus and Grafana
Technical overview of declarative VM provisioning with Proxmox and Crossplane: Git, Flux CD, Crossplane, Proxmox provider, Kyverno and observability with Prometheus and Grafana

Self-service needs both rules and visibility

If more teams are to request infrastructure, clear guardrails are needed too. In the PoC I use Kyverno for Policy as Code, for example to check allowed VM sizes and configurations. Rules can then be enforced in the provisioning flow instead of only manually afterwards.

With Prometheus, Grafana and Alertmanager the platform also gets observability. You can follow GitOps syncs, Kubernetes, Crossplane reconciliation and status or resource usage in Proxmox. If a VM is not created as intended, the team needs to see where in the chain the problem occurred – not just that the request failed.

What did the PoC demonstrate – and what does it make possible?

The solution demonstrates that several Proxmox VMs can be provisioned with declarative Kubernetes resources, that the configuration can be versioned in Git and that a custom VirtualMachine API can hide underlying complexity. It also shows how policy checks and monitoring can be part of the same platform flow.

For a platform team, the gain is fewer special cases and better traceability. For developers, the interesting possibility is a simpler, more self-service way to get VMs. For IT decision makers, it is about standardising how infrastructure is delivered without replacing the existing virtualisation platform.

This is a technical demonstration – not a finished production platform and not measured proof of shorter lead times. But it shows how traditional virtualisation can gain a more cloud-like way of working.

Next step: from PoC to internal platform

For production use I would, among other things, want to develop RBAC and access control, backup, DNS automation, network policies, more Proxmox nodes and routines for security and lifecycle management. What matters is that the core principle can already be tried: infrastructure is declared as code, governed by policy and observable throughout the chain.

We do not need to move everything to a public cloud to start working in a more cloud-like way. Sometimes it is enough to change how we offer and manage the infrastructure we already have.

Frequently asked questions

Can Crossplane create virtual machines in Proxmox?

Yes. With a compatible Proxmox provider, Crossplane can call the Proxmox API and manage VMs through Kubernetes resources.

Do the VMs have to run Kubernetes?

No. K3s is used as the management and control plane. The virtual machines run separately in Proxmox.

What do Flux CD and GitOps add?

VM definitions and platform configuration are versioned in Git and synchronised to K3s, providing traceability and reproducibility.

Is the solution production ready?

No. It is a PoC that needs to be complemented with access control, backup and operational routines, among other things, before production.

Want to make VM management more declarative?

At SHEBANG we help organisations explore and build modern internal platforms – with architecture, automation, GitOps and observability. Want to explore how your existing virtualisation can become easier to consume and manage? Get in touch and let's talk about your needs.

See the flow
for real.

Book a demo with Petter and see how self-service with Proxmox, Crossplane and GitOps can work on your existing infrastructure.

Petter Larsson

Petter Larsson

Platform Engineer

30-minute demo with Petter

  1. 1Live: a Git change that becomes a running VM in Proxmox
  2. 2How policy and observability fit into the flow
  3. 3What it takes to bring it to production in your environment

Or call 08-773 23 00 or email hello@shebang.se.

Share
SHEBANG – hashtag och utropstecken
LinkedIn X