Implements Phase 1 of the OpenTofu deployment plan: - Replace single-VM configuration with locals-based for_each pattern - Support multiple VMs in single deployment - Automatic DHCP vs static IP detection - Configurable defaults with per-VM overrides - Dynamic outputs for VM IPs and specifications New files: - outputs.tf: Dynamic outputs for deployed VMs - vms.tf: VM definitions using locals.vms map Updated files: - variables.tf: Added default variables for VM configuration - README.md: Comprehensive documentation and examples Removed files: - vm.tf: Replaced by new vms.tf (archived as vm.tf.old, then removed) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
198 lines
4.1 KiB
Markdown
198 lines
4.1 KiB
Markdown
# 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
|
|
}
|
|
}
|
|
```
|
|
|
|
## 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"` |
|
|
| `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
|
|
- `outputs.tf` - Output definitions for deployed VMs
|
|
- `terraform.tfvars.example` - Example credentials file
|
|
- `terraform.tfvars` - Your actual credentials (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
|