# OpenTofu Configuration for Proxmox This directory contains OpenTofu configuration for managing Proxmox VMs using a parameterized, multi-VM deployment system. ## Setup 1. **Create a Proxmox API token:** - Log into Proxmox web UI - Go to Datacenter → Permissions → API Tokens - Click Add - User: `root@pam`, Token ID: `terraform` - Uncheck "Privilege Separation" - Save the token secret (shown only once) 2. **Configure credentials:** ```bash cd terraform cp terraform.tfvars.example terraform.tfvars # Edit terraform.tfvars with your Proxmox details ``` 3. **Initialize OpenTofu:** ```bash tofu init ``` 4. **Test connection:** ```bash tofu plan ``` ## Defining VMs All VMs are defined in the `vms.tf` file in the `locals.vms` map. Each VM can specify custom configurations or use defaults from `variables.tf`. ### Example: DHCP VM ```hcl vms = { "simple-vm" = { cpu_cores = 2 memory = 2048 disk_size = "20G" # No "ip" field = DHCP } } ``` ### Example: Static IP VM ```hcl vms = { "web-server" = { ip = "10.69.13.50/24" cpu_cores = 4 memory = 4096 disk_size = "50G" } } ``` ### Example: Minimal VM (all defaults) ```hcl vms = { "test-vm" = {} } ``` ### Example: Multiple VMs ```hcl vms = { "vm1" = { ip = "10.69.13.50/24" } "vm2" = { ip = "10.69.13.51/24" cpu_cores = 4 memory = 8192 } "vm3" = { # DHCP cpu_cores = 2 memory = 2048 } } ``` ### Example: Test VM with Custom Git Branch For testing pipeline changes without polluting master: ```hcl vms = { "test-vm" = { ip = "10.69.13.100/24" flake_branch = "test-pipeline" # Bootstrap from this branch } } ``` This VM will bootstrap from the `test-pipeline` branch instead of `master`. Production VMs should omit the `flake_branch` field. ## Configuration Options Each VM in the `vms` map supports the following fields (all optional): | Field | Description | Default | |-------|-------------|---------| | `ip` | Static IP with CIDR (e.g., "10.69.13.50/24"). Omit for DHCP | DHCP | | `gateway` | Network gateway (used with static IP) | `10.69.13.1` | | `cpu_cores` | Number of CPU cores | `2` | | `memory` | Memory in MB | `2048` | | `disk_size` | Disk size (e.g., "20G", "100G") | `"20G"` | | `flake_branch` | Git branch for bootstrap (for testing, omit for production) | `master` | | `target_node` | Proxmox node to deploy to | `"pve1"` | | `template_name` | Template VM to clone from | `"nixos-25.11.20260128.fa83fd8"` | | `storage` | Storage backend | `"local-zfs"` | | `bridge` | Network bridge | `"vmbr0"` | | `vlan_tag` | VLAN tag | `13` | | `ssh_public_key` | SSH public key for root | See `variables.tf` | | `nameservers` | DNS servers | `"10.69.13.5 10.69.13.6"` | | `search_domain` | DNS search domain | `"home.2rjus.net"` | Defaults are defined in `variables.tf` and can be changed globally. ## Deployment Commands ### Deploy All VMs ```bash tofu apply ``` ### Deploy Specific VM ```bash tofu apply -target=proxmox_vm_qemu.vm[\"vm-name\"] ``` ### Destroy Specific VM ```bash tofu destroy -target=proxmox_vm_qemu.vm[\"vm-name\"] ``` ### View Deployed VMs ```bash tofu output vm_ips tofu output deployment_summary ``` ### Plan Changes ```bash tofu plan ``` ## Outputs After deployment, OpenTofu provides two outputs: **vm_ips**: IP addresses and SSH commands for each VM ``` vm_ips = { "vm1" = { ip = "10.69.13.50" ssh_command = "ssh root@10.69.13.50" } } ``` **deployment_summary**: Full specifications for each VM ``` deployment_summary = { "vm1" = { cpu_cores = 4 memory_mb = 4096 disk_size = "50G" ip = "10.69.13.50" node = "pve1" } } ``` ## Workflow 1. Edit `vms.tf` to define your VMs in the `locals.vms` map 2. Run `tofu plan` to preview changes 3. Run `tofu apply` to deploy 4. Run `tofu output vm_ips` to get IP addresses 5. SSH to VMs and configure as needed ## Files - `main.tf` - Provider configuration - `variables.tf` - Variable definitions and defaults - `vms.tf` - VM definitions and deployment logic - `cloud-init.tf` - Custom cloud-init configuration for branch-specific bootstrap - `outputs.tf` - Output definitions for deployed VMs - `terraform.tfvars.example` - Example credentials file - `terraform.tfvars` - Your actual credentials (gitignored) - `.generated/` - Auto-generated cloud-init files (gitignored) - `vm.tf.old` - Archived single-VM configuration (reference) ## Notes - VMs are deployed as full clones (not linked clones) - Cloud-init handles initial networking configuration - QEMU guest agent is enabled on all VMs - All VMs start on boot by default - IPv6 is disabled - Destroying VMs removes them from Proxmox but does not clean up DNS entries or NixOS configurations