terraform {
  required_providers {
    proxmox = {
      source  = "bpg/proxmox"
      version = "0.109.0"
    }
  }
}

provider "proxmox" {
  endpoint  = var.proxmox_endpoint
  api_token = var.proxmox_api_token
  insecure  = true

  ssh {
    agent       = false
    username    = "root"
    private_key = file("~/.ssh/id_ed25519")
  }
}

locals {
  ssh_key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDiWEYenDDJZJUdkxEDsEt76Nx1z0AJ5pnYGmoaaubDs theanibalos@gmail.com"
  nodes = {
    "201" = { name = "k3s-master-1", ip = "192.168.1.201" }
    "202" = { name = "k3s-worker-1", ip = "192.168.1.202" }
    "203" = { name = "k3s-worker-2", ip = "192.168.1.203" }
    "204" = { name = "k3s-worker-3", ip = "192.168.1.204" }
    "205" = { name = "k3s-worker-4", ip = "192.168.1.205" }
  }
}

# ─── 1. DESCARGA DE IMAGEN ──────────────────────────────────────────────────

resource "proxmox_download_file" "debian_cloud_image" {
  content_type        = "import"
  datastore_id        = "local"
  node_name           = "server"
  url                 = "https://cloud.debian.org/images/cloud/bookworm/latest/debian-12-generic-amd64.qcow2"
  file_name           = "debian-12-generic-amd64.qcow2"
  overwrite           = true
  overwrite_unmanaged = true
}

# ─── 2. CLOUD-INIT SNIPPETS ──────────────────────────────────────────────────

resource "proxmox_virtual_environment_file" "cloud_config" {
  for_each     = local.nodes
  content_type = "snippets"
  datastore_id = "RAM-DISK"
  node_name    = "server"

  source_raw {
    file_name = "cloud-config-${each.value.name}.yaml"
    data = <<-EOF
    #cloud-config
    hostname: ${each.value.name}
    users:
      - name: anibalos
        groups: sudo
        shell: /bin/bash
        ssh_authorized_keys:
          - ${local.ssh_key}
        sudo: ALL=(ALL) NOPASSWD:ALL
    package_update: true
    packages:
      - qemu-guest-agent
      - curl
    runcmd:
      - systemctl enable qemu-guest-agent
      - systemctl start qemu-guest-agent
    EOF
  }
}

# ─── 3. VMs DECLARATIVAS ─────────────────────────────────────────────────────

resource "proxmox_virtual_environment_vm" "k8s_nodes" {
  for_each = local.nodes

  node_name = "server"
  vm_id     = each.key
  name      = each.value.name
  tags      = ["k3s", "kubernetes", "terraform"]

  cpu {
    cores = 4
    type  = "x86-64-v2-AES"
  }

  memory {
    dedicated = 4096
  }

  agent {
    enabled = true
  }

  serial_device {}

  initialization {
    datastore_id = "RAM-DISK"
    user_data_file_id = proxmox_virtual_environment_file.cloud_config[each.key].id
    
    ip_config {
      ipv4 {
        address = "${each.value.ip}/24"
        gateway = "192.168.1.254"
      }
    }
    dns {
      servers = ["192.168.1.254"]
    }
  }

  disk {
    datastore_id = "RAM-DISK"
    import_from  = proxmox_download_file.debian_cloud_image.id
    interface    = "virtio0"
    iothread     = true
    size         = 16
  }

  network_device {
    bridge = "vmbr0"
  }
}

# ─── 4. INVENTORY ANSIBLE ───────────────────────────────────────────────────

resource "local_file" "ansible_inventory" {
  filename = "./inventory.ini"
  content  = <<EOT
[k3s_master]
%{ for id, vm in local.nodes ~}
%{ if length(regexall("master", vm.name)) > 0 ~}
${vm.name} ansible_host=${vm.ip} ansible_user=anibalos
%{ endif ~}
%{ endfor ~}

[k3s_workers]
%{ for id, vm in local.nodes ~}
%{ if length(regexall("worker", vm.name)) > 0 ~}
${vm.name} ansible_host=${vm.ip} ansible_user=anibalos
%{ endif ~}
%{ endfor ~}

[k3s_cluster:children]
k3s_master
k3s_workers

[k3s_cluster:vars]
ansible_ssh_common_args='-o StrictHostKeyChecking=no'
ansible_ssh_private_key_file=~/.ssh/id_ed25519
ansible_become=true
ansible_become_method=sudo
ansible_python_interpreter=/usr/bin/python3
EOT
}

# ─── 5. ANSIBLE PROVISIONING ────────────────────────────────────────────────

resource "null_resource" "ansible_run" {
  depends_on = [local_file.ansible_inventory, proxmox_virtual_environment_vm.k8s_nodes]

  triggers = {
    vm_ids = join(",", [for vm in proxmox_virtual_environment_vm.k8s_nodes : vm.id])
  }

  provisioner "local-exec" {
    command = "ANSIBLE_HOST_KEY_CHECKING=False ansible-playbook -i inventory.ini playbook.yml"
  }
}
