locals { nodes = { for k, v in var.nodes : k => merge(v, { id = 700 + index(keys(var.nodes), k) hash = sha1(v.name) mac_address = "AA:BB:07:00:${format("%v:%v", substr(sha1(v.name), 0, 2), substr(sha1(v.name), 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]["ens18"][0] public_ipv6 = local.ipv6_addresses[k]["ens18"][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" "userdata" { for_each = local.nodes node_name = each.value.host content_type = "snippets" datastore_id = var.common_storage source_raw { data = <<-EOF #cloud-config ssh_authorized_keys: %{for key in var.ssh_keys~} - ${key} %{endfor} write_files: - path: /run/secrets/tailscale.com/authkey content: ${var.tailscale_apikey} permissions: '0400' owner: root:root - path: /etc/nixos/configuration.nix content: | { config, pkgs, ... }: { system.stateVersion = "23.11"; networking.hostName = "${each.value.name}"; networking.domain = "ingress.tjo.cloud"; } runcmd: - systemctl start tailscaled-autoconnect.service - nixos-rebuild switch EOF file_name = "${each.value.name}.ingress.tjo.cloud.userconfig.yaml" } } resource "proxmox_virtual_environment_vm" "nodes" { for_each = local.nodes vm_id = each.value.id name = "${each.value.name}.ingress.tjo.cloud" node_name = each.value.host description = "Node ${each.value.name} for ingress.tjo.cloud." tags = concat( ["ingress-tjo-cloud"], ) stop_on_destroy = true timeout_start_vm = 60 timeout_stop_vm = 60 timeout_shutdown_vm = 60 timeout_reboot = 60 timeout_create = 600 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 = "5m" } 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 { interface = "sata0" datastore_id = each.value.storage user_data_file_id = proxmox_virtual_environment_file.userdata[each.key].id } }