This guide documents how to create Proxmox VMs using Terraform for use as Kubernetes nodes in a k3s cluster. The Terraform configuration clones a cloud-init template, assigns fixed IPs and SSH keys, and tags VMs for k3s roles so they can be targeted by k3s-ansible or similar automation.
Overview#
The setup provisions two groups of VMs:
- k3s masters (3 VMs): control-plane nodes for the Kubernetes cluster
- k3s workers (2 VMs): worker nodes for running workloads
All VMs are created by full clone from a cloud-init template (VM ID 9999 in the examples). They receive static IPs, a common SSH user and public key, and Proxmox tags (k3s, master or worker) for identification. After Terraform applies, you deploy k3s onto these VMs using Ansible or another method. This guide uses placeholders like <subnet> and <first-master-ip>; replace them with values that match your network.
Prerequisites#
- Proxmox VE host with API access (e.g.
https://your-proxmox-host:8006) - Cloud-init template VM (ID
9999in this guide). Create it first using the Proxmox cloud-init template guide - Terraform >= 1.0
- SSH key pair for the cloud user (e.g.
~/.ssh/pvm-ubuntu-cloudand~/.ssh/pvm-ubuntu-cloud.pub). The same key is used later to fetch kubeconfig and run Ansible - Proxmox credentials (username/password; API token can be used when the provider supports it)
Architecture#
| Role | VM names | Count | IP range (example) | Tags |
|---|---|---|---|---|
| Master | k3s-master-01 … 03 | 3 | <subnet>.201–203/24 | k3s, master |
| Worker | k3s-worker-01 … 02 | 2 | <subnet>.211–212/24 | k3s, worker |
- Proxmox node: your Proxmox host name (set in Terraform; e.g.
proxmox-pveor a variable) - Network: one bridge (e.g.
vmbr0), one virtio NIC per VM - Gateway: your LAN gateway (e.g.
<subnet>.1)
Replace <subnet> with your actual subnet (e.g. 192.168.1). Adjust IP ranges, node name, and bridge in the Terraform variables or in main.tf to match your environment.
File layout#
The Terraform code lives in the homelab repo under kubernetes/terraform/:
| File | Purpose |
|---|---|
main.tf | Proxmox VM resources: k3s masters and workers (clone, CPU, memory, network, cloud-init) |
providers.tf | Terraform and Proxmox provider (bpg/proxmox) configuration |
variables.tf | Input variables: Proxmox endpoint, username, password |
terraform.tfvars.example | Example values; copy to terraform.tfvars and fill in |
Provider and variables#
- Provider: bpg/proxmox (
~> 0.66in the snippet below) - Authentication: endpoint URL, username, and password (sensitive). The code comment indicates a future switch to an API token.
Variables:
| Variable | Description | Example |
|---|---|---|
proxmox_endpoint | Proxmox API URL | https://your-proxmox-host:8006 |
proxmox_username | Proxmox user | root@pam or your-username@pam |
proxmox_password | Proxmox password | (sensitive) |
Step-by-step usage#
1. Clone the repo and enter the Terraform directory#
cd /path/to/homelabs
cd kubernetes/terraform2. Copy and edit tfvars#
cp terraform.tfvars.example terraform.tfvarsEdit terraform.tfvars and set:
proxmox_endpoint— your Proxmox API URL (e.g.https://<proxmox-host>:8006)proxmox_username— e.g.root@pamproxmox_password— your Proxmox password
Do not commit terraform.tfvars; add it to .gitignore if needed.
3. Ensure the cloud-init template and SSH key exist#
- Template VM ID 9999 must exist and be a full cloneable template (see Proxmox cloud-init template).
- Place the public key at
~/.ssh/pvm-ubuntu-cloud.pub(or update thefile()path inmain.tf).
4. Initialize and apply#
terraform init
terraform plan
terraform applyConfirm when prompted. Terraform will create 3 master and 2 worker VMs on the configured Proxmox node.
5. Deploy k3s on the new VMs#
Use your preferred method (e.g. k3s-ansible) with the same SSH user and key (ansibleuser, ~/.ssh/pvm-ubuntu-cloud).
- Running the Ansible playbooks
- Copying kubeconfig from the first master (replace
<first-master-ip>with your master’s IP):scp -i ~/.ssh/pvm-ubuntu-cloud ansibleuser@<first-master-ip>:~/.kube/config ~/.kube/config - Verifying with
kubectl get pods --all-namespaces
Destroying the VMs#
To remove all Terraform-managed k3s VMs:
cd kubernetes/terraform
terraform destroyConfirm when prompted. This does not remove the template VM (9999) or any resources not managed by this Terraform configuration.