proxmox: add VM automation with OpenTofu and Ansible

Add automated workflow for building and deploying NixOS VMs on Proxmox including template2 host configuration, Ansible playbook for image building/deployment, and OpenTofu configuration for VM provisioning with cloud-init.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-31 21:54:08 +01:00
parent 7f72a72043
commit 3a464bc323
14 changed files with 519 additions and 0 deletions

37
terraform/README.md Normal file
View File

@@ -0,0 +1,37 @@
# OpenTofu Configuration for Proxmox
This directory contains OpenTofu configuration for managing Proxmox VMs.
## 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
```
## Files
- `main.tf` - Provider configuration and test data source
- `variables.tf` - Variable definitions
- `terraform.tfvars.example` - Example credentials file
- `terraform.tfvars` - Your actual credentials (gitignored)

18
terraform/main.tf Normal file
View File

@@ -0,0 +1,18 @@
terraform {
required_version = ">= 1.0"
required_providers {
proxmox = {
source = "telmate/proxmox"
version = "3.0.2-rc07"
}
}
}
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 = var.proxmox_tls_insecure
}
# Provider configured - ready to add resources

View File

@@ -0,0 +1,7 @@
# Copy this file to terraform.tfvars and fill in your values
# terraform.tfvars is gitignored to keep credentials safe
proxmox_api_url = "https://your-proxmox-host.home.2rjus.net:8006/api2/json"
proxmox_api_token_id = "root@pam!terraform"
proxmox_api_token_secret = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
proxmox_tls_insecure = true

22
terraform/variables.tf Normal file
View File

@@ -0,0 +1,22 @@
variable "proxmox_api_url" {
description = "Proxmox API URL (e.g., https://proxmox.home.2rjus.net:8006/api2/json)"
type = string
}
variable "proxmox_api_token_id" {
description = "Proxmox API Token ID (e.g., root@pam!terraform)"
type = string
sensitive = true
}
variable "proxmox_api_token_secret" {
description = "Proxmox API Token Secret"
type = string
sensitive = true
}
variable "proxmox_tls_insecure" {
description = "Skip TLS verification (set to true for self-signed certs)"
type = bool
default = true
}

90
terraform/vm.tf Normal file
View File

@@ -0,0 +1,90 @@
# Example VM configuration - clone from template
# Before using this, you need to:
# 1. Upload the NixOS image to Proxmox
# 2. Restore it as a template VM (e.g., ID 9000)
# 3. Update the variables below
variable "target_node" {
description = "Proxmox node to deploy to"
type = string
default = "pve1"
}
variable "template_name" {
description = "Template VM name to clone from"
type = string
default = "nixos-25.11.20260128.fa83fd8"
}
variable "ssh_public_key" {
description = "SSH public key for root user"
type = string
default = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAwfb2jpKrBnCw28aevnH8HbE5YbcMXpdaVv2KmueDu6 torjus@gunter"
}
# Example test VM
resource "proxmox_vm_qemu" "test_vm" {
name = "nixos-test-tofu"
target_node = var.target_node
# Clone from template
clone = var.template_name
# Full clone (not linked)
full_clone = true
# Boot configuration
boot = "order=virtio0"
scsihw = "virtio-scsi-single"
# VM settings
cpu {
cores = 2
}
memory = 2048
# Network
network {
id = 0
model = "virtio"
bridge = "vmbr0"
tag = 13
}
# Disk settings
disks {
virtio {
virtio0 {
disk {
size = "20G"
storage = "local-zfs"
}
}
}
}
# Start on boot
start_at_node_boot = true
# Agent
agent = 1
# Cloud-init configuration
ciuser = "root"
sshkeys = var.ssh_public_key
ipconfig0 = "ip=dhcp"
nameserver = "10.69.13.5 10.69.13.6"
searchdomain = "home.2rjus.net"
# Skip IPv6 since we don't use it
skip_ipv6 = true
rng {
source = "/dev/urandom"
period = 1000
}
}
output "test_vm_ip" {
value = proxmox_vm_qemu.test_vm.default_ipv4_address
}