# node-vm: a single MAAS-managed OpenStack node VM (D-103's "OpenTofu creates
# the node-VM libvirt domains (SHIM -- Section 9)" -- Stage 3 / buildout-design
# Phase 2). BLANK disk, PXE-boot -- this is deliberately NOT the cloud-init +
# pre-built-image pattern (that's a separate, still-unbuilt module for Office1
# service VMs / OPNsense; see opentofu/README.md). MAAS enlists, commissions,
# and deploys these VMs after OpenTofu creates them; OpenTofu does not image
# them itself.
#
# Every attribute below is used exactly as shown in the provider's own
# examples/domain_with_network.tf and examples/alpine_cloudinit.tf (fetched
# and read directly this session, tag v0.9.8) -- attribute-style nested
# objects (`os = { ... }`, `devices = { ... }`), NOT classic HCL blocks. The
# ONE inference in this file, the per-device `boot` object's internal shape
# (`order`), is now BETTER-SUPPORTED after a 2026-07-09 audit pass (see
# opentofu/README.md): the provider is confirmed to code-generate its schema
# as a 1:1 mirror of libvirt's own domain XML, and libvirt's own official
# docs confirm the native XML element is exactly `<boot order='N'/>` (one
# attribute, `order`) -- consistent with every other single-attribute
# element already confirmed in this schema (e.g. `mtu = { size = N }` mirrors
# `<mtu size='N'/>`). Reasonably confident, not a blind guess anymore, but
# still not seen in an actual generated schema dump -- VERIFY with
# `tofu providers schema -json` before the first real apply regardless; if
# wrong, `tofu plan` will simply reject the attribute name, not silently
# misconfigure anything.

resource "libvirt_volume" "disk" {
  name     = "${var.vm_name}-disk.qcow2"
  pool     = var.pool_name
  capacity = var.disk_size_bytes
  format = {
    type = "qcow2"
  }
}

resource "libvirt_domain" "node" {
  name   = var.vm_name
  memory = var.memory_mib
  vcpu   = var.vcpu
  type   = "kvm"
  running = true

  os = {
    type         = "hvm"
    type_arch    = "x86_64"
    type_machine = "q35"
  }

  devices = {
    disks = [
      {
        source = {
          volume = {
            pool   = libvirt_volume.disk.pool
            volume = libvirt_volume.disk.name
          }
        }
        target = {
          dev = "vda"
          bus = "virtio"
        }
        driver = {
          type = "qcow2"
        }
        # boot.order shape UNVERIFIED (see file header) -- disk boots second,
        # network boots first (PXE).
        boot = {
          order = 2
        }
      }
    ]

    interfaces = [
      for i, net_name in var.network_names : {
        model = {
          type = "virtio"
        }
        source = {
          network = {
            network = net_name
          }
        }
        # only the first (PXE) interface gets an explicit boot order;
        # see the disk boot-order note above for the same caveat.
        boot = i == 0 ? { order = 1 } : null
      }
    ]
  }
}
