From fa4f065762edb6be345da1aea15bf52d5c7a04b4 Mon Sep 17 00:00:00 2001 From: File Magic Date: Thu, 16 Jul 2026 20:21:52 -0400 Subject: [PATCH] tofu [kubernetes/]: add cluster_index and worker_count variables, generate nodes dynamically --- kubernetes/tofu/main.tf | 73 +++++++++++++++++++++++++----------- kubernetes/tofu/outputs.tf | 24 +++++++++++- kubernetes/tofu/variables.tf | 57 ++++++++++------------------ 3 files changed, 92 insertions(+), 62 deletions(-) diff --git a/kubernetes/tofu/main.tf b/kubernetes/tofu/main.tf index 5613140..8289541 100644 --- a/kubernetes/tofu/main.tf +++ b/kubernetes/tofu/main.tf @@ -18,19 +18,48 @@ provider "libvirt" { } locals { - ovmf_code_file = "${var.ovmf_code_path}/FV/OVMF_CODE.fd" + ovmf_code_file = "${var.ovmf_code_path}/FV/OVMF_CODE.fd" + subnet_third_octet = 122 + var.cluster_index + subnet_cidr = "192.168.${local.subnet_third_octet}.0/24" + gateway_ip = "192.168.${local.subnet_third_octet}.1" + master_ip = "192.168.${local.subnet_third_octet}.10" + + master_nodes = { + "k8s-master-0" = { + role = "master" + ip_suffix = 10 + ip = "192.168.${local.subnet_third_octet}.10" + mac = "52:54:00:00:00:10" + vcpus = 2 + memory = 4096 + } + } + + worker_nodes = { + for i in range(var.worker_count) : + "k8s-worker-${toString(i)}" => { + role = "worker" + ip_suffix = 11 + i + ip = "192.168.${local.subnet_third_octet}.${toString(11 + i)}" + mac = "52:54:00:00:00:${format("%02x", 11 + i)}" + vcpus = 2 + memory = 4096 + } + } + + k8s_nodes = merge(local.master_nodes, local.worker_nodes) } resource "libvirt_network" "k8s" { - name = "k8s-net" + name = "k8s-${var.cluster_index}" autostart = true bridge = { - name = "virbr-k8s" + name = "virbr-k8s-${var.cluster_index}" } domain = { - name = "k8s.local" + name = "k8s-${var.cluster_index}.local" } forward = { @@ -39,21 +68,21 @@ resource "libvirt_network" "k8s" { ips = [ { - address = "192.168.122.1" + address = local.gateway_ip netmask = "255.255.255.0" family = "ipv4" dhcp = { ranges = [ { - start = "192.168.122.2" - end = "192.168.122.254" + start = "192.168.${local.subnet_third_octet}.2" + end = "192.168.${local.subnet_third_octet}.254" } ] hosts = [ - for name, node in var.k8s_nodes : { - mac = node.mac - ip = node.ip - name = name + for name, node in local.k8s_nodes : { + mac = node.mac + ip = node.ip + name = name } ] } @@ -62,7 +91,7 @@ resource "libvirt_network" "k8s" { } resource "libvirt_volume" "master" { - for_each = { for name, node in var.k8s_nodes : name => node if node.role == "master" } + for_each = { for name, node in local.k8s_nodes : name => node if node.role == "master" } name = "${each.key}.qcow2" pool = "default" @@ -79,7 +108,7 @@ resource "libvirt_volume" "master" { } resource "libvirt_volume" "worker" { - for_each = { for name, node in var.k8s_nodes : name => node if node.role == "worker" } + for_each = { for name, node in local.k8s_nodes : name => node if node.role == "worker" } name = "${each.key}.qcow2" pool = "default" @@ -96,7 +125,7 @@ resource "libvirt_volume" "worker" { } resource "libvirt_volume" "worker_data" { - for_each = { for name, node in var.k8s_nodes : name => node if node.role == "worker" } + for_each = { for name, node in local.k8s_nodes : name => node if node.role == "worker" } name = "${each.key}-data" pool = "default" @@ -106,10 +135,10 @@ resource "libvirt_volume" "worker_data" { resource "local_file" "ansible_inventory" { content = templatefile("${path.module}/inventory.tpl", { - master_name = keys({ for name, node in var.k8s_nodes : name => node if node.role == "master" })[0] - master_ip = var.k8s_nodes[keys({ for name, node in var.k8s_nodes : name => node if node.role == "master" })[0]].ip + master_name = keys({ for name, node in local.k8s_nodes : name => node if node.role == "master" })[0] + master_ip = local.k8s_nodes[keys({ for name, node in local.k8s_nodes : name => node if node.role == "master" })[0]].ip workers = { - for name, node in var.k8s_nodes : name => node.ip if node.role == "worker" + for name, node in local.k8s_nodes : name => node.ip if node.role == "worker" } }) filename = "${path.module}/../ansible/inventory.ini" @@ -117,7 +146,7 @@ resource "local_file" "ansible_inventory" { } resource "libvirt_domain" "k8s" { - for_each = var.k8s_nodes + for_each = local.k8s_nodes name = each.key memory = each.value.memory @@ -154,7 +183,7 @@ resource "libvirt_domain" "k8s" { { source = { volume = { - pool = "default" + pool = "default" volume = each.value.role == "master" ? libvirt_volume.master[each.key].name : libvirt_volume.worker[each.key].name } } @@ -171,7 +200,7 @@ resource "libvirt_domain" "k8s" { { source = { volume = { - pool = "default" + pool = "default" volume = libvirt_volume.worker_data[each.key].name } } @@ -214,8 +243,8 @@ resource "libvirt_domain" "k8s" { consoles = [ { target = { - type = "serial" - port = 0 + type = "serial" + port = 0 } } ] diff --git a/kubernetes/tofu/outputs.tf b/kubernetes/tofu/outputs.tf index 8e6e9ff..b4c895b 100644 --- a/kubernetes/tofu/outputs.tf +++ b/kubernetes/tofu/outputs.tf @@ -1,11 +1,31 @@ output "vm_ips" { description = "IP addresses of all K8s nodes" value = { - for name, node in var.k8s_nodes : name => node.ip + for name, node in local.k8s_nodes : name => node.ip } } output "master_ip" { description = "IP address of the master node" - value = var.k8s_nodes["k8s-master-0"].ip + value = local.master_ip +} + +output "subnet_cidr" { + description = "Subnet CIDR for this cluster" + value = local.subnet_cidr +} + +output "cluster_index" { + description = "Cluster index used for this deployment" + value = var.cluster_index +} + +output "worker_count" { + description = "Number of worker nodes" + value = var.worker_count +} + +output "node_names" { + description = "All node names" + value = keys(local.k8s_nodes) } diff --git a/kubernetes/tofu/variables.tf b/kubernetes/tofu/variables.tf index e34fdd3..a7fddfc 100644 --- a/kubernetes/tofu/variables.tf +++ b/kubernetes/tofu/variables.tf @@ -1,41 +1,22 @@ -variable "k8s_nodes" { - description = "Kubernetes node definitions" - type = map(object({ - role = string - ip = string - mac = string - vcpus = number - memory = number - })) - default = { - "k8s-master-0" = { - role = "master" - ip = "192.168.122.10" - mac = "52:54:00:00:00:10" - vcpus = 2 - memory = 4096 - } - "k8s-worker-0" = { - role = "worker" - ip = "192.168.122.11" - mac = "52:54:00:00:00:11" - vcpus = 2 - memory = 4096 - } - "k8s-worker-1" = { - role = "worker" - ip = "192.168.122.12" - mac = "52:54:00:00:00:12" - vcpus = 2 - memory = 4096 - } - "k8s-worker-2" = { - role = "worker" - ip = "192.168.122.13" - mac = "52:54:00:00:00:13" - vcpus = 2 - memory = 4096 - } +variable "cluster_index" { + description = "Cluster subnet index (0-255). Offsets the third octet of all IPs." + type = number + default = 0 + + validation { + condition = var.cluster_index >= 0 && var.cluster_index <= 255 + error_message = "cluster_index must be between 0 and 255." + } +} + +variable "worker_count" { + description = "Number of worker nodes (0-10)" + type = number + default = 3 + + validation { + condition = var.worker_count >= 0 && var.worker_count <= 10 + error_message = "worker_count must be between 0 and 10." } } -- 2.51.2