tofu(proxmox): API-only native cloud-init; move node baseline to Ansible node_baseline role

Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
jakman85andClaude Opus 4.8 committed 2026-08-25 10:55:48 -05:00
1 parent 8a8f28bf80
commit a2392a4a43
10 files changed
+143 -108

No files matched your search

+20 -32
View File
@@ -6,9 +6,10 @@
#
# Provider: bpg/proxmox. VMs land on the Proxmox node `var.proxmox_node`, disks on
# `var.datastore` (ZFS "Storage"), NIC on `var.bridge` (vmbr0), static IPs via the
# native cloud-init `initialization` block. The rich first-boot baseline (users,
# packages, kernel modules, Longhorn mount, swap-off) is delivered as a cloud-init
# user-data SNIPPET (see the snippets note in README / operator action below).
# native cloud-init `initialization` block. Native cloud-init (login user + SSH keys,
# static IP/gateway/DNS) is set via the Proxmox 8006 API. The rich first-boot baseline
# (packages, kernel modules, Longhorn mount, swap-off) is delivered by the Ansible
# `node_baseline` role (infra/ansible), run before k3s — not as a cloud-init snippet.
locals {
# Per-node identity/addressing, KEYED BY NODE NAME (map, not list).
@@ -45,31 +46,13 @@ resource "proxmox_virtual_environment_download_file" "debian_cloud_image" {
overwrite = false
}
# --- per-node cloud-init user-data snippet ----------------------------------
# bpg's native initialization.user_account only sets user/keys/password; it can't
# carry packages/write_files/runcmd. To preserve the full k3s/Cilium/Longhorn
# baseline we render the existing user-data.yaml.tftpl and ship it as a SNIPPET,
# referenced by the VM's initialization.user_data_file_id.
#
# OPERATOR ACTION: the `snippets` content type must be enabled on var.image_datastore
# (Datacenter -> Storage -> local -> Content -> add "Snippets"), else this file
# resource fails. See README "Operator prerequisites".
resource "proxmox_virtual_environment_file" "user_data" {
for_each = local.nodes
content_type = "snippets"
datastore_id = var.image_datastore
node_name = var.proxmox_node
source_raw {
file_name = "${each.value.name}-user-data.yaml"
data = templatefile("${path.module}/../cloud-init/user-data.yaml.tftpl", {
hostname = each.value.name
fqdn = each.value.fqdn
username = var.login_user
ssh_authorized_key = var.ssh_authorized_key
})
}
}
# --- cloud-init: NATIVE Proxmox cloud-init only (API-driven) ------------------
# The rich first-boot baseline (packages, kernel modules, Longhorn disk, swap-off)
# is NOT delivered as a custom snippet any more — custom snippets require SSH/SFTP
# to the Proxmox host, which is not reachable here. Instead the VM's `initialization`
# block below uses bpg's native user_account/ip_config/dns, which Proxmox sets via
# the built-in cloud-init API options (ciuser/sshkeys/ipconfig0/nameserver). The
# baseline moved to the Ansible `node_baseline` role (infra/ansible), run before k3s.
# --- the VMs ----------------------------------------------------------------
resource "proxmox_virtual_environment_vm" "node" {
@@ -93,9 +76,10 @@ resource "proxmox_virtual_environment_vm" "node" {
dedicated = var.memory_mib
}
# qemu-guest-agent is installed by cloud-init; lets tofu/Proxmox read guest state.
# qemu-guest-agent is installed by the Ansible node_baseline role now (not cloud-init),
# so don't block VM create on the agent — static IPs are assigned, not discovered.
agent {
enabled = true
enabled = false
}
operating_system {
@@ -126,7 +110,8 @@ resource "proxmox_virtual_environment_vm" "node" {
}
# Static addressing + DNS come from cloud-init (bpg generates the network-config),
# so the libvirt netplan template is gone. User-data (the baseline) is the snippet.
# so the libvirt netplan template is gone. Native cloud-init (login user + SSH keys)
# comes from user_account below; the OS baseline is the Ansible node_baseline role.
initialization {
datastore_id = var.datastore
@@ -141,7 +126,10 @@ resource "proxmox_virtual_environment_vm" "node" {
servers = [var.dns_server]
}
user_data_file_id = proxmox_virtual_environment_file.user_data[each.key].id
user_account {
username = var.login_user
keys = [trimspace(var.ssh_authorized_key)]
}
}
# Boot from the OS disk only.