Files
talos-proxmox-cluster/terraform/main.tf

261 lines
7.2 KiB
HCL

# Download and upload Talos ISO to Proxmox
# resource "null_resource" "talos_iso" {
# provisioner "local-exec" {
# command = <<-EOT
# ISO_URL="${var.talos_iso_url != "" ? var.talos_iso_url : "https://github.com/siderolabs/talos/releases/download/${var.talos_version}/metal-amd64.iso"}"
# ISO_FILE="talos-${var.talos_version}-metal-amd64.iso"
#
# if [ ! -f "$ISO_FILE" ]; then
# echo "Downloading Talos ISO..."
# curl -L "$ISO_URL" -o "$ISO_FILE"
# fi
#
# echo "Uploading ISO to Proxmox..."
# scp "$ISO_FILE" ${var.proxmox_ssh_user}@${split("://", var.proxmox_endpoint)[1]}:/var/lib/vz/template/iso/
# EOT
# }
# }
# Create control plane VMs
resource "proxmox_virtual_environment_vm" "controlplane" {
count = var.controlplane_count
name = "${var.cluster_name}-cp-${count.index + 1}"
node_name = var.proxmox_node
vm_id = var.vm_id_prefix + count.index
description = "Talos Control Plane ${count.index + 1}"
started = true
on_boot = true
cpu {
cores = var.controlplane_cpu
type = "host"
}
memory {
dedicated = var.controlplane_memory
}
disk {
datastore_id = var.proxmox_storage
interface = "scsi0"
size = var.controlplane_disk_size
file_format = "raw"
discard = "on"
ssd = true
}
network_device {
bridge = var.proxmox_network_bridge
model = "virtio"
}
cdrom {
# enabled = true
file_id = "local:iso/talos-1.11.5-nocloud-amd64.iso"
interface = "ide2"
}
operating_system {
type = "l26"
}
agent {
enabled = true
}
boot_order = ["scsi0", "ide2"]
# depends_on = [null_resource.talos_iso]
}
# Create worker VMs
resource "proxmox_virtual_environment_vm" "worker" {
count = var.worker_count
name = "${var.cluster_name}-worker-${count.index + 1}"
node_name = var.proxmox_node
vm_id = var.vm_id_prefix + var.controlplane_count + count.index
description = "Talos Worker ${count.index + 1}"
started = true
on_boot = true
cpu {
cores = var.worker_cpu
type = "host"
}
memory {
dedicated = var.worker_memory
}
disk {
datastore_id = var.proxmox_storage
interface = "scsi0"
size = var.worker_disk_size
file_format = "raw"
discard = "on"
ssd = true
}
network_device {
bridge = var.proxmox_network_bridge
model = "virtio"
}
cdrom {
# enabled = true
file_id = "local:iso/talos-1.11.5-nocloud-amd64.iso"
interface = "ide2"
}
operating_system {
type = "l26"
}
agent {
enabled = true
}
boot_order = ["scsi0", "ide2"]
# depends_on = [null_resource.talos_iso]
}
# Wait for VMs to boot into maintenance mode and QEMU agent to start
resource "time_sleep" "wait_for_vms" {
depends_on = [
proxmox_virtual_environment_vm.controlplane,
proxmox_virtual_environment_vm.worker
]
create_duration = "60s"
}
# Generate Talos machine secrets
resource "talos_machine_secrets" "this" {
depends_on = [time_sleep.wait_for_vms]
}
# Generate control plane configuration
data "talos_machine_configuration" "controlplane" {
cluster_name = var.cluster_name
cluster_endpoint = var.cluster_endpoint
machine_type = "controlplane"
machine_secrets = talos_machine_secrets.this.machine_secrets
}
# Generate worker configuration
data "talos_machine_configuration" "worker" {
cluster_name = var.cluster_name
cluster_endpoint = var.cluster_endpoint
machine_type = "worker"
machine_secrets = talos_machine_secrets.this.machine_secrets
}
# Generate Talos client configuration
data "talos_client_configuration" "this" {
cluster_name = var.cluster_name
client_configuration = talos_machine_secrets.this.client_configuration
endpoints = local.controlplane_endpoints
}
# Apply configuration to control plane nodes via DHCP IPs
resource "talos_machine_configuration_apply" "controlplane" {
count = var.controlplane_count
client_configuration = talos_machine_secrets.this.client_configuration
machine_configuration_input = data.talos_machine_configuration.controlplane.machine_configuration
node = local.controlplane_dhcp_ips[count.index]
config_patches = concat(
[
templatefile("${path.module}/templates/install-disk-and-hostname.yaml.tmpl", {
hostname = "${var.cluster_name}-cp-${count.index + 1}"
}),
templatefile("${path.module}/templates/proxmox-ccm.yaml.tmpl", {
proxmox_url = var.proxmox_endpoint
proxmox_region = var.proxmox_region
ccm_token_secret = var.proxmox_ccm_token_secret
csi_token_secret = var.proxmox_csi_token_secret
}),
file("${path.module}/files/cp-scheduling.yaml")
],
length(var.controlplane_ips) > 0 && var.gateway != "" ? [
templatefile("${path.module}/templates/static-ip.yaml.tmpl", {
ip_address = var.controlplane_ips[count.index]
netmask = var.netmask
gateway = var.gateway
nameservers = var.nameservers
})
] : [],
var.cluster_vip != "" ? [
templatefile("${path.module}/templates/vip-config.yaml.tmpl", {
vip = var.cluster_vip
interface = "eth0"
})
] : []
)
depends_on = [time_sleep.wait_for_vms]
}
# Apply configuration to worker nodes via DHCP IPs
resource "talos_machine_configuration_apply" "worker" {
count = var.worker_count
client_configuration = talos_machine_secrets.this.client_configuration
machine_configuration_input = data.talos_machine_configuration.worker.machine_configuration
node = local.worker_dhcp_ips[count.index]
config_patches = concat(
[
templatefile("${path.module}/templates/install-disk-and-hostname.yaml.tmpl", {
hostname = "${var.cluster_name}-worker-${count.index + 1}"
}),
templatefile("${path.module}/templates/proxmox-ccm.yaml.tmpl", {
proxmox_url = var.proxmox_endpoint
proxmox_region = var.proxmox_region
ccm_token_secret = var.proxmox_ccm_token_secret
csi_token_secret = var.proxmox_csi_token_secret
})
],
length(var.worker_ips) > 0 && var.gateway != "" ? [
templatefile("${path.module}/templates/static-ip.yaml.tmpl", {
ip_address = var.worker_ips[count.index]
netmask = var.netmask
gateway = var.gateway
nameservers = var.nameservers
})
] : []
)
depends_on = [time_sleep.wait_for_vms]
}
# Bootstrap the cluster (use static IP if configured, otherwise DHCP)
resource "talos_machine_bootstrap" "this" {
depends_on = [talos_machine_configuration_apply.controlplane]
client_configuration = talos_machine_secrets.this.client_configuration
node = local.controlplane_endpoints[0]
}
# Retrieve kubeconfig (use static IP if configured, otherwise DHCP)
resource "talos_cluster_kubeconfig" "this" {
depends_on = [talos_machine_bootstrap.this]
client_configuration = talos_machine_secrets.this.client_configuration
node = local.controlplane_endpoints[0]
}
# Wait for Kubernetes API to be ready
resource "time_sleep" "wait_for_k8s_api" {
depends_on = [talos_cluster_kubeconfig.this]
create_duration = "60s"
}