# ESXi

variable "skylab_ssh_public_key_path" {
  default = "/home/student/.ssh/skylab.pub"
}

data "local_file" "ssh_key" {
  filename = var.skylab_ssh_public_key_path
}

variable "azure_private_key_path" {
  default = "/home/student/.ssh/azure"
}

data "local_file" "azure_private_key" {
  filename = var.azure_private_key_path
}

# Render userdata template with skylab SSH key
data "template_file" "esxi_userdata" {
  template = file("${path.module}/userdata.tftpl")
  vars = {
    skylab-ssh-key    = trimspace(data.local_file.ssh_key.content)
    azure-private-key = indent(6, trimspace(data.local_file.azure_private_key.content))
    azure-vm-ip       = azurerm_linux_virtual_machine.main.public_ip_address
  }
}


# resource "esxi_vswitch" "myvswitch" {
#   name = "${var.prefix}-vswitch"
#   uplink {
#     name = "vmnic0"
#   }
# }

resource "esxi_portgroup" "week-2-opdracht-2" {
  name    = "${var.prefix}-network"
  vswitch = "vSwitch0"
}

resource "esxi_guest" "webserver" {
  guest_name = "${var.prefix}-webserver-${count.index}"
  disk_store = "datastore1"
  count      = 2

  memsize  = "2048"
  numvcpus = "1"
  power    = "on"

  ovf_source = "https://cloud-images.ubuntu.com/releases/24.04/release/ubuntu-24.04-server-cloudimg-amd64.ova"

  network_interfaces {
    virtual_network = esxi_portgroup.week-2-opdracht-2.name
  }

  guestinfo = {
    "metadata" = base64encode(templatefile("${path.module}/metadata.yaml", {
      hostname = "${var.prefix}-webserver-${count.index}" # Directly using count.index for hostname
    }))
    "metadata.encoding" = "base64"
    "userdata"          = base64encode(data.template_file.esxi_userdata.rendered)
    "userdata.encoding" = "base64"
  }
}

resource "esxi_guest" "databaseserver" {
  guest_name = "${var.prefix}-databaseserver-${count.index}"
  disk_store = "datastore1"
  count      = 1

  memsize  = "2048"
  numvcpus = "1"
  power    = "on"

  ovf_source = "https://cloud-images.ubuntu.com/releases/24.04/release/ubuntu-24.04-server-cloudimg-amd64.ova"

  network_interfaces {
    virtual_network = esxi_portgroup.week-2-opdracht-2.name
  }

  guestinfo = {
    "metadata" = base64encode(templatefile("${path.module}/metadata.yaml", {
      hostname = "${var.prefix}-databaseserver-${count.index}" # Directly using count.index for hostname
    }))
    "metadata.encoding" = "base64"
    "userdata"          = base64encode(data.template_file.esxi_userdata.rendered)
    "userdata.encoding" = "base64"
  }
}

# Azure

resource "azurerm_virtual_network" "main" {
  name                = "${var.prefix}-network"
  address_space       = ["10.0.0.0/16"]
  location            = var.azure_location
  resource_group_name = var.azure_resourcegroup
}

resource "azurerm_subnet" "main" {
  name                 = "internal"
  resource_group_name  = var.azure_resourcegroup
  virtual_network_name = azurerm_virtual_network.main.name
  address_prefixes     = ["10.0.2.0/24"]
}

resource "azurerm_public_ip" "pip" {
  name                = "${var.prefix}-pip"
  resource_group_name = var.azure_resourcegroup
  location            = var.azure_location
  allocation_method   = "Static"
}

resource "azurerm_network_interface" "main" {
  name                = "${var.prefix}-nic"
  location            = var.azure_location
  resource_group_name = var.azure_resourcegroup

  ip_configuration {
    name                          = "internal"
    subnet_id                     = azurerm_subnet.main.id
    private_ip_address_allocation = "Dynamic"
    public_ip_address_id          = azurerm_public_ip.pip.id
  }
}

resource "azurerm_network_security_group" "main" {
  name                = "${var.prefix}-nsg"
  location            = var.azure_location
  resource_group_name = var.azure_resourcegroup
  security_rule {
    access                     = "Allow"
    direction                  = "Inbound"
    name                       = "tls"
    priority                   = 100
    protocol                   = "Tcp"
    source_port_range          = "*"
    source_address_prefix      = "*"
    destination_port_range     = "22"
    destination_address_prefix = azurerm_network_interface.main.private_ip_address
  }
}

resource "azurerm_network_interface_security_group_association" "main" {
  network_interface_id      = azurerm_network_interface.main.id
  network_security_group_id = azurerm_network_security_group.main.id
}

# Render userdata template with skylab SSH key
data "template_file" "azure_cloudinit" {
  template = file("${path.module}/cloudinit-azure.yaml")
  vars = {
    azure-ssh-key = trimspace(data.azurerm_ssh_public_key.azure.public_key)
  }
}

resource "azurerm_linux_virtual_machine" "main" {
  name                = "${var.prefix}-vm"
  location            = var.azure_location
  resource_group_name = var.azure_resourcegroup
  network_interface_ids = [
    azurerm_network_interface.main.id,
  ]
  size = "Standard_B2ats_v2"

  admin_username = "adminuser"
  admin_ssh_key {
    username   = "adminuser"
    public_key = data.azurerm_ssh_public_key.azure.public_key
  }

  custom_data = base64encode(data.template_file.azure_cloudinit.rendered)

  os_disk {
    caching              = "ReadWrite"
    storage_account_type = "Standard_LRS"
  }

  source_image_reference {
    publisher = "Canonical"
    offer     = "ubuntu-24_04-lts"
    sku       = "server"
    version   = "latest"
  }
}

# Write ESXi IP adresses to file
resource "local_file" "vm_info" {
  content = join("\n",
    ["ESXi VM's Private IP Adresses:"],
    concat(
      [
        for guest in esxi_guest.webserver :
        "${guest.guest_name} - ${guest.ip_address}"
      ],
      [
        for guest in esxi_guest.databaseserver :
        "${guest.guest_name} - ${guest.ip_address}"
        ], [
        "Azure VM's Private IP Adresses:",
        "${azurerm_linux_virtual_machine.main.name} - ${azurerm_linux_virtual_machine.main.private_ip_address}",
        "Azure VM's Public IP Adresses:",
    "${azurerm_linux_virtual_machine.main.name} - ${azurerm_linux_virtual_machine.main.public_ip_address}"])
  )

  filename = "${path.module}/vm_info.txt"
}

output "ip_addresses" {
  value = local_file.vm_info.content
}
