locals { # --- Primary Network Identification --- control_plane_nodes_source = [for node in var.nodes : node if node.role == "controlplane"] primary_network_cidr = local.control_plane_nodes_source[0].networks[0].cidr primary_gateway = local.control_plane_nodes_source[0].networks[0].gateway cluster_endpoint = length(local.control_plane_nodes_source) > 1 ? "https://${var.control_plane_vip}:6443" : "https://${local.control_plane_nodes_source[0].networks[0].ip}:6443" # --- Proxmox Network Resource Generation --- # 1. Flatten the list of all network assignments from all nodes. all_networks_flat = flatten([ for node in var.nodes : [ for network in node.networks : { proxmox_node = lookup(node, "proxmox_node", var.proxmox_node) vlan_id = network.vlan_id } ] ]) # 2. CORRECTED LOGIC: Group all network assignments by a unique key. # The "..." syntax groups all items with the same key into a list. # This creates a map where each value is a LIST of networks for that key. grouped_bridges = { for net in local.all_networks_flat : "${net.proxmox_node}-${net.vlan_id}" => net... } # 3. Build the final unique map for the resources to iterate over. # We now loop over the de-duplicated, grouped map. We only need the first item ([0]) # from each group to get the data we need to create the bridge. unique_bridges = { for key, group in local.grouped_bridges : key => { proxmox_node = group[0].proxmox_node vlan_id = group[0].vlan_id bridge_name = "vmbr${group[0].vlan_id}" phys_iface = lookup(var.node_interfaces, group[0].proxmox_node, var.default_physical_interface) } } talos_iso_download_url = "https://factory.talos.dev/image/${var.talos_factory_schematic_id}/${var.talos_version}/nocloud-${var.talos_image_architecture}.iso" image_target_nodes = toset([for node in var.nodes : node.name]) node_iso_filenames = { for node in var.nodes : node.name => "talos-${trimprefix(var.talos_version, "v")}-${substr(var.talos_factory_schematic_id, 0, 12)}-${node.name}-${var.talos_image_architecture}.iso" } node_iso_files = { for node in var.nodes : node.name => format("%s:iso/%s", var.talos_image_storage, local.node_iso_filenames[node.name]) } # --- VM Resource Transformation (No changes needed below this line) --- all_nodes_transformed = { for node in var.nodes : node.name => { vmid = node.vmid name = node.name cores = node.cores memory = node.memory role = node.role proxmox_node = lookup(node, "proxmox_node", var.proxmox_node) disk_size = node.disk_size disk_storage = var.disk_storage tags = lookup(node, "tags", [node.role]) iso_file = local.node_iso_files[node.name] additional_disk_size = lookup(node, "additional_disk_size", null) additional_disk_storage = lookup(node, "additional_disk_size", null) != null ? var.additional_disk_storage : null network_devices = [ for net in node.networks : { mac_address = net.mac_address bridge = "vmbr${net.vlan_id}" model = "virtio" } ] # Data for Talos config and outputs ip = node.networks[0].ip gateway = node.networks[0].gateway network_cidr = node.networks[0].cidr } } node_configs = { controlplane = { cpu_type = "host", bios = "seabios", boot_order = ["scsi0", "ide2"], description = "Talos Control Plane Node - Managed by Terraform" } worker = { cpu_type = "host", bios = "seabios", boot_order = ["scsi0", "ide2"], description = "Talos Worker Node - Managed by Terraform" } } }