Initial commit

This commit is contained in:
Zhongwei Li
2025-11-29 18:00:27 +08:00
commit 0c6988a884
19 changed files with 5729 additions and 0 deletions

View File

@@ -0,0 +1,245 @@
# Basic VM Deployment Example
**Learning objective:** Deploy your first VM using the unified VM module with minimal configuration.
## What This Example Shows
- ✅ Minimal required configuration for VM deployment
- ✅ Cloning from an existing template
- ✅ Static IP address configuration with cloud-init
- ✅ SSH key injection
- ✅ Module defaults (what you DON'T need to specify)
## Prerequisites
1. **Proxmox template** exists (VMID 9000)
- Create one using: `terraform/netbox-template/` or Ansible playbook
- Or use Triangulum-Prime template examples
2. **Proxmox API credentials** configured:
```bash
export PROXMOX_VE_ENDPOINT="https://192.168.3.5:8006"
export PROXMOX_VE_API_TOKEN="user@realm!token-id=secret"
# OR
export PROXMOX_VE_USERNAME="root@pam"
export PROXMOX_VE_PASSWORD="your-password"
```
3. **SSH public key** available:
```bash
export TF_VAR_ssh_public_key="$(cat ~/.ssh/id_rsa.pub)"
```
## Quick Start
### 1. Initialize Terraform
```bash
tofu init
```
### 2. Review the Plan
```bash
tofu plan
```
**Expected resources:**
- 1 VM (cloned from template 9000)
- Cloud-init configuration
- Network interface with static IP
### 3. Deploy
```bash
tofu apply
```
### 4. Verify
```bash
# SSH into the VM
ssh ansible@192.168.3.100
# Check VM in Proxmox
qm status 100 # Or whatever VMID was assigned
```
### 5. Cleanup
```bash
tofu destroy
```
## Understanding the Configuration
### What You MUST Specify
```hcl
# These 6 parameters are required:
vm_type = "clone" # Clone from template
pve_node = "foxtrot" # Which node
vm_name = "test-vm-01" # VM name
src_clone = { ... } # Template to clone
vm_disk = { ... } # Disk config
vm_net_ifaces = { ... } # Network config
vm_init = { ... } # Cloud-init config
vm_efi_disk = { ... } # EFI boot disk
```
### What Uses Defaults
The module provides sensible defaults for:
| Setting | Default | Why It's Good |
|---------|---------|---------------|
| CPU cores | 2 | Minimal baseline |
| Memory | 2048 MB (2GB) | Enough for most services |
| CPU type | `host` | Best performance |
| Guest agent | Enabled | Needed for IP detection |
| BIOS | `ovmf` (UEFI) | Modern, secure |
| Machine | `q35` | Modern chipset |
| Display | Standard VGA | Works everywhere |
| Serial console | Enabled | Troubleshooting |
| RNG device | Enabled | Entropy for crypto |
**See:** [Module DEFAULTS.md](https://github.com/basher83/Triangulum-Prime/blob/main/terraform-bgp-vm/DEFAULTS.md)
## Customization
### Change VM Resources
Override defaults in `main.tf`:
```hcl
module "basic_vm" {
# ... required params ...
# Override CPU
vm_cpu = {
cores = 4 # Increase to 4 cores
}
# Override memory
vm_mem = {
dedicated = 8192 # 8GB
}
}
```
### Use Different Template
Change the template ID:
```hcl
src_clone = {
datastore_id = "local-lvm"
tpl_id = 9001 # Different template
}
```
### Add VLAN Tagging
```hcl
vm_net_ifaces = {
net0 = {
bridge = "vmbr0"
vlan_id = 30 # Add VLAN tag
ipv4_addr = "192.168.3.100/24"
ipv4_gw = "192.168.3.1"
}
}
```
## Common Issues
### Issue: "Template 9000 not found"
**Solution:** Create a template first:
```bash
cd ../../.. # Back to repo root
cd terraform/netbox-template
tofu apply
```
### Issue: "IP address already in use"
**Solution:** Change `ip_address` variable:
```bash
tofu apply -var="ip_address=192.168.3.101"
```
### Issue: "Cannot connect to Proxmox API"
**Solution:** Check credentials:
```bash
echo $PROXMOX_VE_ENDPOINT
echo $PROXMOX_VE_API_TOKEN
```
### Issue: "EFI disk creation failed"
**Solution:** Ensure datastore has space:
```bash
# On Proxmox node
pvesm status
```
## Next Steps
### Learn More
1. **Production Configuration:** See `../02-production-vm/`
- Shows common overrides for production
- Resource sizing best practices
- Tagging and organization
2. **Template Creation:** See `../03-template-creation/`
- How to create templates from cloud images
- Template best practices
3. **Complete Examples:** Triangulum-Prime repository
- [Single VM](https://github.com/basher83/Triangulum-Prime/tree/main/examples/single-vm)
- [MicroK8s Cluster](https://github.com/basher83/Triangulum-Prime/tree/main/examples/microk8s-cluster)
- [Custom Cloud-init](https://github.com/basher83/Triangulum-Prime/tree/main/examples/template-with-custom-cloudinit)
### Integration Examples
- **NetBox + DNS:** See `.claude/skills/netbox-powerdns-integration/examples/01-vm-with-dns/`
- **Ansible Configuration:** See `.claude/skills/ansible-best-practices/examples/`
## Module Documentation
- **README:** [terraform-bgp-vm](https://github.com/basher83/Triangulum-Prime/tree/main/terraform-bgp-vm)
- **DEFAULTS:** [DEFAULTS.md](https://github.com/basher83/Triangulum-Prime/blob/main/terraform-bgp-vm/DEFAULTS.md)
- **Full API:** Module variables.tf
## Philosophy: DRY (Don't Repeat Yourself)
This example follows the module's DRY principle:
✅ **Good:** Only specify what differs from defaults
```hcl
vm_cpu = {
cores = 4 # Only override cores, use default type
}
```
❌ **Bad:** Repeating module defaults
```hcl
vm_cpu = {
cores = 4
type = "host" # This is already the default!
}
```
**Why?** Reduces maintenance burden and makes changes obvious.

View File

@@ -0,0 +1,138 @@
# =============================================================================
# Basic VM Deployment Example
# =============================================================================
# This is a minimal example for learning the VM module. It shows only the
# required parameters with sensible defaults for everything else.
#
# Use this as a starting point for understanding the module, then refer to
# Triangulum-Prime examples for production-ready configurations.
terraform {
required_version = ">= 1.0"
required_providers {
proxmox = {
source = "bpg/proxmox"
version = "~> 0.69"
}
}
}
# Provider configuration (credentials from environment)
provider "proxmox" {
endpoint = var.proxmox_endpoint
# Uses PROXMOX_VE_API_TOKEN or PROXMOX_VE_USERNAME/PASSWORD from environment
}
# =============================================================================
# Basic VM Module Usage
# =============================================================================
module "basic_vm" {
source = "github.com/basher83/Triangulum-Prime//terraform-bgp-vm?ref=vm/1.0.1"
# === REQUIRED: Basic Configuration ===
vm_type = "clone" # Clone from existing template
pve_node = var.proxmox_node # Which Proxmox node to deploy on
vm_name = var.vm_name # Name of the VM
# === REQUIRED: Clone Source ===
# Specify which template to clone from
src_clone = {
datastore_id = "local-lvm"
tpl_id = 9000 # Your template VMID
}
# === REQUIRED: Disk Configuration ===
# Define the VM's disk
vm_disk = {
scsi0 = {
datastore_id = "local-lvm"
size = 20 # GB
main_disk = true
# Note: file_format, iothread, ssd, discard use optimal defaults
}
}
# === REQUIRED: Network Configuration ===
# At minimum, configure one network interface
vm_net_ifaces = {
net0 = {
bridge = "vmbr0"
ipv4_addr = "${var.ip_address}/24"
ipv4_gw = var.gateway
# Note: model defaults to "virtio", vlan_id defaults to null
}
}
# === REQUIRED: Cloud-init Configuration ===
vm_init = {
datastore_id = "local-lvm"
user = {
name = var.username
keys = [var.ssh_public_key]
}
dns = {
domain = "spaceships.work"
servers = ["192.168.3.1"]
}
}
# === REQUIRED: EFI Disk (for UEFI boot) ===
vm_efi_disk = {
datastore_id = "local-lvm"
# file_format defaults to "raw"
# type defaults to "4m"
}
# === OPTIONAL OVERRIDES ===
# These are only shown here for educational purposes.
# The module already provides these defaults - you DON'T need to specify them!
# CPU (defaults to 2 cores, "host" type)
# vm_cpu = {
# cores = 2
# type = "host"
# }
# Memory (defaults to 2048 MB / 2GB)
# vm_mem = {
# dedicated = 2048
# }
# Guest agent (defaults to enabled)
# vm_agent = {
# enabled = true
# }
# VM start behavior (defaults: start on deploy, start on boot)
# vm_start = {
# on_deploy = true
# on_boot = true
# }
# === Learn More ===
# See module DEFAULTS.md for complete list of defaults:
# https://github.com/basher83/Triangulum-Prime/blob/main/terraform-bgp-vm/DEFAULTS.md
}
# =============================================================================
# Outputs
# =============================================================================
output "vm_id" {
description = "The ID of the created VM"
value = module.basic_vm.vm_id
}
output "vm_name" {
description = "The name of the created VM"
value = module.basic_vm.vm_name
}
output "vm_ipv4_addresses" {
description = "IPv4 addresses assigned to the VM"
value = module.basic_vm.ipv4_addresses
}

View File

@@ -0,0 +1,41 @@
variable "proxmox_endpoint" {
description = "Proxmox API endpoint (e.g., https://192.168.3.5:8006)"
type = string
default = "https://192.168.3.5:8006"
}
variable "proxmox_node" {
description = "Proxmox node to deploy on"
type = string
default = "foxtrot"
}
variable "vm_name" {
description = "Name of the VM"
type = string
default = "test-vm-01"
}
variable "ip_address" {
description = "Static IP address for the VM (without CIDR)"
type = string
default = "192.168.3.100"
}
variable "gateway" {
description = "Network gateway"
type = string
default = "192.168.3.1"
}
variable "username" {
description = "VM username for cloud-init"
type = string
default = "ansible"
}
variable "ssh_public_key" {
description = "SSH public key for VM access"
type = string
# Set via environment variable or tfvars file
}