4.5 KiB
Terraform LXC Deployment for Iron Legion — PRD
Status: Draft | Author: Artemis | Date: 2026-06-04
1. Objective
Deploy Proxmox LXC containers via Terraform using the bpg/proxmox provider, running inside a custom Docker container (lazy automator pattern). Support runtime parameterization for bulk LXC creation with auto-incrementing VMID, IPv4, and naming.
2. Architecture
2.1 Docker Image
Base: Custom Dockerfile extending hashicorp/terraform:latest
Provider: bpg/proxmox pre-installed via terraform init at build time
Pattern: Matches thelazyautomator's guide — local workspace mounted into container
FROM hashicorp/terraform:latest
# Pre-install bpg/proxmox provider cache
COPY providers.tf /tmp/providers.tf
RUN cd /tmp && terraform init -upgrade && rm -f providers.tf
WORKDIR /workspace
ENTRYPOINT ["terraform"]
2.2 Credential Model
Proxmox API token stored in .env / terraform.tfvars, referenced as variables:
variable "pm_api_url" {
default = "https://192.168.7.33:8006/api2/json"
}
variable "pm_api_token_id" {
default = "root@pam!terraform"
}
variable "pm_api_token_secret" {
default = "terraform"
}
Token to be created on MK33: pveum user token add root@pam terraform --comment "Terraform automation" --privsep 0
2.3 Runtime Parameterization
| Parameter | Example | Effect |
|---|---|---|
count |
4 |
Number of LXCs to create |
vmid_base |
5050 |
Starting VMID |
Auto-derived per LXC (index i from 0 to count-1):
- VMID:
vmid_base + i - Name:
lxc-${vmid} - IPv4:
192.168.${first2digits(vmid)}.${last2digits(vmid)}/18- Example: vmid 5050 →
192.168.50.50/18 - Example: vmid 5051 →
192.168.50.51/18
- Example: vmid 5050 →
2.4 LXC Configuration (Static)
- OS: Debian 13 (or Debian 12 if 13 unavailable)
- CPU: 1 vCPU, 2 cores
- RAM: 2048 MB
- Storage: 8GB rootfs on local disk (test), migrate to NFS after validation
- Network: Static IPv4 with gateway
192.168.0.1
2.5 User / SSH (Option A First)
Bake jarvis user + SSH key into LXC via initialization block:
initialization {
user_account {
username = "jarvis"
keys = [file("~/.ssh/artemis_key.pub")]
}
}
Fallback (B): If initialization fails after 3 attempts, set root password to ubuntu via root_password and let Ansible configure post-build.
3. Phase Breakdown
Phase 1 — Single LXC (Plan/Build/Destroy)
Goal: Prove the pipeline works end-to-end with one manual LXC.
Deliverables:
Dockerfilefor custom Terraform imagedocker-compose.ymlfor local executionmain.tf— single LXC resource with hardcoded VMIDproviders.tf— bpg/proxmox provider configvariables.tf— API credentials and defaultsrun.sh— wrapper script for plan/apply/destroy
Test:
./run.sh plan # Validate config
./run.sh apply # Build lxc-5050
./run.sh destroy # Clean up
Phase 2 — Modular + Bulk Creation
Goal: Add count, vmid_base, and auto-derived naming/IP.
Deliverables:
modules/lxc/— reusable LXC modulelocals.tf— VMID/IP/name calculation logicmain.tf— uses module withcount = var.lxc_count- Step-counter for sequential VMID assignment
Example execution:
TF_VAR_lxc_count=4 TF_VAR_vmid_base=5050 ./run.sh apply
# Creates: lxc-5050, lxc-5051, lxc-5052, lxc-5053
4. File Structure
~/docker/terraform-pve/
├── Dockerfile
├── docker-compose.yml
├── run.sh
├── terraform/
│ ├── providers.tf
│ ├── variables.tf
│ ├── main.tf
│ ├── locals.tf
│ └── modules/
│ └── lxc/
│ ├── main.tf
│ ├── variables.tf
│ └── outputs.tf
5. Open Questions
- Debian version: Is Debian 13 available on your PVE nodes as a template, or should we use Debian 12?
- Gateway IP: Confirm
192.168.0.1is the correct gateway for192.168.0.0/18subnet? - DNS servers: Use Technitium (
192.168.7.7) for LXC/etc/resolv.conf? - SSH key: Use
~/.ssh/artemis_key.pubfor jarvis user, or a dedicated terraform key?
6. Decision Points
| Decision | Option A | Option B |
|---|---|---|
| Debian template | 13 (if available) | 12 (fallback) |
| DNS | Technitium (192.168.7.7) | Router default (192.168.18.1) |
| SSH key | artemis_key.pub | New dedicated terraform key |
Awaiting Commander Bobby approval before Phase 1 build.