Files
homelab-optimized/docs/advanced/TERRAFORM_IMPLEMENTATION_GUIDE.md
Gitea Mirror Bot fb4cb4fc23
Some checks failed
Documentation / Build Docusaurus (push) Failing after 5m0s
Documentation / Deploy to GitHub Pages (push) Has been skipped
Sanitized mirror from private repository - 2026-03-21 11:39:16 UTC
2026-03-21 11:39:16 +00:00

675 lines
15 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Terraform Implementation Guide for Homelab
## 🎯 Overview
This guide provides a comprehensive approach to implementing Terraform for your homelab infrastructure, focusing on practical benefits and gradual adoption.
## 🤔 Should You Use Terraform?
### Decision Matrix
| Factor | Your Current Setup | With Terraform | Recommendation |
|--------|-------------------|----------------|----------------|
| **VM Management** | Manual via Proxmox UI | Automated, version-controlled | ✅ **High Value** |
| **Network Config** | Manual VLAN/firewall setup | Declarative networking | ✅ **High Value** |
| **Storage Provisioning** | Manual NFS/iSCSI setup | Automated storage allocation | ✅ **Medium Value** |
| **Service Deployment** | Docker Compose (working well) | Limited benefit | ❌ **Low Value** |
| **Backup Management** | Scripts + manual verification | Infrastructure-level backups | ✅ **Medium Value** |
### **Recommendation: Hybrid Approach**
- **Use Terraform for**: Infrastructure (VMs, networks, storage)
- **Keep current approach for**: Services (Docker Compose + Ansible)
## 🏗️ Implementation Strategy
### Phase 1: Foundation Setup (Week 1)
#### 1.1 Directory Structure
```
terraform/
├── modules/
│ ├── proxmox-vm/
│ │ ├── main.tf
│ │ ├── variables.tf
│ │ ├── outputs.tf
│ │ └── README.md
│ ├── synology-storage/
│ │ ├── main.tf
│ │ ├── variables.tf
│ │ └── outputs.tf
│ └── networking/
│ ├── vlans.tf
│ ├── firewall.tf
│ └── dns.tf
├── environments/
│ ├── production/
│ │ ├── main.tf
│ │ ├── terraform.tfvars
│ │ ├── backend.tf
│ │ └── versions.tf
│ └── staging/
│ ├── main.tf
│ ├── terraform.tfvars
│ └── backend.tf
├── scripts/
│ ├── init-terraform.sh
│ ├── plan-and-apply.sh
│ └── destroy-environment.sh
└── docs/
├── GETTING_STARTED.md
├── MODULES.md
└── TROUBLESHOOTING.md
```
#### 1.2 Provider Configuration
```hcl
# terraform/environments/production/versions.tf
terraform {
required_version = ">= 1.0"
required_providers {
proxmox = {
source = "telmate/proxmox"
version = "~> 2.9"
}
cloudflare = {
source = "cloudflare/cloudflare"
version = "~> 4.0"
}
}
backend "local" {
path = "terraform.tfstate"
}
}
provider "proxmox" {
pm_api_url = var.proxmox_api_url
pm_user = var.proxmox_user
pm_password = "REDACTED_PASSWORD"
pm_tls_insecure = true
}
provider "cloudflare" {
api_token = var.cloudflare_api_token
}
```
### Phase 2: VM Module Development (Week 2)
#### 2.1 Proxmox VM Module
```hcl
# terraform/modules/proxmox-vm/main.tf
resource "proxmox_vm_qemu" "vm" {
name = var.vm_name
target_node = var.proxmox_node
vmid = var.vm_id
# VM Configuration
cores = var.cpu_cores
memory = var.memory_mb
sockets = var.cpu_sockets
# Boot Configuration
boot = "order=scsi0"
scsihw = "virtio-scsi-pci"
# Disk Configuration
disk {
slot = 0
size = var.disk_size
type = "scsi"
storage = var.storage_pool
iothread = 1
ssd = var.disk_ssd
}
# Network Configuration
network {
model = "virtio"
bridge = var.network_bridge
tag = var.vlan_tag
}
# Cloud-init Configuration
os_type = "cloud-init"
ipconfig0 = "ip=${var.ip_address}/${var.subnet_mask},gw=${var.gateway}"
# SSH Configuration
sshkeys = var.ssh_public_keys
# Lifecycle Management
lifecycle {
ignore_changes = [
network,
disk,
]
}
tags = var.tags
}
```
#### 2.2 VM Module Variables
```hcl
# terraform/modules/proxmox-vm/variables.tf
variable "vm_name" {
description = "Name of the virtual machine"
type = string
}
variable "proxmox_node" {
description = "Proxmox node to deploy VM on"
type = string
default = "proxmox"
}
variable "vm_id" {
description = "VM ID (must be unique)"
type = number
}
variable "cpu_cores" {
description = "Number of CPU cores"
type = number
default = 2
}
variable "memory_mb" {
description = "Memory in MB"
type = number
default = 2048
}
variable "disk_size" {
description = "Disk size (e.g., '20G')"
type = string
default = "20G"
}
variable "storage_pool" {
description = "Storage pool name"
type = string
default = "local-lvm"
}
variable "network_bridge" {
description = "Network bridge"
type = string
default = "vmbr0"
}
variable "vlan_tag" {
description = "VLAN tag"
type = number
default = null
}
variable "ip_address" {
description = "Static IP address"
type = string
}
variable "subnet_mask" {
description = "Subnet mask (CIDR notation)"
type = string
default = "24"
}
variable "gateway" {
description = "Gateway IP address"
type = string
}
variable "ssh_public_keys" {
description = "SSH public keys for access"
type = string
}
variable "tags" {
description = "Tags for the VM"
type = string
default = ""
}
variable "disk_ssd" {
description = "Whether disk is SSD"
type = bool
default = true
}
variable "cpu_sockets" {
description = "Number of CPU sockets"
type = number
default = 1
}
```
### Phase 3: Environment Configuration (Week 3)
#### 3.1 Production Environment
```hcl
# terraform/environments/production/main.tf
module "atlantis_vm" {
source = "../../modules/proxmox-vm"
vm_name = "atlantis"
vm_id = 100
proxmox_node = "proxmox-node1"
cpu_cores = 4
memory_mb = 8192
disk_size = "100G"
ip_address = "192.168.1.10"
gateway = "192.168.1.1"
network_bridge = "vmbr0"
vlan_tag = 10
ssh_public_keys = file("~/.ssh/id_rsa.pub")
tags = "homelab,synology,production"
}
module "calypso_vm" {
source = "../../modules/proxmox-vm"
vm_name = "calypso"
vm_id = 101
proxmox_node = "proxmox-node1"
cpu_cores = 6
memory_mb = 16384
disk_size = "200G"
ip_address = "192.168.1.11"
gateway = "192.168.1.1"
network_bridge = "vmbr0"
vlan_tag = 10
ssh_public_keys = file("~/.ssh/id_rsa.pub")
tags = "homelab,synology,production"
}
module "homelab_vm" {
source = "../../modules/proxmox-vm"
vm_name = "homelab-vm"
vm_id = 102
proxmox_node = "proxmox-node2"
cpu_cores = 2
memory_mb = 4096
disk_size = "50G"
ip_address = "192.168.1.12"
gateway = "192.168.1.1"
network_bridge = "vmbr0"
vlan_tag = 20
ssh_public_keys = file("~/.ssh/id_rsa.pub")
tags = "homelab,vm,production"
}
```
#### 3.2 Environment Variables
```hcl
# terraform/environments/production/terraform.tfvars
proxmox_api_url = "https://proxmox.local:8006/api2/json"
proxmox_user = "terraform@pve"
proxmox_password = "REDACTED_PASSWORD"
cloudflare_api_token = REDACTED_TOKEN
# Network Configuration
default_gateway = "192.168.1.1"
dns_servers = ["1.1.1.1", "8.8.8.8"]
# Storage Configuration
default_storage_pool = "local-lvm"
backup_storage_pool = "backup-storage"
# SSH Configuration
ssh_public_key_path = "~/.ssh/id_rsa.pub"
```
### Phase 4: Advanced Features (Week 4)
#### 4.1 Network Module
```hcl
# terraform/modules/networking/vlans.tf
resource "proxmox_vm_qemu" "pfsense" {
count = var.deploy_pfsense ? 1 : 0
name = "pfsense-firewall"
target_node = var.proxmox_node
vmid = 50
cores = 2
memory = 2048
disk {
slot = 0
size = "20G"
type = "scsi"
storage = var.storage_pool
}
# WAN Interface
network {
model = "virtio"
bridge = "vmbr0"
}
# LAN Interface
network {
model = "virtio"
bridge = "vmbr1"
}
# DMZ Interface
network {
model = "virtio"
bridge = "vmbr2"
}
tags = "firewall,network,security"
}
```
#### 4.2 Storage Module
```hcl
# terraform/modules/synology-storage/main.tf
resource "proxmox_lvm_thinpool" "storage" {
count = length(var.storage_pools)
name = var.storage_pools[count.index].name
vgname = var.storage_pools[count.index].vg_name
size = var.storage_pools[count.index].size
node = var.proxmox_node
}
# NFS Storage Configuration
resource "proxmox_storage" "nfs" {
count = length(var.nfs_shares)
storage_id = var.nfs_shares[count.index].id
type = "nfs"
server = var.nfs_shares[count.index].server
export = var.nfs_shares[count.index].export
content = var.nfs_shares[count.index].content
nodes = var.nfs_shares[count.index].nodes
}
```
## 🚀 Deployment Scripts
### Initialization Script
```bash
#!/bin/bash
# terraform/scripts/init-terraform.sh
set -e
ENVIRONMENT=${1:-production}
TERRAFORM_DIR="terraform/environments/$ENVIRONMENT"
echo "🚀 Initializing Terraform for $ENVIRONMENT environment..."
cd "$TERRAFORM_DIR"
# Initialize Terraform
terraform init
# Validate configuration
terraform validate
# Format code
terraform fmt -recursive
echo "✅ Terraform initialized successfully!"
echo "Next steps:"
echo " 1. Review terraform.tfvars"
echo " 2. Run: terraform plan"
echo " 3. Run: terraform apply"
```
### Plan and Apply Script
```bash
#!/bin/bash
# terraform/scripts/plan-and-apply.sh
set -e
ENVIRONMENT=${1:-production}
TERRAFORM_DIR="terraform/environments/$ENVIRONMENT"
AUTO_APPROVE=${2:-false}
echo "🔍 Planning Terraform deployment for $ENVIRONMENT..."
cd "$TERRAFORM_DIR"
# Create plan
terraform plan -out=tfplan
echo "📋 Plan created. Review the changes above."
if [ "$AUTO_APPROVE" = "true" ]; then
echo "🚀 Auto-applying changes..."
terraform apply tfplan
else
echo "Apply changes? (y/N)"
read -r response
if [[ "$response" =~ ^[Yy]$ ]]; then
terraform apply tfplan
else
echo "❌ Deployment cancelled"
exit 1
fi
fi
# Clean up plan file
rm -f tfplan
echo "✅ Deployment complete!"
```
## 🔧 Integration with Existing Workflow
### Ansible Integration
```yaml
# ansible/homelab/terraform-integration.yml
---
- name: Deploy Infrastructure with Terraform
hosts: localhost
tasks:
- name: Initialize Terraform
shell: |
cd terraform/environments/production
terraform init
- name: Plan Terraform Changes
shell: |
cd terraform/environments/production
terraform plan -out=tfplan
register: terraform_plan
- name: Apply Terraform Changes
shell: |
cd terraform/environments/production
terraform apply tfplan
when: terraform_plan.rc == 0
- name: Wait for VMs to be Ready
wait_for:
host: "{{ item }}"
port: 22
timeout: 300
loop:
- "192.168.1.10" # Atlantis
- "192.168.1.11" # Calypso
- "192.168.1.12" # Homelab VM
```
### CI/CD Integration
```yaml
# .github/workflows/terraform.yml
name: Terraform Infrastructure
on:
push:
branches: [main]
paths: ['terraform/**']
pull_request:
branches: [main]
paths: ['terraform/**']
jobs:
terraform:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Terraform
uses: hashicorp/setup-terraform@v2
with:
terraform_version: 1.5.0
- name: Terraform Init
run: |
cd terraform/environments/production
terraform init
- name: Terraform Validate
run: |
cd terraform/environments/production
terraform validate
- name: Terraform Plan
run: |
cd terraform/environments/production
terraform plan
- name: Terraform Apply
if: github.ref == 'refs/heads/main'
run: |
cd terraform/environments/production
terraform apply -auto-approve
```
## 📊 Benefits Analysis
### Quantified Benefits
| Aspect | Before Terraform | With Terraform | Time Saved |
|--------|------------------|----------------|------------|
| **VM Deployment** | 30 min manual setup | 5 min automated | 25 min/VM |
| **Network Changes** | 45 min manual config | 10 min code change | 35 min/change |
| **Disaster Recovery** | 4+ hours manual rebuild | 1 hour automated | 3+ hours |
| **Environment Consistency** | Manual verification | Guaranteed identical | 2+ hours/audit |
| **Documentation** | Separate docs (often stale) | Self-documenting code | 1+ hour/update |
### ROI Calculation
```
Annual Time Savings:
- VM deployments: 10 VMs × 25 min = 250 min
- Network changes: 20 changes × 35 min = 700 min
- DR testing: 4 tests × 180 min = 720 min
- Documentation: 12 updates × 60 min = 720 min
Total: 2,390 minutes = 39.8 hours annually
At $50/hour value: $1,990 annual savings
Implementation cost: ~40 hours = $2,000
Break-even: 1 year
```
## ⚠️ Risks and Mitigation
### Risk 1: State File Corruption
**Mitigation:**
- Implement remote state backend (S3 + DynamoDB)
- Regular state file backups
- State locking to prevent concurrent modifications
### Risk 2: Accidental Resource Deletion
**Mitigation:**
- Use `prevent_destroy` lifecycle rules
- Implement approval workflows for destructive changes
- Regular backups before major changes
### Risk 3: Learning Curve
**Mitigation:**
- Start with simple VM deployments
- Gradual adoption over 4-6 weeks
- Comprehensive documentation and examples
## 🎯 Success Metrics
### Key Performance Indicators
- **Deployment Time**: < 10 minutes for new VM
- **Configuration Drift**: Zero manual changes
- **Recovery Time**: < 2 hours for complete rebuild
- **Error Rate**: < 5% failed deployments
### Monitoring and Alerting
```bash
# Add to monitoring stack
terraform_deployment_success_rate
terraform_plan_execution_time
terraform_state_file_size
infrastructure_drift_detection
```
## 📚 Learning Resources
### Essential Reading
1. [Terraform Proxmox Provider Documentation](https://registry.terraform.io/providers/Telmate/proxmox/latest/docs)
2. [Terraform Best Practices](https://www.terraform-best-practices.com/)
3. [Infrastructure as Code Patterns](https://infrastructure-as-code.com/)
### Hands-on Labs
1. Deploy single VM with Terraform
2. Create reusable VM module
3. Implement multi-environment setup
4. Add networking and storage modules
### Community Resources
- [r/Terraform](https://reddit.com/r/Terraform)
- [Terraform Discord](https://discord.gg/terraform)
- [HashiCorp Learn](https://learn.hashicorp.com/terraform)
## 🔄 Migration Strategy
### Week 1: Preparation
- [ ] Install Terraform and providers
- [ ] Create basic directory structure
- [ ] Document current infrastructure
### Week 2: First VM
- [ ] Create simple VM module
- [ ] Deploy test VM with Terraform
- [ ] Validate functionality
### Week 3: Production VMs
- [ ] Import existing VMs to Terraform state
- [ ] Create production environment
- [ ] Test disaster recovery
### Week 4: Advanced Features
- [ ] Add networking module
- [ ] Implement storage management
- [ ] Create CI/CD pipeline
### Week 5-6: Optimization
- [ ] Refine modules and variables
- [ ] Add monitoring and alerting
- [ ] Create comprehensive documentation
---
**Next Steps:**
1. Review this guide with your team
2. Set up development environment
3. Start with Phase 1 implementation
4. Schedule weekly progress reviews