Skip to main content

VMs for K3s

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 9999 in 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-cloud and ~/.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
#

RoleVM namesCountIP range (example)Tags
Masterk3s-master-01033<subnet>.201203/24k3s, master
Workerk3s-worker-01022<subnet>.211212/24k3s, worker
  • Proxmox node: your Proxmox host name (set in Terraform; e.g. proxmox-pve or 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/:

FilePurpose
main.tfProxmox VM resources: k3s masters and workers (clone, CPU, memory, network, cloud-init)
providers.tfTerraform and Proxmox provider (bpg/proxmox) configuration
variables.tfInput variables: Proxmox endpoint, username, password
terraform.tfvars.exampleExample values; copy to terraform.tfvars and fill in

Provider and variables
#

  • Provider: bpg/proxmox (~> 0.66 in the snippet below)
  • Authentication: endpoint URL, username, and password (sensitive). The code comment indicates a future switch to an API token.

Variables:

VariableDescriptionExample
proxmox_endpointProxmox API URLhttps://your-proxmox-host:8006
proxmox_usernameProxmox userroot@pam or your-username@pam
proxmox_passwordProxmox password(sensitive)

Step-by-step usage
#

1. Clone the repo and enter the Terraform directory
#

cd /path/to/homelabs
cd kubernetes/terraform

2. Copy and edit tfvars
#

cp terraform.tfvars.example terraform.tfvars

Edit terraform.tfvars and set:

  • proxmox_endpoint — your Proxmox API URL (e.g. https://<proxmox-host>:8006)
  • proxmox_username — e.g. root@pam
  • proxmox_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 the file() path in main.tf).

4. Initialize and apply
#

terraform init
terraform plan
terraform apply

Confirm 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 destroy

Confirm when prompted. This does not remove the template VM (9999) or any resources not managed by this Terraform configuration.