Proxmox Talos
This Guide shows the creation of a Talos Linux cluster on a proxmox node using Terraform. The following steps need to be executed:
- creation of a a Proxmox user to be able to create resources via terraform
- gathering of a image for Proxmox from the Talos factory
- actually running terraform
Creating the Proxmox user and role for terraform
pveum role add TerraformProv -privs "Datastore.AllocateSpace Datastore.AllocateTemplate Datastore.Audit Pool.Allocate Pool.Audit Sys.Audit Sys.Console Sys.Modify VM.Allocate VM.Audit VM.Clone VM.Config.CDROM VM.Config.Cloudinit VM.Config.CPU VM.Config.Disk VM.Config.HWType VM.Config.Memory VM.Config.Network VM.Config.Options VM.GuestAgent.Audit VM.GuestAgent.Unrestricte VM.Migrate VM.PowerMgmt SDN.Use"
pveum user add terraform-prov@pve
pveum aclmod / -user terraform-prov@pve -role TerraformProvUsing an API Token (Recommended)
pveum user token add terraform-prov@pve mytoken
pveum aclmod / --tokens '<<full-tokenid>>' -role TerraformProvCreating the connection via username and API token
# use single quotes for the API token ID because of the exclamation mark
export PM_API_TOKEN_ID='terraform-prov@pve!mytoken'
export PM_API_TOKEN_SECRET="afcd8f45-acc1-4d0f-bb12-a70b0777ec11"Talos Factory
System Extensions:
- siderolabs/iscsi-tools
- siderolabs/qemu-guest-agent
- siderolabs/util-linux-tools
Configuration of the Terraform provider
To be able to create resources on proxmox with terraform i chose to use the provider from telmate.
terraform.tf
terraform {
required_providers {
proxmox = {
source = "telmate/proxmox"
version = "3.0.2-rc07"
}
}
}
provider "proxmox" {
pm_api_url = "https://192.168.20.251:8006/api2/json"
pm_tls_insecure = true # By default Proxmox Virtual Environment uses self-signed certificates.
}variables.tf
variable "target_node" {
type = string
description = "The name of the PVE Node on which to place the VM."
default = "westfall"
}
variable "machine" {
type = string
description = "The type of the Machine."
default = "q35"
}
variable "bios" {
type = string
description = "The BIOS to use, options are seabios or ovmf for UEFI."
default = "ovmf"
}
variable "memory" {
type = number
description = "The amount of memory to allocate to the VM in Megabytes."
default = 6144
}
variable "scsihw" {
type = string
description = "The SCSI controller to emulate. Options: lsi, lsi53c810, megasas, pvscsi, virtio-scsi-pci, virtio-scsi-single."
default = "virtio-scsi-pci"
}
variable "cpu_cores" {
type = number
description = "The number of CPU cores to allocate to the Qemu guest."
default = 2
}
variable "cpu_type" {
type = string
description = "The CPU type to emulate."
default = "x86-64-v2-AES"
}
variable "vga_type" {
type = string
description = "The type of display to virtualize. Options: cirrus, none, qxl, qxl2, qxl3, qxl4, serial0, serial1, serial2, serial3, std, virtio, vmware."
default = "qxl"
}
variable "network_model" {
type = string
description = "Network Card Model. The virtio model provides the best performance with very low CPU overhead. If your guest does not support this driver, it is usually best to use e1000. Options: e1000, e1000-82540em, e1000-82544gc, e1000-82545em, i82551, i82557b, i82559er, ne2k_isa, ne2k_pci, pcnet, rtl8139, virtio, vmxnet3."
default = "virtio"
}
variable "network_bridge" {
type = string
description = "Bridge to which the network device should be attached. The Proxmox VE standard bridge is called vmbr0."
default = "vmbr0"
}
variable "disk_storage" {
type = string
description = "The name of the storage pool on which to store the disk."
default = "local-lvm"
}
variable "osdisk_size" {
type = string
description = "The size of the created disk. Accepts K for kibibytes, M for mebibytes, G for gibibytes, T for tibibytes. When only a number is provided gibibytes is assumed."
default = "32G"
}
variable "datadisk_size" {
type = string
description = "The size of the created disk. Accepts K for kibibytes, M for mebibytes, G for gibibytes, T for tibibytes. When only a number is provided gibibytes is assumed."
default = "64G"
}
variable "cdrom_iso" {
type = string
description = "The name of the ISO image to mount to the VM in the format: [storage pool]:iso/[name of iso file]."
default = "local:iso/metal-amd64.iso"
}
variable "efidisk_storage" {
type = string
description = "The name of the storage pool on which to store the disk."
default = "local-lvm"
}main.tf
resource "proxmox_vm_qemu" "talos-01" {
vmid = "100"
name = "talos-01"
machine = var.machine
target_node = var.target_node
bios = var.bios
start_at_node_boot = true
agent = 1
memory = var.memory
scsihw = var.scsihw
skip_ipv6 = true
cpu {
cores = var.cpu_cores
type = var.cpu_type
}
vga {
type = var.vga_type
}
network {
id = 0
model = var.network_model
bridge = var.network_bridge
}
disks {
scsi {
scsi0 {
disk {
storage = var.disk_storage
size = var.osdisk_size
cache = "none"
discard = true
}
}
scsi1 {
disk {
storage = var.disk_storage
size = var.datadisk_size
cache = "none"
discard = true
}
}
}
ide {
ide2 {
cdrom {
iso = var.cdrom_iso
}
}
}
}
efidisk {
efitype = "4m"
storage = var.efidisk_storage
}
}
resource "proxmox_vm_qemu" "talos-02" {
vmid = "200"
name = "talos-02"
machine = var.machine
target_node = var.target_node
bios = var.bios
start_at_node_boot = true
agent = 1
memory = var.memory
scsihw = var.scsihw
skip_ipv6 = true
cpu {
cores = var.cpu_cores
type = var.cpu_type
}
vga {
type = var.vga_type
}
network {
id = 0
model = var.network_model
bridge = var.network_bridge
}
disks {
scsi {
scsi0 {
disk {
storage = var.disk_storage
size = var.osdisk_size
cache = "none"
discard = true
}
}
scsi1 {
disk {
storage = var.disk_storage
size = var.datadisk_size
cache = "none"
discard = true
}
}
}
ide {
ide2 {
cdrom {
iso = var.cdrom_iso
}
}
}
}
efidisk {
efitype = "4m"
storage = var.efidisk_storage
}
}
resource "proxmox_vm_qemu" "talos-03" {
vmid = "300"
name = "talos-03"
machine = var.machine
target_node = var.target_node
bios = var.bios
start_at_node_boot = true
agent = 1
memory = var.memory
scsihw = var.scsihw
skip_ipv6 = true
cpu {
cores = var.cpu_cores
type = var.cpu_type
}
vga {
type = var.vga_type
}
network {
id = 0
model = var.network_model
bridge = var.network_bridge
}
disks {
scsi {
scsi0 {
disk {
storage = var.disk_storage
size = var.osdisk_size
cache = "none"
discard = true
}
}
scsi1 {
disk {
storage = var.disk_storage
size = var.datadisk_size
cache = "none"
discard = true
}
}
}
ide {
ide2 {
cdrom {
iso = var.cdrom_iso
}
}
}
}
efidisk {
efitype = "4m"
storage = var.efidisk_storage
}
}