This commit adds several new features to enhance homelab management: ## New Services ### Backrest (backup.fig.systems) - Modern web UI for managing Restic backups - Encrypted, deduplicated backups to Backblaze B2 - Automated scheduling and retention policies - Pre-configured to backup Immich photos and homelab configs - SSO protected via tinyauth ### Homarr (home.fig.systems) - Auto-discovery dashboard for all homelab services - Docker socket integration for service monitoring - Clean, modern interface with customizable widgets - SSO protected via tinyauth ## Infrastructure ### Service Template System (templates/service-template/) - Complete template with all common patterns - Traefik labels, health checks, dependencies - Environment variable examples - Comprehensive README with usage instructions - Ensures consistency across all new services ### OpenTofu/Terraform IaC (terraform/) - Complete Proxmox VM provisioning setup - Cloud-init automation for Docker host creation - Automated Docker installation and configuration - Media directory structure creation - Step-by-step documentation including: - Cloud template creation guide - Variable configuration examples - Resource sizing recommendations - Security hardening options ## Documentation Updates - Updated README with new service URLs - Added Homarr and Backrest to directory structure - Updated deployment instructions - Added service table entries for new services All new services follow established patterns: - External homelab network - Let's Encrypt SSL via Traefik - Dual domain support (fig.systems + edfig.dev) - Consistent naming and structure |
||
|---|---|---|
| .. | ||
| proxmox-examples/docker-host | ||
| README.md | ||
OpenTofu Infrastructure as Code for Proxmox
This directory contains OpenTofu (Terraform) configurations for managing Proxmox infrastructure.
What is OpenTofu?
OpenTofu is an open-source fork of Terraform, providing Infrastructure as Code (IaC) capabilities. It allows you to:
- 📝 Define infrastructure as code - Version control your infrastructure
- 🔄 Automate provisioning - Create VMs/containers with one command
- 🎯 Consistency - Same config = same result every time
- 🔍 Plan changes - Preview changes before applying
- 🗑️ Easy cleanup - Destroy infrastructure when done
Why OpenTofu over Terraform?
- ✅ Truly Open Source - MPL 2.0 license (vs. Terraform's BSL)
- ✅ Community Driven - Not controlled by single company
- ✅ Terraform Compatible - Drop-in replacement
- ✅ Active Development - Regular updates and features
Quick Start
1. Install OpenTofu
Linux/macOS:
# Install via package manager
curl --proto '=https' --tlsv1.2 -fsSL https://get.opentofu.org/install-opentofu.sh | sh
# Or via Homebrew (macOS/Linux)
brew install opentofu
Verify installation:
tofu version
2. Configure Proxmox API
Create API Token in Proxmox:
- Login to Proxmox web UI
- Datacenter → Permissions → API Tokens
- Add new token:
- User:
root@pam - Token ID:
terraform - Privilege Separation: Unchecked (for full access)
- User:
- Save the token ID and secret!
Set environment variables:
export PM_API_URL="https://proxmox.local:8006/api2/json"
export PM_API_TOKEN_ID="root@pam!terraform"
export PM_API_TOKEN_SECRET="your-secret-here"
# Verify SSL (optional, set to false for self-signed certs)
export PM_TLS_INSECURE=true
3. Choose Your Use Case
We provide examples for common scenarios:
| Example | Description | Best For |
|---|---|---|
| single-vm | Simple Ubuntu VM | Learning, testing |
| docker-host | VM for Docker containers | Production homelab |
| lxc-containers | Lightweight LXC containers | Resource efficiency |
| multi-node | Multiple VMs/services | Complex deployments |
| cloud-init | Cloud-init automation | Production VMs |
Directory Structure
terraform/
├── README.md # This file
├── proxmox-examples/
│ ├── single-vm/ # Simple VM example
│ │ ├── main.tf
│ │ ├── variables.tf
│ │ └── terraform.tfvars
│ ├── docker-host/ # Docker host VM
│ ├── lxc-containers/ # LXC container examples
│ ├── multi-node/ # Multiple VM deployment
│ └── cloud-init/ # Cloud-init examples
└── modules/ # Reusable modules (future)
Basic Workflow
Initialize
cd proxmox-examples/single-vm
tofu init
Plan
tofu plan
Preview changes before applying.
Apply
tofu apply
Review plan and type yes to proceed.
Destroy
tofu destroy
Removes all managed resources.
Common Commands
# Initialize and download providers
tofu init
# Validate configuration syntax
tofu validate
# Format code to standard style
tofu fmt
# Preview changes
tofu plan
# Apply changes
tofu apply
# Apply without confirmation (careful!)
tofu apply -auto-approve
# Show current state
tofu show
# List all resources
tofu state list
# Destroy specific resource
tofu destroy -target=proxmox_vm_qemu.vm
# Destroy everything
tofu destroy
Provider Configuration
Proxmox Provider
terraform {
required_providers {
proxmox = {
source = "bpg/proxmox"
version = "~> 0.50"
}
}
}
provider "proxmox" {
endpoint = var.pm_api_url
api_token = "${var.pm_token_id}!${var.pm_token_secret}"
insecure = true # For self-signed certs
ssh {
agent = true
}
}
Best Practices
1. Use Variables
Don't hardcode values:
# Bad
target_node = "pve"
# Good
target_node = var.proxmox_node
2. Use terraform.tfvars
Store configuration separately:
# terraform.tfvars
proxmox_node = "pve"
vm_name = "docker-host"
vm_cores = 4
vm_memory = 8192
3. Version Control
Commit:
- ✅
*.tffiles - ✅
*.tfvars(if no secrets) - ✅
.terraform.lock.hcl
DO NOT commit:
- ❌
terraform.tfstate - ❌
terraform.tfstate.backup - ❌
.terraform/directory - ❌ Secrets/passwords
Use .gitignore:
.terraform/
*.tfstate
*.tfstate.backup
*.tfvars # If contains secrets
4. Use Modules
For reusable components:
module "docker_vm" {
source = "./modules/docker-host"
vm_name = "docker-01"
cores = 4
memory = 8192
}
5. State Management
Local State (default):
- Simple, single-user
- State in
terraform.tfstate
Remote State (recommended for teams):
terraform {
backend "s3" {
bucket = "my-terraform-state"
key = "proxmox/terraform.tfstate"
region = "us-east-1"
}
}
Example Use Cases
Homelab Docker Host
Provision a VM optimized for Docker:
- 4-8 CPU cores
- 8-16GB RAM
- 50GB+ disk
- Ubuntu Server 24.04
- Docker pre-installed via cloud-init
See: proxmox-examples/docker-host/
Development Environment
Multiple VMs for testing:
- Web server VM
- Database VM
- Application VM
- All networked together
See: proxmox-examples/multi-node/
LXC Containers
Lightweight containers for services:
- Lower overhead than VMs
- Fast startup
- Resource efficient
See: proxmox-examples/lxc-containers/
Proxmox Provider Resources
Virtual Machines (QEMU)
resource "proxmox_vm_qemu" "vm" {
name = "my-vm"
target_node = "pve"
clone = "ubuntu-cloud-template" # Template to clone
cores = 2
memory = 2048
disk {
size = "20G"
storage = "local-lvm"
}
network {
model = "virtio"
bridge = "vmbr0"
}
}
LXC Containers
resource "proxmox_lxc" "container" {
hostname = "my-container"
target_node = "pve"
ostemplate = "local:vztmpl/ubuntu-22.04-standard_22.04-1_amd64.tar.gz"
cores = 1
memory = 512
rootfs {
storage = "local-lvm"
size = "8G"
}
network {
name = "eth0"
bridge = "vmbr0"
ip = "dhcp"
}
}
Cloud-Init
resource "proxmox_vm_qemu" "cloudinit_vm" {
# ... basic config ...
ciuser = "ubuntu"
cipassword = var.vm_password
sshkeys = file("~/.ssh/id_rsa.pub")
ipconfig0 = "ip=dhcp"
}
Troubleshooting
SSL Certificate Errors
export PM_TLS_INSECURE=true
Or add to provider:
provider "proxmox" {
insecure = true
}
API Permission Errors
Ensure API token has necessary permissions:
# In Proxmox shell
pveum acl modify / -token 'root@pam!terraform' -role Administrator
VM Clone Errors
Ensure template exists:
# List VMs
qm list
# Check template flag
qm config 9000
Timeout Errors
Increase timeout:
resource "proxmox_vm_qemu" "vm" {
# ...
timeout_create = "30m"
timeout_clone = "30m"
}
Migration from Terraform
OpenTofu is a drop-in replacement:
# Rename binary
alias tofu=terraform
# Or replace commands
terraform → tofu
State files are compatible - no conversion needed!
Advanced Topics
Custom Cloud Images
- Download cloud image
- Create VM template
- Use cloud-init for customization
See: proxmox-examples/cloud-init/
Network Configuration
# VLAN tagging
network {
model = "virtio"
bridge = "vmbr0"
tag = 100 # VLAN 100
}
# Multiple NICs
network {
model = "virtio"
bridge = "vmbr0"
}
network {
model = "virtio"
bridge = "vmbr1"
}
Storage Options
# Local LVM
disk {
storage = "local-lvm"
size = "50G"
type = "scsi"
}
# NFS/CIFS
disk {
storage = "nfs-storage"
size = "100G"
}
# Multiple disks
disk {
slot = 0
size = "50G"
storage = "local-lvm"
}
disk {
slot = 1
size = "100G"
storage = "data"
}
Recommended Resources
Providers
- bpg/proxmox - Most feature-complete (recommended)
- Telmate/proxmox - Legacy, still works
Learning
Tools
- tflint - Linting
- terraform-docs - Generate docs
- infracost - Cost estimation
- terragrunt - Wrapper for DRY configs
Next Steps
- Start Simple: Try
proxmox-examples/single-vm/ - Learn Basics: Get familiar with plan/apply/destroy
- Expand: Try docker-host or multi-node
- Customize: Adapt examples to your needs
- Automate: Integrate with CI/CD
Getting Help
- Check example READMEs in each directory
- Review Proxmox provider docs
- OpenTofu community Discord
- Ask in r/Proxmox or r/selfhosted
Happy Infrastructure as Code! 🚀