⚠️ This code was tested on Proxmox VE v9.1.5.
This projetct provisions a kubernetes cluster using K3s on a Proxmox VE server. You can either specify the k3s version or allow the script to automatically install the latest stable release.
This Terraform configuration:
- Provisions virtual machines on Proxmox VE
- Configures one or more K3s Control Plane node
- Provisions and joins Worker nodes
- Uses Proxmox Directory Mappings to share the cluster join token between nodes
Before applying the Terraform configuration, ensure the following prerequisites are configured in Proxmox VE.
The target storage must allow disk image import.
Steps:
- Navigate to Datacenter → Storage
- Select the desired storage
- Click Edit
- Under Content, enable:
Import
Download the base image from the official Ubuntu URL and store it in your selected storage.
This prevents the image from being downloaded again every time you run terraform destroy, allowing you to reuse the previously stored base image.
I am currently tracking the following issue for potential improvements to this implementation.
The intention is to conditionally download the image only if it does not already exist.
A Directory Mapping is required to allow the K3s Control Plane to share the cluster join token with worker nodes. Make sure the user/token used by the provider has the following privileges:
Mapping.ModifyMapping.Use
Thanks to the maintainers of the terraform-provider-proxmox project for making Proxmox provisioning with Terraform possible.
| Name | Version |
|---|---|
| terraform | >= 1.5.0 |
| external | >= 2.3.5 |
| proxmox | >= 0.99 |
| Name | Version |
|---|---|
| external | 2.3.5 |
| proxmox | 0.99.0 |
| random | 3.8.1 |
| Name | Source | Version |
|---|---|---|
| server | ./modules | n/a |
| worker | ./modules | n/a |
| Name | Type |
|---|---|
| proxmox_virtual_environment_download_file.base_image | resource |
| proxmox_virtual_environment_hardware_mapping_dir.add | resource |
| random_integer.token_id | resource |
| external_external.k3s_version | data source |
| proxmox_files.base_image | data source |
| Name | Description | Type | Default | Required |
|---|---|---|---|---|
| datastore_id | The Proxmox datastore ID where VM disks and snippets will be stored. | string |
n/a | yes |
| disk | Disk(s) to be attached to the VM | list(object({ |
[ |
no |
| net_cidr | Network CIDR block (e.g., 192.168.0.0/24). | string |
n/a | yes |
| net_domain | Network domain name assigned to the VM. The first domain on the list is used as the default FQDN | list(string) |
n/a | yes |
| node_name | The name of the Proxmox node where the virtual machines will be created. | string |
n/a | yes |
| pve_api_url | The HTTPS URL of the Proxmox VE API endpoint (e.g., https://proxmox.example.com:8006/api2/json). | string |
n/a | yes |
| pve_ssh_private_key | Private SSH Key. Add the path of the file (e.g. ~/.ssh/private_key). |
string |
n/a | yes |
| pve_ssh_user | SSH connection is required for the proxmox_virtual_environment_file to upload the cloud-init files. | string |
n/a | yes |
| pve_token_id | Proxmox API Token Name. | string |
n/a | yes |
| pve_token_secret | Proxmox API Token Value. | string |
n/a | yes |
| ssh_pub_keys | A list of SSH public keys to be injected into the VM via cloud-init. | list(string) |
[] |
no |
| tags | Virtual machine tag(s) | list(string) |
[ |
no |
| user_name | The default VM user name. | string |
"ubuntu" |
no |
| user_passwd | The password for the default VM user. | string |
n/a | yes |
| Name | Description |
|---|---|
| all_nodes | Shows what will be appended to /etc/hosts on each VM |
| k3s_version | k3s version to be installed on the nodes |