Automating VM Deployment in Proxmox Using OpenTofu (Terraform) and Cloud-Init Pt. 2
First off, apologies for the delay in publishing Part 2 — things got quite busy at work. I also wanted to make sure this part delivers a clear and practical solution that anyone can easily adapt to their own environment with minimal adjustments.
In Part 1, I described how to efficiently create a cloud-init–ready image in Proxmox for automated deployments.
In this second part, I’ll walk through the OpenTofu code I’m using to deploy multiple VMs based on that template.
📦 Code Repo: https://github.com/r0k5t4r/tf-proxmox-multi-vms
What This Terraform Setup Does
This setup allows you to:
- Deploy multiple VMs from a Proxmox cloud-init template
- Customize each VM's resources (vCPUs, memory, disk)
- Set static IPs using the
ipconfigparameter - Inject metadata (e.g., hostname, SSH keys) via cloud-init
- Manage deployments using separate environment configs
It's ideal for spinning up test clusters, homelab services, or small production workloads quickly and repeatably.
Project Structure
The codebase is organized for flexibility and reusability. The main logic resides in a generic Terraform module, and different deployment scenarios are defined via .tfvars files inside an environments/ directory:
KopierenBearbeitenenvironments/
├── ceph.tfvars
├── dev.tfvars
├── openstack-allinone.tfvars
├── openstack-multinode-dev.tfvars
├── openstack-multnode.tfvars
└── prod.tfvars
Each .tfvars file represents an environment and contains one or more VM definitions.
Example: Defining VMs in a .tfvars File
Here’s a minimal example from one of the files:
vms = [
{
name = "dev-vm1"
description = "Development Node 1"
cores = 2
memory = 2048
ip = "192.168.100.201"
},
{
name = "dev-vm2"
description = "Development Node 2"
cores = 2
memory = 2048
ip = "192.168.100.202"
}
]This format is easy to modify and extend. Add more VMs or change specs without touching the core Terraform logic.
Running the Deployment
After cloning the repository and setting up your Proxmox API token/credentials, you can deploy an environment like this:
tofu init
tofu apply -var-file=environments/dev.tfvarsThis will clone the template VM, set cloud-init parameters, and boot the instances with their specified configuration.
Why OpenTofu?
I’m using OpenTofu instead of Terraform because of its open governance model. It’s a drop-in replacement that works seamlessly with the Telmate Proxmox provider, so you don’t need to change anything in your existing workflow.
Let me know if this setup works for you, or if you’ve found other ways to automate VM provisioning in Proxmox. Feedback is always welcome!
🤖 Happy hacking