forked from fediversity/fediversity
		
	
		
			
				
	
	
		
			224 lines
		
	
	
	
		
			6.4 KiB
		
	
	
	
		
			HCL
		
	
	
	
	
	
			
		
		
	
	
			224 lines
		
	
	
	
		
			6.4 KiB
		
	
	
	
		
			HCL
		
	
	
	
	
	
terraform {
 | 
						|
  required_providers {
 | 
						|
    proxmox = {
 | 
						|
      source  = "bpg/proxmox"
 | 
						|
      version = "= 0.81.0"
 | 
						|
    }
 | 
						|
  }
 | 
						|
  backend "http" {
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
locals {
 | 
						|
  dump_name = "qemu-nixos-fediversity-${var.category}.qcow2"
 | 
						|
}
 | 
						|
 | 
						|
# https://registry.terraform.io/providers/bpg/proxmox/latest/docs
 | 
						|
provider "proxmox" {
 | 
						|
  endpoint = "https://${var.host}:8006/"
 | 
						|
  insecure = true
 | 
						|
  # FIXME secure
 | 
						|
  # insecure = false
 | 
						|
 | 
						|
  # used only for files and creating custom disks
 | 
						|
  ssh {
 | 
						|
    agent = true
 | 
						|
    # uncomment and configure if using api_token instead of password
 | 
						|
    username = "root"
 | 
						|
    # node {
 | 
						|
    #   name = "${var.node_name}"
 | 
						|
    #   address = "${var.host}"
 | 
						|
    #   # port = 22
 | 
						|
    # }
 | 
						|
  }
 | 
						|
 | 
						|
  # # Choose one authentication method:
 | 
						|
  # api_token = var.virtual_environment_api_token
 | 
						|
  # # OR
 | 
						|
  username  = var.proxmox_user
 | 
						|
  password  = var.proxmox_password
 | 
						|
  # # OR
 | 
						|
  # auth_ticket           = var.virtual_environment_auth_ticket
 | 
						|
  # csrf_prevention_token = var.virtual_environment_csrf_prevention_token
 | 
						|
}
 | 
						|
 | 
						|
# # FIXME move to host
 | 
						|
# # FIXME add proxmox
 | 
						|
# data "external" "base-hash" {
 | 
						|
#   program = ["sh", "-c", "echo \"{\\\"hash\\\":\\\"$(nix-hash ${path.module}/../common/nixos/base.nix)\\\"}\""]
 | 
						|
# }
 | 
						|
 | 
						|
# # hash of our code directory, used to trigger re-deploy
 | 
						|
# # FIXME calculate separately to reduce false positives
 | 
						|
# data "external" "hash" {
 | 
						|
#   program = ["sh", "-c", "echo \"{\\\"hash\\\":\\\"$(nix-hash ..)\\\"}\""]
 | 
						|
# }
 | 
						|
 | 
						|
# FIXME handle known-hosts in TF state
 | 
						|
# FIXME move to host
 | 
						|
# FIXME switch to base image shared between jobs as upload seems a bottleneck? e.g. by:
 | 
						|
# - recursive TF
 | 
						|
# - hash in name over overwrite
 | 
						|
# won't notice file changes: https://github.com/bpg/terraform-provider-proxmox/issues/677
 | 
						|
resource "proxmox_virtual_environment_file" "upload" {
 | 
						|
  # # https://developer.hashicorp.com/terraform/plugin/sdkv2/resources/retries-and-customizable-timeouts
 | 
						|
  # timeouts {
 | 
						|
  #   create = "60m"
 | 
						|
  # }
 | 
						|
 | 
						|
  # content_type - (Optional) The content type. If not specified, the content type will be inferred from the file extension. Valid values are:
 | 
						|
  #     backup (allowed extensions: .vzdump, .tar.gz, .tar.xz, tar.zst)
 | 
						|
  #     iso (allowed extensions: .iso, .img)
 | 
						|
  #     snippets (allowed extensions: any)
 | 
						|
  #     import (allowed extensions: .raw, .qcow2, .vmdk)
 | 
						|
  #     vztmpl (allowed extensions: .tar.gz, .tar.xz, tar.zst)
 | 
						|
  # content_type = "backup"
 | 
						|
  content_type = "import"
 | 
						|
  # https://192.168.51.81:8006/#v1:0:=storage%2Fnode051%2Flocal:4::=contentIso:::::
 | 
						|
  # PVE -> Datacenter -> Storage -> local -> Edit -> General -> Content -> check Import + Disk Images -> OK
 | 
						|
  # that UI action also adds it in `/etc/pve/storage.cfg`
 | 
						|
  datastore_id = var.image_datastore_id
 | 
						|
  node_name    = var.node_name
 | 
						|
  overwrite = true
 | 
						|
  timeout_upload = 180
 | 
						|
  # timeout_upload = 1
 | 
						|
 | 
						|
  source_file {
 | 
						|
    # path = "/tmp/proxmox-image/${local.dump_name}"
 | 
						|
    path = var.image
 | 
						|
    file_name = local.dump_name
 | 
						|
    # FIXME compute and pass hash (so identical builds don't trigger drift)
 | 
						|
    # checksum = "sha256"
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
resource "proxmox_virtual_environment_vm" "nix_vm" {
 | 
						|
  lifecycle {
 | 
						|
    # wait, would this not disseminate any changes to this property,
 | 
						|
    # or just defer syncing when only this changed?
 | 
						|
    ignore_changes = [
 | 
						|
      disk["import_from"],
 | 
						|
    ]
 | 
						|
  }
 | 
						|
  node_name      = var.node_name
 | 
						|
  pool_id        = var.pool_id
 | 
						|
  description    = var.description
 | 
						|
  started        = true
 | 
						|
 | 
						|
  # https://wiki.nixos.org/wiki/Virt-manager#Guest_Agent
 | 
						|
  agent {
 | 
						|
    enabled = true
 | 
						|
    # timeout = "5m"
 | 
						|
    timeout = "2m"
 | 
						|
    trim = true
 | 
						|
  }
 | 
						|
 | 
						|
  cpu {
 | 
						|
    type         = "x86-64-v2-AES"
 | 
						|
    cores        = var.cores
 | 
						|
    sockets      = var.sockets
 | 
						|
    numa         = true
 | 
						|
  }
 | 
						|
 | 
						|
  memory {
 | 
						|
    dedicated    = var.memory
 | 
						|
  }
 | 
						|
 | 
						|
  disk {
 | 
						|
    datastore_id = var.vm_datastore_id
 | 
						|
    file_format  = "qcow2"
 | 
						|
    interface    = "scsi0"
 | 
						|
    discard      = "on"
 | 
						|
    iothread     = true
 | 
						|
    size         = var.disk_size
 | 
						|
    ssd          = true
 | 
						|
    backup       = false
 | 
						|
    cache        = "none"
 | 
						|
 | 
						|
    # FIXME make the provider allow this as a distinct block to allow making this depend on VM id?
 | 
						|
    # FIXME replace with an effectful ~~function~~template from vm_id replacing resource `proxmox_virtual_environment_file.upload`
 | 
						|
    # import_from  = "local:import/${proxmox_virtual_environment_vm.nix_vm.vm_id}-${local.dump_name}" # bogus import name to test if it would accept self-referential values here # may not refer to itself
 | 
						|
    # import_from  = "local:import/${local.dump_name}"
 | 
						|
    import_from  = proxmox_virtual_environment_file.upload.id
 | 
						|
  }
 | 
						|
 | 
						|
  efi_disk {
 | 
						|
    datastore_id = var.vm_datastore_id
 | 
						|
    file_format  = "qcow2"
 | 
						|
    type         = "4m"
 | 
						|
  }
 | 
						|
 | 
						|
  network_device {
 | 
						|
    model        = "virtio"
 | 
						|
    bridge       = var.bridge
 | 
						|
    vlan_id      = var.vlan_id
 | 
						|
  }
 | 
						|
 | 
						|
  operating_system {
 | 
						|
    type         = "l26"
 | 
						|
  }
 | 
						|
 | 
						|
  scsi_hardware  = "virtio-scsi-single"
 | 
						|
  bios           = "ovmf"
 | 
						|
 | 
						|
  initialization {
 | 
						|
    datastore_id = var.cd_datastore_id
 | 
						|
    interface = "sata2"
 | 
						|
    ip_config {
 | 
						|
      ipv4 {
 | 
						|
        gateway = var.ipv4_gateway
 | 
						|
        address = var.ipv4_address
 | 
						|
      }
 | 
						|
      # ipv6 {
 | 
						|
      #   gateway = var.ipv6_gateway
 | 
						|
      #   address = var.ipv6_address
 | 
						|
      # }
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
resource "null_resource" "wait_for_ssh" {
 | 
						|
  depends_on = [
 | 
						|
    proxmox_virtual_environment_vm.nix_vm
 | 
						|
  ]
 | 
						|
  provisioner "local-exec" {
 | 
						|
    command = <<-EOT
 | 
						|
      for i in $(seq 1 30); do
 | 
						|
        if ssh -vvv \
 | 
						|
        -i "${var.key_file}" \
 | 
						|
        -o BatchMode=yes \
 | 
						|
        -o StrictHostKeyChecking=no \
 | 
						|
        -o ConnectTimeout=1 \
 | 
						|
        -o ServerAliveInterval=1 \
 | 
						|
        root@${proxmox_virtual_environment_vm.nix_vm.ipv4_addresses[1][0]} "true"; then
 | 
						|
          exit 0
 | 
						|
        fi
 | 
						|
        echo "Waiting for SSH (attempt #$i)..."
 | 
						|
        sleep 5
 | 
						|
      done
 | 
						|
      echo "SSH never came up!" >&2
 | 
						|
      exit 1
 | 
						|
    EOT
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
# FIXME expose (and handle thru) [`exec`](https://pve.proxmox.com/pve-docs/api-viewer/#/nodes/{node}/qemu/{vmid}/agent/exec) endpoint in proxmox TF provider? wait, what command would i use it for?: https://github.com/bpg/terraform-provider-proxmox/issues/1576
 | 
						|
module "nixos-rebuild" {
 | 
						|
  depends_on = [
 | 
						|
    null_resource.wait_for_ssh
 | 
						|
  ]
 | 
						|
  source = "../tf-single-host"
 | 
						|
  nixos_conf = var.nixos_conf
 | 
						|
  # username = var.ssh_user # refers to the proxmox ssh user, not the VM one
 | 
						|
  username = "root"
 | 
						|
  host = proxmox_virtual_environment_vm.nix_vm.ipv4_addresses[1][0]
 | 
						|
  key_file = var.key_file
 | 
						|
  ssh_opts = var.ssh_opts
 | 
						|
}
 | 
						|
 | 
						|
output "ipv4" {
 | 
						|
  value = proxmox_virtual_environment_vm.nix_vm.ipv4_addresses[1]
 | 
						|
}
 | 
						|
output "ipv6" {
 | 
						|
  value = proxmox_virtual_environment_vm.nix_vm.ipv6_addresses[1]
 | 
						|
}
 |