Personal Homelab
at master 186 lines 4.4 kB view raw
1locals { 2 // Add secrets into quadlets config 3 containers_config = merge(var.containers_config, { 4 proxmox_ip : var.proxmox_config.host, 5 truenas_ip : var.fcos_config.truenas_ip, 6 fcos_ip : var.fcos_config.ip, 7 }) 8 9 # Get a list of all files in the specified directory 10 config_paths = fileset("${path.module}/configs", "**") 11 config_files = { 12 for cfgpath in local.config_paths : 13 replace(cfgpath, ".tftpl", "") => templatefile("${path.module}/configs/${cfgpath}", local.containers_config) 14 } 15 # Terraform hasn't directory alternative for fileset method 16 config_dirs = provider::homelab-helpers::dirset("${path.module}/configs", "**") 17 18 butane_config = merge(var.fcos_config, { 19 config_files : local.config_files, 20 config_dirs : local.config_dirs, 21 }) 22 23 config_rendered_files = { 24 for path, content in local.config_files : 25 path => content 26 } 27 28 init_script_path = "${path.module}/scripts/init_fcos.sh.tftpl" 29 get_secret_script_path = "${path.module}/scripts/get_secret.sh" 30} 31 32output "directories_to_create" { 33 value = local.config_dirs 34} 35 36data "ct_config" "fcos_ignition" { 37 content = templatefile("${path.module}/butane/fcos.yml.tftpl", local.butane_config) 38 strict = true 39} 40 41resource "proxmox_virtual_environment_vm" "fcos" { 42 node_name = "pve" 43 name = "fcos" 44 description = "Managed by OpenTofu" 45 46 lifecycle { 47 ignore_changes = [ 48 disk["file_id"], 49 kvm_arguments 50 ] 51 } 52 53 # Use modern platform 54 machine = "q35" 55 bios = "ovmf" 56 scsi_hardware = "virtio-scsi-single" 57 58 startup { 59 order = 20 60 } 61 62 cpu { 63 cores = 16 64 type = "Skylake-Client-v4" 65 } 66 67 memory { 68 dedicated = 32768 69 floating = 32768 70 } 71 72 efi_disk { 73 datastore_id = "local-zfs" 74 type = "4m" 75 pre_enrolled_keys = true 76 } 77 78 disk { 79 interface = "virtio0" 80 datastore_id = "local-zfs" 81 file_id = proxmox_virtual_environment_file.fcos_qcow2.id 82 size = 32 83 } 84 85 tpm_state { 86 datastore_id = "local-zfs" 87 } 88 89 network_device { 90 bridge = "vmbr0" 91 vlan_id = 100 92 mac_address = var.fcos_config.mac_address 93 } 94 95 # Linux 6.x 96 operating_system { 97 type = "l26" 98 } 99 100 # Intel Arc Pro B50 video 101 hostpci { 102 device = "hostpci0" 103 id = "0000:03:00.1" 104 pcie = true 105 rombar = true 106 } 107 108 agent { 109 enabled = true 110 } 111 112 kvm_arguments = "-fw_cfg 'name=opt/com.coreos/config,string=${replace(data.ct_config.fcos_ignition.rendered, ",", ",,")}' -smbios type=11,value=io.systemd.credential:bws-access-token=${var.bws_access_token}" 113} 114 115resource "null_resource" "fcos_provision_secrets" { 116 depends_on = [proxmox_virtual_environment_vm.fcos] 117 118 triggers = { 119 checksum = sha256(file(local.init_script_path)) 120 } 121 122 connection { 123 type = "ssh" 124 user = "core" 125 private_key = file(pathexpand(var.fcos_config.ssh_private_key_path)) 126 host = var.fcos_config.ip 127 } 128 129 provisioner "file" { 130 destination = "/var/tmp/init.sh" 131 content = templatefile(local.init_script_path, { 132 config_files : local.config_files 133 secret_uuids : var.containers_secret_config 134 }) 135 } 136 137 provisioner "file" { 138 destination = "/home/core/.local/bin/get_secret.sh" 139 content = file(local.get_secret_script_path) 140 } 141 142 provisioner "remote-exec" { 143 inline = ["sh /var/tmp/init.sh"] 144 on_failure = fail 145 } 146} 147 148resource "null_resource" "sync_configs" { 149 depends_on = [proxmox_virtual_environment_vm.fcos] 150 151 triggers = { 152 configs_hash = provider::homelab-helpers::dirhash("${path.module}/configs", "**") 153 } 154 155 connection { 156 type = "ssh" 157 user = "core" 158 private_key = file(pathexpand(var.fcos_config.ssh_private_key_path)) 159 host = var.fcos_config.ip 160 } 161 162 // Create directories if not exist 163 provisioner "remote-exec" { 164 inline = distinct([ 165 for path, _ in local.config_rendered_files : 166 "mkdir -p /var/home/core/.config/${replace(dirname(path), "\\", "/")}" 167 ]) 168 } 169 170 // Copy files, but remove the last byte to avoid double newline 171 provisioner "remote-exec" { 172 inline = [ 173 for path, content in local.config_rendered_files : <<-EOT 174 cat <<'EOF' | head -c -1 > "/var/home/core/.config/${path}" 175 ${content} 176 EOF 177 EOT 178 ] 179 } 180 181 provisioner "remote-exec" { 182 inline = [ 183 "systemctl --user daemon-reload" 184 ] 185 } 186}