locals { nodes_with_names = { for k, v in var.nodes : k => merge(v, { id = 700 + index(keys(var.nodes), k) hostname = "${v.name}.ingress.tjo.cloud" hash = sha1(v.name) }) } nodes = { for k, v in local.nodes_with_names : k => merge(v, { mac_address = "AA:BB:07:00:${format("%v:%v", substr(v.hash, 0, 2), substr(v.hash, 2, 2))}" }) } ipv4_addresses = { for key, node in local.nodes : key => { for k, v in proxmox_virtual_environment_vm.nodes[key].ipv4_addresses : proxmox_virtual_environment_vm.nodes[key].network_interface_names[k] => v } } ipv6_addresses = { for key, node in local.nodes : key => { for k, v in proxmox_virtual_environment_vm.nodes[key].ipv6_addresses : proxmox_virtual_environment_vm.nodes[key].network_interface_names[k] => v } } nodes_with_address = { for k, v in local.nodes : k => merge(v, { public_ipv4 = local.ipv4_addresses[k]["eth0"][0] public_ipv6 = local.ipv6_addresses[k]["eth0"][0] internal_ipv4 = local.ipv4_addresses[k]["tailscale0"][0] internal_ipv6 = local.ipv6_addresses[k]["tailscale0"][0] }) } } resource "tailscale_tailnet_key" "ingress" { reusable = true ephemeral = true preauthorized = true tags = ["tag:ingress-tjo-cloud"] description = "tailscale key for ingress-tjo-cloud nodes" } resource "proxmox_virtual_environment_file" "ingress" { content_type = "iso" datastore_id = var.common_storage node_name = values(var.nodes)[0].host source_file { path = var.image_path file_name = "ingress-tjo-cloud.img" } } resource "proxmox_virtual_environment_file" "cloudinit" { for_each = local.nodes node_name = each.value.host content_type = "snippets" datastore_id = var.common_storage source_raw { data = <<-EOF #cloud-config bootcmd: - [ 'tailscale', 'up', '--authkey', '${tailscale_tailnet_key.ingress.key}', '--hostname', '${each.value.name}', '--accept-routes', 'true', '--ssh' ] EOF file_name = "${each.value.hostname}.cloudinit.yaml" } } resource "proxmox_virtual_environment_vm" "nodes" { for_each = local.nodes vm_id = each.value.id name = each.value.hostname node_name = each.value.host description = "Node ${each.value.name} for ingress.tjo.cloud." tags = concat( ["tjo-space"], [each.value.name] ) stop_on_destroy = true timeout_start_vm = 60 timeout_stop_vm = 60 timeout_shutdown_vm = 60 timeout_reboot = 60 timeout_create = 120 cpu { cores = each.value.cores type = "host" } memory { dedicated = each.value.memory } bios = "ovmf" efi_disk { datastore_id = each.value.storage } operating_system { type = "l26" } agent { enabled = true timeout = "1m" } network_device { bridge = each.value.bridge mac_address = each.value.mac_address } scsi_hardware = "virtio-scsi-single" disk { file_id = proxmox_virtual_environment_file.ingress.id file_format = "qcow2" interface = "virtio0" datastore_id = each.value.storage size = each.value.boot_size backup = true cache = "none" iothread = true } initialization { datastore_id = each.value.storage meta_data_file_id = proxmox_virtual_environment_file.cloudinit[each.key].id } }