provider "proxmox" { endpoint = var.proxmox_server api_token = var.proxmox_apikey ssh { agent = true username = var.proxmox_username_ssh socks5_server = var.proxmox_server_ssh password = var.proxmox_password_ssh node { name = "fenix" address = "127.0.0.1" port = 1081 } } } resource "proxmox_virtual_environment_download_file" "latest_ubunto_cloud_img" { content_type = "iso" datastore_id = "local" node_name = "fenix" url = "https://cloud-images.ubuntu.com/jammy/20250725/jammy-server-cloudimg-amd64.img" file_name = "jammyservercloudimgamd64.img" } resource "proxmox_virtual_environment_file" "cloud_init_yaml" { node_name = "fenix" datastore_id = "local-snippets" content_type = "snippets" source_raw { file_name = "user-data-cloud-config.yaml" data = yamldecode(file("${path.module}/cloud-init-base.yaml")) } } # Gerar um snippet cloud-init por VM resource "proxmox_virtual_environment_file" "vm_user_data" { for_each = local.merged_cloudinit node_name = "fenix" datastore_id = "local-snippets" content_type = "snippets" source_raw { file_name = "cloud-init-iac-k8s-${each.key}.yaml" data = yamlencode(each.value) } } locals { # Lê o ficheiro base (que está no mesmo módulo) base_cloudinit = yamldecode(file("${path.module}/cloud-init-base.yaml")) # Renderiza cada ficheiro por VM vm_cloudinits = { for vm in var.proxmox_k8s_vms : vm.name => yamldecode( templatefile("${path.module}/cloud-init-vm.yaml.tftpl", { extra_packages = try(vm.extra_packages, []) extra_users = try(vm.extra_users, []) extra_runcmd = try(vm.extra_runcmd, []) }) ) } deep_merge = function("deep_merge", [any, any], any, <<-EOT base, override = args result = {} for k in setunion(keys(base), keys(override)) { if can(base[k]) && can(override[k]) { if type(base[k]) == list && type(override[k]) == list { result[k] = concat(base[k], override[k]) } else if type(base[k]) == map && type(override[k]) == map { result[k] = deep_merge(base[k], override[k]) } else { result[k] = override[k] } } else if can(override[k]) { result[k] = override[k] } else { result[k] = base[k] } } return result EOT ) merged_cloudinit = { for vm_name, vm_cfg in local.vm_cloudinits : vm_name => local.deep_merge([local.base_cloudinit, vm_cfg]) } } resource "proxmox_virtual_environment_vm" "proxmox-kubernetes-VM-template" { depends_on = [proxmox_virtual_environment_download_file.latest_ubunto_cloud_img, proxmox_virtual_environment_file.cloud_init_yaml] name = "proxmox-kubernetes-VM-template" node_name = "fenix" vm_id = 1002 template = true started = false agent { enabled = true } tags = ["opentofu", "kubernetes", "fedora"] machine = "q35" bios = "seabios" description = "kubernetes VM Template created via iac" cpu { cores = 2 } memory { dedicated = 4096 } # Configuração do disco rígido #disk { # datastore_id = "local-lvm" # interface = "scsi1" # size = 64 #} disk { datastore_id = "local-lvm" file_id = proxmox_virtual_environment_download_file.latest_ubunto_cloud_img.id interface = "scsi0" file_format = "qcow2" } # Configuração da interface de rede network_device { bridge = "vmbr0" model = "virtio" } initialization { ip_config { ipv4 { address = "dhcp" # IP estático + máscara de rede } } user_data_file_id = proxmox_virtual_environment_file.cloud_init_yaml.id } } resource "proxmox_virtual_environment_vm" "k8s_vms" { for_each = { for vm in var.proxmox_k8s_vms : vm.name => vm } depends_on = [proxmox_virtual_environment_vm.proxmox-kubernetes-VM-template] name = each.value.name node_name = each.value.node_name vm_id = each.value.vm_id cpu { cores = each.value.cores } memory { dedicated = each.value.memory } disk { datastore_id = each.value.data_store size = each.value.disk_size interface = "scsi1" } clone { vm_id = proxmox_virtual_environment_vm.proxmox-kubernetes-VM-template.id } initialization { ip_config { ipv4 { address = each.value.ip gateway = each.value.gateway } } user_data_file_id = proxmox_virtual_environment_file.vm_user_data[each.key].id } agent { enabled = true } }