diff --git a/.gitignore b/.gitignore index 11ce9bc..8068363 100644 --- a/.gitignore +++ b/.gitignore @@ -10,4 +10,3 @@ terraform/terraform.tfvars terraform/*.auto.tfvars terraform/crash.log terraform/crash.*.log -terraform/.generated/ diff --git a/terraform/cloud-init.tf b/terraform/cloud-init.tf index 2779145..837a2fb 100644 --- a/terraform/cloud-init.tf +++ b/terraform/cloud-init.tf @@ -1,55 +1,51 @@ -# Cloud-init configuration for branch-specific bootstrap +# Cloud-init configuration for all VMs # -# This file manages custom cloud-init snippets for VMs that need to bootstrap -# from a specific git branch (non-master). Production VMs omit flake_branch -# and use the default master branch. +# This file manages cloud-init disks for all VMs using the proxmox_cloud_init_disk resource. +# VMs with flake_branch set will include NIXOS_FLAKE_BRANCH environment variable. -# Generate cloud-init snippets for VMs with custom branch configuration -resource "local_file" "cloud_init_branch" { - for_each = { - for name, vm in local.vm_configs : name => vm - if vm.flake_branch != null - } +resource "proxmox_cloud_init_disk" "ci" { + for_each = local.vm_configs - filename = "${path.module}/.generated/cloud-init-${each.key}.yml" - content = yamlencode({ - # Write NIXOS_FLAKE_BRANCH to /etc/environment - # This will be read by bootstrap.nix service via EnvironmentFile - write_files = [{ - path = "/etc/environment" - content = "NIXOS_FLAKE_BRANCH=${each.value.flake_branch}\n" - append = true + name = each.key + pve_node = each.value.target_node + storage = each.value.storage + + # User data includes SSH keys and optionally NIXOS_FLAKE_BRANCH + user_data = <<-EOT + #cloud-config + ssh_authorized_keys: + - ${each.value.ssh_public_key} + ${each.value.flake_branch != null ? <<-BRANCH + write_files: + - path: /etc/environment + content: | + NIXOS_FLAKE_BRANCH=${each.value.flake_branch} + append: true + BRANCH +: ""} + EOT + +# Network configuration - static IP or DHCP +network_config = yamlencode({ + version = 1 + config = [{ + type = "physical" + name = "ens18" + subnets = each.value.ip != null ? [{ + type = "static" + address = each.value.ip + gateway = each.value.gateway + dns_nameservers = split(" ", each.value.nameservers) + dns_search = [each.value.search_domain] + }] : [{ + type = "dhcp" }] - }) + }] +}) - file_permission = "0644" +# Instance metadata +meta_data = yamlencode({ + instance_id = sha1(each.key) + local-hostname = each.key +}) } - -# Upload cloud-init snippets to Proxmox -# Note: This requires SSH access to the Proxmox host -# Alternative: Manually copy files or use Proxmox API if available -resource "null_resource" "upload_cloud_init" { - for_each = { - for name, vm in local.vm_configs : name => vm - if vm.flake_branch != null - } - - # Trigger re-upload when content changes - triggers = { - content_hash = local_file.cloud_init_branch[each.key].content - } - - # Upload the cloud-init file to Proxmox snippets directory - provisioner "local-exec" { - command = <<-EOT - scp -o StrictHostKeyChecking=no \ - ${local_file.cloud_init_branch[each.key].filename} \ - ${var.proxmox_host}:/var/lib/vz/snippets/cloud-init-${each.key}.yml - EOT - } - - depends_on = [local_file.cloud_init_branch] -} - -# Ensure VMs depend on cloud-init being uploaded -# This is handled implicitly by the cicustom reference in vms.tf diff --git a/terraform/variables.tf b/terraform/variables.tf index c6acc26..fe13cb0 100644 --- a/terraform/variables.tf +++ b/terraform/variables.tf @@ -21,12 +21,6 @@ variable "proxmox_tls_insecure" { default = true } -variable "proxmox_host" { - description = "Proxmox host for SSH access (used to upload cloud-init snippets)" - type = string - default = "pve1.home.2rjus.net" -} - # Default values for VM configurations # These can be overridden per-VM in vms.tf diff --git a/terraform/vms.tf b/terraform/vms.tf index 604377f..340b2cb 100644 --- a/terraform/vms.tf +++ b/terraform/vms.tf @@ -32,10 +32,10 @@ locals { # "minimal-vm" = {} # "bootstrap-verify-test" = {} "testvm01" = { - ip = "10.69.13.101/24" - cpu_cores = 2 - memory = 2048 - disk_size = "20G" + ip = "10.69.13.101/24" + cpu_cores = 2 + memory = 2048 + disk_size = "20G" flake_branch = "pipeline-testing-improvements" } } @@ -104,8 +104,9 @@ resource "proxmox_vm_qemu" "vm" { } ide { ide2 { - cloudinit { - storage = each.value.storage + # Reference the custom cloud-init disk created in cloud-init.tf + cdrom { + iso = proxmox_cloud_init_disk.ci[each.key].id } } } @@ -117,18 +118,6 @@ resource "proxmox_vm_qemu" "vm" { # Agent agent = 1 - # Cloud-init configuration - ciuser = "root" - sshkeys = each.value.ssh_public_key - nameserver = each.value.nameservers - searchdomain = each.value.search_domain - - # Network configuration - DHCP or static IP - ipconfig0 = each.value.ip != null ? "ip=${each.value.ip},gw=${each.value.gateway}" : "ip=dhcp" - - # Custom cloud-init disk for branch configuration (if flake_branch is set) - cicustom = each.value.flake_branch != null ? "user=${each.value.storage}:snippets/cloud-init-${each.key}.yml" : null - # Skip IPv6 since we don't use it skip_ipv6 = true