diff --git a/.gitignore b/.gitignore index 852f36f..312de7e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,14 +1,3 @@ -# OpenTofu / Terraform -.terraform/ -.tofu/ -.terraform.lock.hcl -.tofu.lock.hcl -terraform.tfstate -terraform.tfstate.* -crash.log -*.tfvars -*.tfvars.json - inventory.ini venv/* .env diff --git a/ansible/infra/nodito/33_proxmox_debian_cloud_template.yml b/ansible/infra/nodito/33_proxmox_debian_cloud_template.yml index 40cf26e..ff69525 100644 --- a/ansible/infra/nodito/33_proxmox_debian_cloud_template.yml +++ b/ansible/infra/nodito/33_proxmox_debian_cloud_template.yml @@ -26,9 +26,6 @@ proxmox_sshkey_path: "/home/{{ new_user }}/.ssh/authorized_keys" # Path to pubkey file for cloud-init injection proxmox_ci_upgrade: true # If true, run package upgrade on first boot - # Auto-install qemu-guest-agent in clones via cloud-init snippet - qemu_agent_snippet_filename: "user-data-qemu-agent.yaml" - # Storage to import disk into; use existing storage like local-lvm or your ZFS pool name proxmox_image_storage: "{{ zfs_pool_name }}" @@ -39,6 +36,8 @@ changed_when: false failed_when: pve_version_check.rc != 0 + + - name: Ensure destination directory exists for cloud image file: path: "{{ debian_cloud_image_dest_dir }}" @@ -58,42 +57,6 @@ force: false when: not debian_image_stat.stat.exists - - name: Ensure local storage allows snippets content (used for cloud-init snippets) - command: > - pvesm set local --content images,iso,vztmpl,snippets - failed_when: false - - - name: Ensure snippets directory exists on storage mountpoint - file: - path: "{{ zfs_pool_mountpoint }}/snippets" - state: directory - mode: '0755' - - - name: Read SSH public key content - slurp: - src: "{{ proxmox_sshkey_path }}" - register: ssh_key_content - - - name: Extract SSH keys from authorized_keys file - set_fact: - ssh_keys_list: "{{ ssh_key_content.content | b64decode | split('\n') | select('match', '^ssh-') | list }}" - - - name: Write cloud-init vendor-data snippet to install qemu-guest-agent - copy: - dest: "{{ zfs_pool_mountpoint }}/snippets/{{ qemu_agent_snippet_filename }}" - mode: '0644' - content: | - #cloud-config - # Vendor-data snippet: Proxmox will automatically set hostname from VM name when using vendor-data - # User info (ciuser/sshkeys) is set separately via Terraform/Proxmox parameters - package_update: true - package_upgrade: true - packages: - - qemu-guest-agent - runcmd: - - systemctl enable qemu-guest-agent - - systemctl start qemu-guest-agent - - name: Check if VMID already exists command: qm config {{ proxmox_template_vmid }} register: vmid_config_check @@ -128,22 +91,6 @@ when: - vmid_config_check.rc != 0 or not vm_already_template - - name: Check if ide2 (cloudinit) drive exists - command: qm config {{ proxmox_template_vmid }} - register: vm_config_check - failed_when: false - changed_when: false - when: - - vmid_config_check.rc == 0 - - - name: Remove existing ide2 (cloudinit) drive if it exists for idempotency - command: > - qm set {{ proxmox_template_vmid }} --delete ide2 - register: ide2_removed - when: - - vmid_config_check.rc == 0 - - "'ide2:' in vm_config_check.stdout" - - name: Build consolidated qm set argument list (simplified) set_fact: qm_set_args: >- @@ -163,16 +110,15 @@ ] + (proxmox_ci_upgrade | bool | ternary(['--ciupgrade 1'], [])) - + ['--cicustom vendor=local:snippets/' ~ qemu_agent_snippet_filename] }} when: - - vmid_config_check.rc != 0 or not vm_already_template | default(false) or ide2_removed.changed | default(false) + - vmid_config_check.rc != 0 or not vm_already_template - name: Apply consolidated qm set command: > qm set {{ proxmox_template_vmid }} {{ qm_set_args | join(' ') }} when: - - vmid_config_check.rc != 0 or not vm_already_template | default(false) or ide2_removed.changed | default(false) + - vmid_config_check.rc != 0 or not vm_already_template - name: Resize primary disk to requested size command: > @@ -184,3 +130,13 @@ command: qm template {{ proxmox_template_vmid }} when: - vmid_config_check.rc == 0 and not vm_already_template or vmid_config_check.rc != 0 + + - name: Show resulting template configuration + command: qm config {{ proxmox_template_vmid }} + register: final_template_config + changed_when: false + + - name: Debug final template config + debug: + msg: "{{ final_template_config.stdout }}" + diff --git a/tofu/nodito/README.md b/tofu/nodito/README.md deleted file mode 100644 index a6762a5..0000000 --- a/tofu/nodito/README.md +++ /dev/null @@ -1,66 +0,0 @@ -## Nodito VMs with OpenTofu (Proxmox) - -This directory lets you declare VMs on the `nodito` Proxmox node and apply with OpenTofu. It clones the Ansible-built template `debian-13-cloud-init` and places disks on the ZFS pool `proxmox-tank-1`. - -### Prereqs -- Proxmox API token with VM privileges. Example: user `root@pam`, token name `tofu`. -- OpenTofu installed. - ``` - sudo apt-get update - sudo apt-get install -y apt-transport-https ca-certificates curl gnupg - - sudo install -m 0755 -d /etc/apt/keyrings - curl -fsSL https://get.opentofu.org/opentofu.gpg | sudo tee /etc/apt/keyrings/opentofu.gpg >/dev/null - curl -fsSL https://packages.opentofu.org/opentofu/tofu/gpgkey | sudo gpg --no-tty --batch --dearmor -o /etc/apt/keyrings/opentofu-repo.gpg >/dev/null - sudo chmod a+r /etc/apt/keyrings/opentofu.gpg /etc/apt/keyrings/opentofu-repo.gpg - - echo \ - "deb [signed-by=/etc/apt/keyrings/opentofu.gpg,/etc/apt/keyrings/opentofu-repo.gpg] https://packages.opentofu.org/opentofu/tofu/any/ any main - deb-src [signed-by=/etc/apt/keyrings/opentofu.gpg,/etc/apt/keyrings/opentofu-repo.gpg] https://packages.opentofu.org/opentofu/tofu/any/ any main" | \ - sudo tee /etc/apt/sources.list.d/opentofu.list > /dev/null - sudo chmod a+r /etc/apt/sources.list.d/opentofu.list - - sudo apt-get update - sudo apt-get install -y tofu - tofu version - ``` -- The Ansible template exists: `debian-13-cloud-init` (VMID 9001 by default). - -### Provider Auth -Create a `terraform.tfvars` (copy from `terraform.tfvars.example`) and set: -- `proxmox_api_url` (e.g. `https://nodito:8006/api2/json`) -- `proxmox_api_token_id` (e.g. `root@pam!tofu`) -- `proxmox_api_token_secret` -- `ssh_authorized_keys` (your public key content) - -Alternatively, you can export env vars and reference them in a tfvars file. - -### Declare VMs -Edit `terraform.tfvars` and fill the `vms` map. Example entry: -``` -vms = { - web1 = { - name = "web1" - cores = 2 - memory_mb = 2048 - disk_size_gb = 20 - ipconfig0 = "ip=dhcp" # or "ip=192.168.1.50/24,gw=192.168.1.1" - } -} -``` - -All VM disks are created on `zfs_storage_name` (defaults to `proxmox-tank-1`). Network attaches to `vmbr0`. VLAN can be set per-VM with `vlan_tag`. - -### Usage -``` -tofu init -tofu plan -var-file=terraform.tfvars -tofu apply -var-file=terraform.tfvars -``` - -### Notes -- Clones are full clones by default (`full_clone = true`). -- Cloud-init injects `cloud_init_user` and `ssh_authorized_keys`. -- Disks use `scsi0` on ZFS with `discard` enabled. - - diff --git a/tofu/nodito/main.tf b/tofu/nodito/main.tf deleted file mode 100644 index cc7a75d..0000000 --- a/tofu/nodito/main.tf +++ /dev/null @@ -1,70 +0,0 @@ -locals { - default_ipconfig0 = "ip=dhcp" -} - -resource "proxmox_vm_qemu" "vm" { - for_each = var.vms - - name = each.value.name - target_node = var.proxmox_node - vmid = try(each.value.vmid, null) - - onboot = true - agent = 1 - clone = var.template_name - full_clone = true - vga { - type = "serial0" - } - - cpu { - sockets = 1 - cores = each.value.cores - type = "host" - } - memory = each.value.memory_mb - - scsihw = "virtio-scsi-pci" - boot = "c" - bootdisk = "scsi0" - - serial { - id = 0 - type = "socket" - } - - # Network: bridge vmbr0, optional VLAN tag - network { - id = 0 - model = "virtio" - bridge = "vmbr0" - tag = try(each.value.vlan_tag, 0) - } - - # Cloud-init: user, ssh keys, IP, and custom snippet for qemu-guest-agent - # Note: Using vendor-data snippet (instead of user-data) allows Proxmox to automatically - # set the hostname from the VM name. User info is set separately via ciuser/sshkeys. - # Using 'local' storage for snippets (not ZFS) as ZFS storage doesn't properly support snippet paths - ciuser = var.cloud_init_user - sshkeys = var.ssh_authorized_keys - ipconfig0 = try(each.value.ipconfig0, local.default_ipconfig0) - cicustom = "vendor=local:snippets/user-data-qemu-agent.yaml" - - # Disk on ZFS storage - disk { - slot = "scsi0" - type = "disk" - storage = var.zfs_storage_name - size = "${each.value.disk_size_gb}G" - # optional flags like iothread/ssd/discard differ by provider versions; keep minimal - } - - # Cloud-init CD-ROM so ipconfig0/sshkeys apply - disk { - slot = "ide2" - type = "cloudinit" - storage = var.zfs_storage_name - } -} - - diff --git a/tofu/nodito/provider.tf b/tofu/nodito/provider.tf deleted file mode 100644 index f907fb9..0000000 --- a/tofu/nodito/provider.tf +++ /dev/null @@ -1,8 +0,0 @@ -provider "proxmox" { - pm_api_url = var.proxmox_api_url - pm_api_token_id = var.proxmox_api_token_id - pm_api_token_secret = var.proxmox_api_token_secret - pm_tls_insecure = true -} - - diff --git a/tofu/nodito/terraform.tfvars.example b/tofu/nodito/terraform.tfvars.example deleted file mode 100644 index cc88b3f..0000000 --- a/tofu/nodito/terraform.tfvars.example +++ /dev/null @@ -1,35 +0,0 @@ -proxmox_api_url = "https://nodito:8006/api2/json" -proxmox_api_token_id = "root@pam!tofu" -proxmox_api_token_secret = "REPLACE_ME" - -proxmox_node = "nodito" -zfs_storage_name = "proxmox-tank-1" -template_name = "debian-13-cloud-init" -cloud_init_user = "counterweight" - -# paste your ~/.ssh/id_ed25519.pub or similar -ssh_authorized_keys = <