diff --git a/.gitignore b/.gitignore index 0f30459..7e0f1fa 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,10 @@ .Trashes ehthumbs.db Thumbs.db -logs \ No newline at end of file +logs +# Terraform +terraform/.terraform/ +terraform/.terraform.lock.hcl +terraform/terraform.tfstate* +terraform/terraform.tfvars +terraform/*.backup diff --git a/INFRASTRUCTURE_AS_CODE_ARCHITECTURE.md b/INFRASTRUCTURE_AS_CODE_ARCHITECTURE.md new file mode 100644 index 0000000..4391500 --- /dev/null +++ b/INFRASTRUCTURE_AS_CODE_ARCHITECTURE.md @@ -0,0 +1,926 @@ +# ORION Infrastructure as Code (IaC) - Complete Stack + +**Version**: 2.0.0-iac +**Created**: 2025-01-22 +**Status**: Architecture Design + +--- + +## 🎯 Overview + +Complete Infrastructure-as-Code stack for ORION Dell R730, integrating industry-standard tools for declarative infrastructure management, automated configuration, IP address management, container orchestration, and programmable routing. + +### Technology Stack + +| Component | Technology | Purpose | +|-----------|-----------|---------| +| **Infrastructure Provisioning** | Terraform | Declarative VM/container deployment | +| **Configuration Management** | Ansible | Automated OS and application configuration | +| **IPAM/Documentation** | NetBox | IP address management and network documentation | +| **Container Orchestration** | Kubernetes (K3s) | Lightweight K8s for container workloads | +| **Programmable Routing** | GoBGP | API-driven BGP routing with Go | +| **Secret Management** | Vault (optional) | Secrets and credential management | +| **State Backend** | Consul/S3 | Terraform state management | + +--- + +## πŸ—οΈ Complete Architecture + +``` +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ CONTROL PLANE (Your Workstation) β”‚ +β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ +β”‚ β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ Terraform β”‚ β”‚ Ansible β”‚ β”‚ kubectl β”‚ β”‚ +β”‚ β”‚ (HCL) β”‚ β”‚ (Playbooks) β”‚ β”‚ (K8s) β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ β”‚ β”‚ + ↓ ↓ ↓ +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ Dell R730 - Proxmox VE Layer β”‚ +β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ +β”‚ β”‚ +β”‚ Terraform creates/manages VMs ──→ Ansible configures ──→ Apps run β”‚ +β”‚ β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ VM 500: NetBox (IPAM) β”‚ β”‚ +β”‚ β”‚ - PostgreSQL database β”‚ β”‚ +β”‚ β”‚ - Redis cache β”‚ β”‚ +β”‚ β”‚ - Web UI: 192.168.100.50:8000 β”‚ β”‚ +β”‚ β”‚ Purpose: IP address management, network documentation β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β”‚ β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ VM 200: Router (GoBGP + VyOS) β”‚ β”‚ +β”‚ β”‚ - GoBGP daemon (port 50051 - gRPC API) β”‚ β”‚ +β”‚ β”‚ - REST API for BGP control β”‚ β”‚ +β”‚ β”‚ - AS394955 ←→ AS6939 (Telus) β”‚ β”‚ +β”‚ β”‚ Purpose: Programmable BGP routing β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β”‚ β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ VMs 600-603: Kubernetes Cluster (K3s) β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ +β”‚ β”‚ β”‚ VM 600: K3s Master (Control Plane) β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ - 4 cores, 8GB RAM β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ - etcd, API server, scheduler, controller β”‚ β”‚ β”‚ +β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ +β”‚ β”‚ β”‚ VM 601-603: K3s Workers (3 nodes) β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ - 4 cores, 16GB RAM each β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ - Run containerized workloads β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ - CNI: Flannel or Cilium β”‚ β”‚ β”‚ +β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ Workloads on K8s: β”‚ β”‚ +β”‚ β”‚ - Backstage (Developer Portal) β”‚ β”‚ +β”‚ β”‚ - Vapor API (Swift middleware) β”‚ β”‚ +β”‚ β”‚ - Prometheus + Grafana (Monitoring) β”‚ β”‚ +β”‚ β”‚ - Additional microservices β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β”‚ β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ VM 100: macOS Sequoia (Development) β”‚ β”‚ +β”‚ β”‚ - Still deployed via Terraform β”‚ β”‚ +β”‚ β”‚ - Configured via Ansible (post-install scripts) β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β”‚ β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ VM 300: AI Agent (Monitoring) β”‚ β”‚ +β”‚ β”‚ - Monitors K8s cluster health β”‚ β”‚ +β”‚ β”‚ - Integrates with GoBGP API β”‚ β”‚ +β”‚ β”‚ - Manages NetBox updates β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β”‚ β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +``` + +--- + +## πŸ“¦ Component 1: Terraform + +### Purpose +Declarative infrastructure provisioning - define VMs, networks, and storage in code. + +### What Terraform Will Manage + +```hcl +# Infrastructure Components +- Proxmox VMs (all VMs defined as Terraform resources) +- Network bridges and VLANs +- Storage allocations +- VM snapshots and backups (scheduled) +- Cloud-init configurations +- DNS records (if using external DNS) +``` + +### Directory Structure + +``` +terraform/ +β”œβ”€β”€ main.tf # Main configuration +β”œβ”€β”€ variables.tf # Input variables +β”œβ”€β”€ outputs.tf # Output values +β”œβ”€β”€ terraform.tfvars # Variable values (gitignored) +β”œβ”€β”€ modules/ +β”‚ β”œβ”€β”€ proxmox-vm/ # Reusable VM module +β”‚ β”œβ”€β”€ k8s-cluster/ # K8s cluster module +β”‚ └── networking/ # Network configuration +β”œβ”€β”€ environments/ +β”‚ β”œβ”€β”€ dev/ # Development environment +β”‚ β”œβ”€β”€ staging/ # Staging environment +β”‚ └── production/ # Production environment +└── state/ + └── backend.tf # State backend configuration +``` + +### Example: VM Definition + +```hcl +module "netbox_vm" { + source = "./modules/proxmox-vm" + + vm_id = 500 + name = "ORION-NetBox" + cores = 4 + memory = 8192 + disk_size = 100 + bridge = "vmbr1" + ip_address = "192.168.100.50" + tags = ["ipam", "infrastructure"] +} +``` + +### Benefits +- βœ… **Reproducible** - Rebuild entire infrastructure from code +- βœ… **Version controlled** - Track infrastructure changes in Git +- βœ… **Idempotent** - Run multiple times safely +- βœ… **Plan before apply** - Preview changes before execution +- βœ… **State management** - Track resource state + +--- + +## πŸ”§ Component 2: Ansible + +### Purpose +Automated configuration management - configure VMs after they're created by Terraform. + +### What Ansible Will Manage + +```yaml +# Configuration Tasks +- Operating system updates and packages +- User accounts and SSH keys +- Application installation (GoBGP, NetBox, etc.) +- Service configuration files +- Firewall rules +- Monitoring agents +- Security hardening +``` + +### Directory Structure + +``` +ansible/ +β”œβ”€β”€ ansible.cfg # Ansible configuration +β”œβ”€β”€ inventory/ +β”‚ β”œβ”€β”€ hosts.yml # Static inventory +β”‚ └── proxmox.py # Dynamic inventory (from Proxmox) +β”œβ”€β”€ playbooks/ +β”‚ β”œβ”€β”€ site.yml # Master playbook +β”‚ β”œβ”€β”€ router.yml # Router VM configuration +β”‚ β”œβ”€β”€ k8s-cluster.yml # K8s cluster setup +β”‚ β”œβ”€β”€ netbox.yml # NetBox deployment +β”‚ └── monitoring.yml # Monitoring stack +β”œβ”€β”€ roles/ +β”‚ β”œβ”€β”€ common/ # Common configuration +β”‚ β”œβ”€β”€ gobgp/ # GoBGP installation +β”‚ β”œβ”€β”€ k3s-master/ # K3s control plane +β”‚ β”œβ”€β”€ k3s-worker/ # K3s worker node +β”‚ β”œβ”€β”€ netbox/ # NetBox setup +β”‚ └── security/ # Security hardening +β”œβ”€β”€ group_vars/ +β”‚ β”œβ”€β”€ all.yml # Variables for all hosts +β”‚ β”œβ”€β”€ routers.yml # Router-specific vars +β”‚ └── k8s.yml # K8s-specific vars +└── host_vars/ + └── router.yml # Per-host variables +``` + +### Example: GoBGP Installation Role + +```yaml +# roles/gobgp/tasks/main.yml +--- +- name: Install GoBGP + apt: + name: golang-go + state: present + +- name: Download GoBGP binary + get_url: + url: "https://github.com/osrg/gobgp/releases/download/v3.20.0/gobgp_3.20.0_linux_amd64.tar.gz" + dest: /tmp/gobgp.tar.gz + +- name: Extract GoBGP + unarchive: + src: /tmp/gobgp.tar.gz + dest: /usr/local/bin/ + remote_src: yes + +- name: Create GoBGP config directory + file: + path: /etc/gobgp + state: directory + +- name: Deploy GoBGP configuration + template: + src: gobgpd.conf.j2 + dest: /etc/gobgp/gobgpd.conf + notify: restart gobgp + +- name: Install GoBGP systemd service + template: + src: gobgpd.service.j2 + dest: /etc/systemd/system/gobgpd.service + notify: reload systemd +``` + +### Integration with Terraform + +```bash +# Terraform creates VMs, then triggers Ansible +terraform apply +terraform output -json > ansible/inventory/terraform.json +ansible-playbook -i ansible/inventory ansible/playbooks/site.yml +``` + +--- + +## πŸ—„οΈ Component 3: NetBox (IPAM) + +### Purpose +Centralized IP address management, network documentation, and source of truth for infrastructure. + +### Features + +- **IPAM**: IPv4 and IPv6 address management +- **DCIM**: Data center infrastructure management +- **Circuits**: ISP/provider circuit tracking +- **Secrets**: Encrypted credential storage +- **API**: RESTful API for automation +- **Plugins**: Extensible with custom plugins + +### VM Specifications + +```yaml +VM ID: 500 +Name: ORION-NetBox +OS: Ubuntu 24.04 LTS +CPU: 4 cores +RAM: 8GB +Disk: 100GB +Network: 192.168.100.50/24 (vmbr1) +Services: + - NetBox web UI (port 8000) + - PostgreSQL 16 + - Redis 7 + - nginx (reverse proxy) +``` + +### NetBox Data Model for ORION + +```python +# Sites +ORION-Datacenter (Home Lab) + +# Racks +Dell-R730-Rack + +# Devices +- Dell R730 (CQ5QBM2) + - Type: Server + - Role: Hypervisor + - NICs: 8x (eno1-eno6, enp3s0f0-1) + +# Virtual Machines (synced from Proxmox) +- ORION-Router (VM 200) +- ORION-AI-Agent (VM 300) +- ORION-Backstage (VM 400) +- ORION-VaporAPI (VM 401) +- ORION-NetBox (VM 500) +- ORION-K3s-Master (VM 600) +- ORION-K3s-Worker-1 (VM 601) +- ORION-K3s-Worker-2 (VM 602) +- ORION-K3s-Worker-3 (VM 603) + +# IP Addresses (both IPv4 and IPv6) +# Prefixes +- 192.168.100.0/24 (LAN) +- 192.168.200.0/24 (Guest) +- 2602:F674::/48 (IPv6 allocation) + - 2602:F674:1000::/64 (LAN) + - 2602:F674:2000::/64 (Guest) + +# Circuits +- Telus Fiber (10Gbps) + - BGP AS: 6939 + - IPv6 Peers: 3x +``` + +### Integration Points + +1. **Terraform** ↔ NetBox + - Terraform reads IP allocations from NetBox API + - Auto-assigns IPs based on NetBox IPAM + +2. **Ansible** ↔ NetBox + - Dynamic inventory from NetBox + - Pull configuration data (VLANs, IPs) + +3. **Proxmox** ↔ NetBox + - Sync VMs to NetBox automatically + - Track VM lifecycle + +--- + +## ☸️ Component 4: Kubernetes (K3s) + +### Purpose +Lightweight Kubernetes for container orchestration, replacing standalone VMs for certain workloads. + +### Why K3s? + +- **Lightweight**: 100MB binary vs 1GB+ for full K8s +- **Easy setup**: Single command installation +- **Low resource**: Runs on smaller VMs +- **Full K8s**: 100% Kubernetes API compatible +- **Built-in**: Traefik ingress, local storage + +### Cluster Topology + +``` +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ K3s Cluster - ORION β”‚ +β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ +β”‚ β”‚ +β”‚ Control Plane (VM 600) β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ - etcd (distributed key-value store) β”‚ β”‚ +β”‚ β”‚ - kube-apiserver β”‚ β”‚ +β”‚ β”‚ - kube-scheduler β”‚ β”‚ +β”‚ β”‚ - kube-controller-manager β”‚ β”‚ +β”‚ β”‚ - Traefik ingress controller β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β”‚ β”‚ +β”‚ Worker Nodes (VMs 601-603) β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ Worker 1 (601): General workloads β”‚ β”‚ +β”‚ β”‚ Worker 2 (602): Stateful apps (databases) β”‚ β”‚ +β”‚ β”‚ Worker 3 (603): Monitoring stack β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β”‚ β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +``` + +### What Runs on K8s + +**Instead of separate VMs, these run as Pods:** + +1. **Backstage** (formerly VM 400) + ```yaml + Deployment: backstage + Replicas: 2 (HA) + Resources: 2 CPU, 4GB RAM per pod + Service: LoadBalancer (192.168.100.40) + Storage: PVC 50GB + ``` + +2. **Vapor API** (formerly VM 401) + ```yaml + Deployment: vapor-api + Replicas: 3 (load balanced) + Resources: 1 CPU, 2GB RAM per pod + Service: ClusterIP (internal only) + ``` + +3. **Monitoring Stack** + ```yaml + - Prometheus (metrics) + - Grafana (visualization) + - AlertManager (alerting) + - Node exporters (DaemonSet on all nodes) + ``` + +4. **Additional Services** + ```yaml + - Redis (caching) + - PostgreSQL (database) + - RabbitMQ (message queue) + - MinIO (S3-compatible storage) + ``` + +### Storage + +**Longhorn** - Distributed block storage for K8s +- Replicated volumes across worker nodes +- Snapshots and backups +- Web UI for management + +### Networking + +**CNI**: Cilium (instead of Flannel) +- Better performance +- Network policies +- Service mesh capabilities +- Observability + +### Deployment via Terraform + Ansible + +```hcl +# Terraform creates K8s VMs +module "k8s_cluster" { + source = "./modules/k8s-cluster" + + master_count = 1 + worker_count = 3 + master_cpu = 4 + master_ram = 8192 + worker_cpu = 4 + worker_ram = 16384 +} +``` + +```yaml +# Ansible installs K3s +- hosts: k8s_masters + roles: + - k3s-master + +- hosts: k8s_workers + roles: + - k3s-worker +``` + +### Benefits + +- βœ… **Higher density**: More services per VM +- βœ… **Auto-scaling**: HPA (Horizontal Pod Autoscaler) +- βœ… **Self-healing**: Automatic pod restarts +- βœ… **Rolling updates**: Zero-downtime deployments +- βœ… **Resource efficiency**: Better CPU/RAM utilization + +--- + +## πŸ”€ Component 5: GoBGP (Programmable Routing) + +### Purpose +Replace BIRD2 with GoBGP for API-driven, programmable BGP routing. + +### Why GoBGP over BIRD2? + +| Feature | BIRD2 | GoBGP | +|---------|-------|-------| +| **API** | Limited | Full gRPC/REST API | +| **Language** | C | Go (easier to extend) | +| **Configuration** | Text files | API + config file | +| **Monitoring** | birdc CLI | Prometheus metrics built-in | +| **Automation** | Manual | Programmatic | +| **Libraries** | None | Go client library | + +### GoBGP Architecture + +``` +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ Router VM (200) - GoBGP Stack β”‚ +β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ +β”‚ β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ gobgpd (BGP Daemon) β”‚ β”‚ +β”‚ β”‚ - Port 179: BGP protocol β”‚ β”‚ +β”‚ β”‚ - Port 50051: gRPC API β”‚ β”‚ +β”‚ β”‚ - Port 8080: REST API (optional) β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β”‚ ↕ β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ GoBGP REST API Wrapper (Go service) β”‚ β”‚ +β”‚ β”‚ - Exposes REST endpoints for easy integration β”‚ β”‚ +β”‚ β”‚ - Integrates with Backstage/Vapor API β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β”‚ ↕ β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ GoBGP Exporter (Prometheus) β”‚ β”‚ +β”‚ β”‚ - Port 9100: Metrics endpoint β”‚ β”‚ +β”‚ β”‚ - BGP session state, route counts, etc. β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β”‚ β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + ↕ + β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” + β”‚ Telus AS6939 β”‚ + β”‚ BGP Peers (3x) β”‚ + β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +``` + +### GoBGP Configuration + +```toml +# /etc/gobgp/gobgpd.toml +[global.config] + as = 394955 + router-id = "100.64.0.1" + +# Telus Peer 1 (Primary) +[[neighbors]] + [neighbors.config] + neighbor-address = "2602:F674:0000::ffff" + peer-as = 6939 + description = "Telus Gateway 1 - Primary" + [neighbors.timers.config] + hold-time = 90 + keepalive-interval = 30 + [neighbors.afi-safis] + [[neighbors.afi-safis.list]] + afi-safi-name = "ipv6-unicast" + [neighbors.afi-safis.list.config] + enabled = true + +# Telus Peer 2 (Secondary) +[[neighbors]] + [neighbors.config] + neighbor-address = "2602:F674:0000::fffe" + peer-as = 6939 + description = "Telus Gateway 2 - Secondary" + [neighbors.afi-safis] + [[neighbors.afi-safis.list]] + afi-safi-name = "ipv6-unicast" + +# Telus Peer 3 (Tertiary) +[[neighbors]] + [neighbors.config] + neighbor-address = "2602:F674:0000::fffd" + peer-as = 6939 + description = "Telus Gateway 3 - Tertiary" + [neighbors.afi-safis] + [[neighbors.afi-safis.list]] + afi-safi-name = "ipv6-unicast" +``` + +### API Usage Examples + +**Add a route programmatically:** + +```go +package main + +import ( + "context" + api "github.com/osrg/gobgp/v3/api" + "google.golang.org/grpc" +) + +func main() { + conn, _ := grpc.Dial("192.168.100.1:50051", grpc.WithInsecure()) + defer conn.Close() + + client := api.NewGobgpApiClient(conn) + + // Announce a new prefix + nlri := &api.IPAddressPrefix{ + PrefixLen: 48, + Prefix: "2602:F674::", + } + + attrs := []*api.PathAttribute{ + api.NewOriginAttribute(0), + api.NewNextHopAttribute("::"), + api.NewAsPathAttribute([]uint32{394955}), + } + + path := &api.Path{ + Nlri: api.NewAnyFromMessage(nlri), + Pattrs: attrs, + } + + client.AddPath(context.Background(), &api.AddPathRequest{ + Path: path, + }) +} +``` + +**REST API (via wrapper):** + +```bash +# Get all neighbors +curl http://192.168.100.1:8080/v1/neighbors + +# Get specific neighbor +curl http://192.168.100.1:8080/v1/neighbors/2602:F674:0000::ffff + +# Add route +curl -X POST http://192.168.100.1:8080/v1/routes \ + -H "Content-Type: application/json" \ + -d '{ + "prefix": "2602:F674:5000::/64", + "nexthop": "2602:F674:1000::1" + }' +``` + +### Integration with AI Agent + +```python +# AI Agent monitors and adjusts BGP automatically +import requests + +class BGPController: + def __init__(self, gobgp_url="http://192.168.100.1:8080"): + self.base_url = gobgp_url + + def check_bgp_health(self): + """Check BGP session health""" + resp = requests.get(f"{self.base_url}/v1/neighbors") + neighbors = resp.json() + + for neighbor in neighbors: + if neighbor['state'] != 'established': + self.alert(f"BGP peer {neighbor['address']} is down!") + self.attempt_recovery(neighbor) + + def announce_prefix(self, prefix, nexthop): + """Programmatically announce a new prefix""" + requests.post(f"{self.base_url}/v1/routes", json={ + "prefix": prefix, + "nexthop": nexthop + }) + + def withdraw_prefix(self, prefix): + """Withdraw a prefix""" + requests.delete(f"{self.base_url}/v1/routes/{prefix}") +``` + +### Benefits + +- βœ… **API-driven**: Control BGP programmatically +- βœ… **Automation-friendly**: Easy integration with CI/CD +- βœ… **Metrics built-in**: Native Prometheus support +- βœ… **Modern codebase**: Active development, Go ecosystem +- βœ… **Flexible**: Add custom logic in Go + +--- + +## πŸ”„ Complete Workflow + +### Initial Deployment + +```bash +# 1. Define infrastructure in Terraform +cd terraform/ +terraform init +terraform plan +terraform apply + +# VMs created: +# - VM 200: Router (GoBGP) +# - VM 300: AI Agent +# - VM 500: NetBox +# - VM 600-603: K8s cluster (K3s) + +# 2. Configure VMs with Ansible +cd ../ansible/ +ansible-playbook -i inventory/hosts.yml playbooks/site.yml + +# Installs: +# - GoBGP on Router +# - NetBox on VM 500 +# - K3s on cluster VMs +# - Monitoring agents everywhere + +# 3. Deploy applications to K8s +cd ../k8s/ +kubectl apply -f backstage/ +kubectl apply -f vapor-api/ +kubectl apply -f monitoring/ + +# 4. Configure NetBox +# - Import IP allocations +# - Sync VMs from Proxmox +# - Document network topology + +# 5. Start BGP +# - GoBGP establishes sessions +# - Routes announced automatically +# - Monitoring begins +``` + +### Day-2 Operations + +**Add a new VM:** + +```bash +# 1. Define in Terraform +cat >> terraform/vms.tf << 'EOF' +module "new_app_vm" { + source = "./modules/proxmox-vm" + vm_id = 700 + name = "app-server" + # ... +} +EOF + +# 2. Apply +terraform apply + +# 3. Ansible configures automatically (if in inventory) +ansible-playbook -i inventory playbooks/app-server.yml + +# 4. NetBox updated automatically via API +``` + +**Deploy new app to K8s:** + +```bash +# 1. Create Kubernetes manifest +cat > k8s/myapp/deployment.yaml + +# 2. Apply +kubectl apply -f k8s/myapp/ + +# 3. Monitoring auto-discovers new pods +# 4. Logs aggregated automatically +``` + +**Modify BGP routing:** + +```bash +# Option 1: Via API +curl -X POST http://192.168.100.1:8080/v1/routes \ + -d '{"prefix": "2602:F674:9000::/64", "nexthop": "..."}' + +# Option 2: Via Terraform +# (if managing routes as code) +terraform apply + +# Option 3: Via AI Agent +# (automatic based on conditions) +``` + +--- + +## πŸ“Š Monitoring & Observability + +### Metrics Collection + +``` +Prometheus scrapes: +β”œβ”€ Node Exporter (all VMs) - System metrics +β”œβ”€ GoBGP Exporter (Router) - BGP metrics +β”œβ”€ K8s Metrics Server - Container metrics +β”œβ”€ NetBox - IPAM metrics +└─ Custom exporters - Application metrics +``` + +### Dashboards (Grafana) + +1. **Infrastructure Overview** + - All VMs health + - Resource utilization + - Network throughput + +2. **BGP Routing** + - Session states + - Route counts + - Peer health + - Prefix announcements + +3. **Kubernetes Cluster** + - Pod status + - Resource requests/limits + - Node health + - Deployment status + +4. **NetBox** + - IP utilization + - Prefix usage + - Device inventory + +### Alerting + +```yaml +# Prometheus Alert Rules +groups: + - name: infrastructure + rules: + - alert: BGPSessionDown + expr: gobgp_peer_state != 6 + for: 5m + + - alert: VMHighCPU + expr: node_cpu_usage > 90 + for: 10m + + - alert: K8sPodCrashLoop + expr: kube_pod_container_status_restarts_total > 5 + for: 5m +``` + +--- + +## πŸ” Security Considerations + +### Secrets Management + +**Option 1: Ansible Vault** +```bash +ansible-vault encrypt group_vars/all.yml +``` + +**Option 2: HashiCorp Vault** (recommended) +```hcl +# Terraform reads secrets from Vault +data "vault_generic_secret" "proxmox" { + path = "secret/proxmox" +} +``` + +### Access Control + +- **Terraform**: State encryption, remote backend +- **Ansible**: SSH key-based auth, vault for secrets +- **NetBox**: RBAC, API tokens +- **K8s**: RBAC, network policies, Pod security standards +- **GoBGP**: API authentication, mTLS + +--- + +## πŸ“š Documentation Standards + +All infrastructure is documented as code: + +``` +docs/ +β”œβ”€β”€ architecture/ +β”‚ └── decisions/ # ADRs (Architecture Decision Records) +β”œβ”€β”€ runbooks/ +β”‚ β”œβ”€β”€ deployment.md # How to deploy +β”‚ β”œβ”€β”€ disaster-recovery.md # DR procedures +β”‚ └── troubleshooting.md # Common issues +└── diagrams/ + β”œβ”€β”€ network-topology.png + └── k8s-architecture.png +``` + +--- + +## 🎯 Implementation Plan + +### Phase 1: Foundation (Week 1) +- [ ] Set up Terraform with Proxmox provider +- [ ] Create base VM modules +- [ ] Set up Ansible inventory and roles +- [ ] Deploy NetBox VM + +### Phase 2: Routing (Week 2) +- [ ] Replace BIRD2 with GoBGP +- [ ] Create GoBGP REST API wrapper +- [ ] Test BGP sessions +- [ ] Integrate with monitoring + +### Phase 3: Kubernetes (Week 3) +- [ ] Deploy K3s cluster (1 master, 3 workers) +- [ ] Set up Longhorn storage +- [ ] Install Cilium CNI +- [ ] Migrate Backstage to K8s +- [ ] Migrate Vapor API to K8s + +### Phase 4: Integration (Week 4) +- [ ] Terraform ↔ NetBox integration +- [ ] Ansible dynamic inventory from NetBox +- [ ] GoBGP API integration with AI Agent +- [ ] Complete monitoring stack +- [ ] Documentation and runbooks + +--- + +## πŸ“ˆ Expected Outcomes + +### Infrastructure Benefits + +| Metric | Before | After | +|--------|--------|-------| +| **Deployment time** | 4-6 hours (manual) | 15 minutes (automated) | +| **VM utilization** | 40% (dedicated VMs) | 75% (K8s pods) | +| **Reproducibility** | Manual docs | 100% code-defined | +| **MTTR** | 30+ minutes | <5 minutes (auto-healing) | +| **Configuration drift** | Common | Eliminated | +| **Documentation** | Out of date | Always current (code) | + +--- + +**Status**: Ready for implementation +**Next Steps**: Begin Phase 1 - Terraform foundation diff --git a/terraform/README.md b/terraform/README.md new file mode 100644 index 0000000..d7d1fbc --- /dev/null +++ b/terraform/README.md @@ -0,0 +1,222 @@ +# ORION Terraform Infrastructure + +Infrastructure as Code for the ORION Dell R730 Proxmox environment. + +## πŸš€ Quick Start + +### Prerequisites + +1. **Terraform** installed (>= 1.6.0) + ```bash + # Install Terraform + wget https://releases.hashicorp.com/terraform/1.7.0/terraform_1.7.0_linux_amd64.zip + unzip terraform_1.7.0_linux_amd64.zip + sudo mv terraform /usr/local/bin/ + ``` + +2. **Proxmox API Token** created + ```bash + # On Proxmox host, create API token: + pveum user add terraform@pam + pveum role add TerraformRole -privs "VM.Allocate VM.Clone VM.Config.CDROM VM.Config.CPU VM.Config.Cloudinit VM.Config.Disk VM.Config.HWType VM.Config.Memory VM.Config.Network VM.Config.Options VM.Monitor VM.Audit VM.PowerMgmt Datastore.AllocateSpace Datastore.Audit Pool.Allocate Sys.Audit Sys.Console Sys.Modify" + pveum aclmod / -user terraform@pam -role TerraformRole + pveum user token add terraform@pam terraform-token --privsep=0 + + # Save the token ID and secret that are displayed + ``` + +3. **Cloud-init template** in Proxmox + ```bash + # Create Ubuntu 24.04 cloud-init template + # (See detailed instructions in docs/proxmox-cloud-init-template.md) + ``` + +### Setup + +1. **Copy and configure variables:** + ```bash + cp terraform.tfvars.example terraform.tfvars + nano terraform.tfvars + + # Update: + # - proxmox_api_token_id + # - proxmox_api_token_secret + # - vm_ssh_keys + ``` + +2. **Initialize Terraform:** + ```bash + terraform init + ``` + +3. **Plan deployment:** + ```bash + terraform plan + ``` + +4. **Apply configuration:** + ```bash + terraform apply + ``` + +## πŸ“ Directory Structure + +``` +terraform/ +β”œβ”€β”€ providers.tf # Provider configuration +β”œβ”€β”€ variables.tf # Variable definitions +β”œβ”€β”€ main.tf # Main infrastructure (to be created) +β”œβ”€β”€ outputs.tf # Output values (to be created) +β”œβ”€β”€ terraform.tfvars.example # Example variables +β”œβ”€β”€ terraform.tfvars # Actual variables (gitignored) +β”œβ”€β”€ modules/ +β”‚ β”œβ”€β”€ proxmox-vm/ # Reusable VM module (to be created) +β”‚ β”œβ”€β”€ k8s-cluster/ # K8s cluster module (to be created) +β”‚ └── networking/ # Network module (to be created) +└── environments/ + β”œβ”€β”€ dev/ # Development environment + β”œβ”€β”€ staging/ # Staging environment + └── production/ # Production environment +``` + +## 🎯 What Gets Deployed + +When you run `terraform apply`, the following VMs will be created: + +### NetBox (VM 500) +- **Purpose**: IP Address Management and network documentation +- **Resources**: 4 cores, 8GB RAM, 100GB disk +- **IP**: 192.168.100.50 +- **Services**: NetBox web UI, PostgreSQL, Redis + +### Kubernetes Cluster (VMs 600-603) +- **Master** (VM 600): 4 cores, 8GB RAM +- **Workers** (VMs 601-603): 4 cores, 16GB RAM each +- **IP Range**: 192.168.100.60-63 + +## πŸ”§ Common Operations + +### Check Current State +```bash +terraform show +terraform state list +``` + +### View Planned Changes +```bash +terraform plan +``` + +### Apply Changes +```bash +terraform apply + +# Or auto-approve (skip confirmation) +terraform apply -auto-approve +``` + +### Destroy Infrastructure +```bash +# Destroy specific resource +terraform destroy -target=module.netbox_vm + +# Destroy everything +terraform destroy +``` + +### Update a Single VM +```bash +# Taint a resource to force recreation +terraform taint module.netbox_vm.proxmox_vm_qemu.vm +terraform apply +``` + +### Import Existing VM +```bash +# Import an existing VM into Terraform state +terraform import module.router_vm.proxmox_vm_qemu.vm orion-pve/qemu/200 +``` + +## πŸ“Š Outputs + +After applying, Terraform will output useful information: + +```bash +terraform output + +# Example outputs: +# netbox_ip = "192.168.100.50" +# netbox_url = "http://192.168.100.50:8000" +# k8s_master_ip = "192.168.100.60" +# k8s_worker_ips = ["192.168.100.61", "192.168.100.62", "192.168.100.63"] +``` + +## πŸ” Security + +- **Never commit** `terraform.tfvars` or `*.tfstate` files +- **Use API tokens** instead of passwords +- **Encrypt state** if using remote backend +- **Limit token permissions** to minimum required + +## πŸ› Troubleshooting + +### "Error acquiring the state lock" +```bash +# Force unlock (use with caution) +terraform force-unlock +``` + +### "Error creating VM: timeout while waiting" +```bash +# Increase timeout in provider configuration +# Or check Proxmox host resources +``` + +### "Template not found" +```bash +# Ensure cloud-init template exists: +qm list | grep template + +# Or create it (see docs) +``` + +### API Token Permission Denied +```bash +# Verify token permissions: +pveum user token permissions terraform@pam terraform-token +``` + +## πŸ”„ Integration with Ansible + +After Terraform creates VMs, use Ansible to configure them: + +```bash +# Generate Ansible inventory from Terraform outputs +terraform output -json > ../ansible/inventory/terraform.json + +# Run Ansible playbooks +cd ../ansible +ansible-playbook -i inventory/hosts.yml playbooks/site.yml +``` + +## πŸ“š Next Steps + +1. **Create main.tf** - Define your infrastructure +2. **Customize modules** - Tailor VM configurations +3. **Set up remote state** - Use S3 or Consul backend +4. **Integrate with CI/CD** - Automate deployments +5. **Add monitoring** - Track infrastructure changes + +## πŸ“– Documentation + +- [Terraform Proxmox Provider](https://registry.terraform.io/providers/Telmate/proxmox/latest/docs) +- [Main Architecture](../INFRASTRUCTURE_AS_CODE_ARCHITECTURE.md) +- [ORION Overview](../README.md) + +## ⚠️ Important Notes + +- Always run `terraform plan` before `apply` +- Review changes carefully before confirming +- Keep state files secure and backed up +- Test in dev environment first +- Document any manual changes outside Terraform diff --git a/terraform/providers.tf b/terraform/providers.tf new file mode 100644 index 0000000..c3c82a2 --- /dev/null +++ b/terraform/providers.tf @@ -0,0 +1,67 @@ +# Terraform Proxmox Provider Configuration +# ORION Infrastructure as Code + +terraform { + required_version = ">= 1.6.0" + + required_providers { + proxmox = { + source = "telmate/proxmox" + version = "~> 2.9.14" + } + } + + # Backend configuration for state management + # Uncomment and configure based on your needs + + # Option 1: Local backend (default) + # backend "local" { + # path = "terraform.tfstate" + # } + + # Option 2: S3-compatible backend (MinIO, AWS S3, etc.) + # backend "s3" { + # bucket = "orion-terraform-state" + # key = "infrastructure/terraform.tfstate" + # region = "us-east-1" + # endpoint = "https://minio.orion.local" + # skip_credentials_validation = true + # skip_metadata_api_check = true + # force_path_style = true + # } + + # Option 3: Consul backend + # backend "consul" { + # address = "192.168.100.1:8500" + # scheme = "http" + # path = "orion/terraform/state" + # } +} + +# Proxmox Provider +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 + + # Or use username/password (less secure) + # pm_user = var.proxmox_user + # pm_password = var.proxmox_password + + # TLS verification + pm_tls_insecure = var.proxmox_tls_insecure + + # Logging + pm_log_enable = true + pm_log_file = "terraform-plugin-proxmox.log" + pm_log_levels = { + _default = "debug" + _capturelog = "" + } + + # Timeout for API calls + pm_timeout = 600 + + # Parallel operations + pm_parallel = 2 +} diff --git a/terraform/terraform.tfvars.example b/terraform/terraform.tfvars.example new file mode 100644 index 0000000..d221f6f --- /dev/null +++ b/terraform/terraform.tfvars.example @@ -0,0 +1,84 @@ +# Terraform Variables - ORION Infrastructure +# Copy this file to terraform.tfvars and fill in your values +# DO NOT commit terraform.tfvars to git (it's in .gitignore) + +# ============================================================================= +# Proxmox Connection (REQUIRED) +# ============================================================================= + +# Method 1: API Token (Recommended - more secure) +proxmox_api_token_id = "terraform@pam!terraform-token" +proxmox_api_token_secret = "your-token-secret-here" + +# Method 2: Username/Password (Less secure - not recommended) +# proxmox_user = "root@pam" +# proxmox_password = "your-password-here" + +# Proxmox settings +proxmox_api_url = "https://192.168.100.10:8006/api2/json" +proxmox_node = "orion-pve" +proxmox_tls_insecure = true # Set to false if using valid SSL cert + +# ============================================================================= +# Network Configuration +# ============================================================================= + +network_gateway = "192.168.100.1" +network_dns = ["1.1.1.1", "8.8.8.8"] +network_domain = "orion.local" + +# ============================================================================= +# SSH Access +# ============================================================================= + +vm_ssh_keys = [ + "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC... user@workstation", + # Add more SSH public keys here +] + +# ============================================================================= +# Storage +# ============================================================================= + +vm_storage_pool = "local-lvm" +vm_iso_storage = "local" + +# ============================================================================= +# NetBox VM +# ============================================================================= + +enable_netbox = true + +netbox_vm_id = 500 +netbox_cores = 4 +netbox_memory = 8192 +netbox_disk_size = "100G" +netbox_ip_address = "192.168.100.50" + +# ============================================================================= +# Kubernetes Cluster +# ============================================================================= + +enable_k8s_cluster = true + +k8s_master_count = 1 +k8s_worker_count = 3 +k8s_master_cores = 4 +k8s_master_memory = 8192 +k8s_worker_cores = 4 +k8s_worker_memory = 16384 +k8s_disk_size = "100G" + +k8s_master_vm_id = 600 +k8s_worker_vm_id_start = 601 +k8s_ip_range_start = "192.168.100.60" + +# ============================================================================= +# General Settings +# ============================================================================= + +environment = "production" +auto_start = true +enable_monitoring = true + +tags = ["terraform", "orion", "iac"] diff --git a/terraform/variables.tf b/terraform/variables.tf new file mode 100644 index 0000000..c29d03c --- /dev/null +++ b/terraform/variables.tf @@ -0,0 +1,250 @@ +# Terraform Variables for ORION Infrastructure +# Define all input variables here + +# ============================================================================= +# Proxmox Connection +# ============================================================================= + +variable "proxmox_api_url" { + description = "Proxmox API URL" + type = string + default = "https://192.168.100.10:8006/api2/json" +} + +variable "proxmox_api_token_id" { + description = "Proxmox API token ID" + 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 (use for self-signed certs)" + type = bool + default = true +} + +variable "proxmox_node" { + description = "Proxmox node name" + type = string + default = "orion-pve" +} + +# ============================================================================= +# Network Configuration +# ============================================================================= + +variable "network_gateway" { + description = "Default gateway for VMs" + type = string + default = "192.168.100.1" +} + +variable "network_dns" { + description = "DNS servers for VMs" + type = list(string) + default = ["1.1.1.1", "8.8.8.8"] +} + +variable "network_domain" { + description = "DNS domain for VMs" + type = string + default = "orion.local" +} + +variable "network_vlan_id" { + description = "VLAN ID (0 = no VLAN)" + type = number + default = 0 +} + +# ============================================================================= +# VM Defaults +# ============================================================================= + +variable "vm_default_user" { + description = "Default username for cloud-init" + type = string + default = "ubuntu" +} + +variable "vm_ssh_keys" { + description = "SSH public keys for VM access" + type = list(string) + default = [] +} + +variable "vm_storage_pool" { + description = "Storage pool for VM disks" + type = string + default = "local-lvm" +} + +variable "vm_iso_storage" { + description = "Storage for ISO files" + type = string + default = "local" +} + +# ============================================================================= +# NetBox VM Configuration +# ============================================================================= + +variable "netbox_vm_id" { + description = "VM ID for NetBox" + type = number + default = 500 +} + +variable "netbox_cores" { + description = "CPU cores for NetBox VM" + type = number + default = 4 +} + +variable "netbox_memory" { + description = "Memory (MB) for NetBox VM" + type = number + default = 8192 +} + +variable "netbox_disk_size" { + description = "Disk size (GB) for NetBox VM" + type = string + default = "100G" +} + +variable "netbox_ip_address" { + description = "IP address for NetBox" + type = string + default = "192.168.100.50" +} + +variable "netbox_cidr" { + description = "CIDR notation for NetBox IP" + type = number + default = 24 +} + +# ============================================================================= +# K8s Cluster Configuration +# ============================================================================= + +variable "k8s_master_vm_id" { + description = "Starting VM ID for K8s master nodes" + type = number + default = 600 +} + +variable "k8s_worker_vm_id_start" { + description = "Starting VM ID for K8s worker nodes" + type = number + default = 601 +} + +variable "k8s_master_count" { + description = "Number of K8s master nodes" + type = number + default = 1 +} + +variable "k8s_worker_count" { + description = "Number of K8s worker nodes" + type = number + default = 3 +} + +variable "k8s_master_cores" { + description = "CPU cores for K8s master nodes" + type = number + default = 4 +} + +variable "k8s_master_memory" { + description = "Memory (MB) for K8s master nodes" + type = number + default = 8192 +} + +variable "k8s_worker_cores" { + description = "CPU cores for K8s worker nodes" + type = number + default = 4 +} + +variable "k8s_worker_memory" { + description = "Memory (MB) for K8s worker nodes" + type = number + default = 16384 +} + +variable "k8s_disk_size" { + description = "Disk size for K8s nodes" + type = string + default = "100G" +} + +variable "k8s_ip_range_start" { + description = "Starting IP for K8s cluster" + type = string + default = "192.168.100.60" +} + +# ============================================================================= +# Tags and Metadata +# ============================================================================= + +variable "tags" { + description = "Tags to apply to all resources" + type = list(string) + default = ["terraform", "orion", "iac"] +} + +variable "environment" { + description = "Environment name (dev, staging, production)" + type = string + default = "production" +} + +# ============================================================================= +# Cloud-init Template +# ============================================================================= + +variable "cloud_init_template" { + description = "Cloud-init template name (must exist in Proxmox)" + type = string + default = "ubuntu-2404-cloudinit-template" +} + +# ============================================================================= +# Feature Flags +# ============================================================================= + +variable "enable_netbox" { + description = "Deploy NetBox VM" + type = bool + default = true +} + +variable "enable_k8s_cluster" { + description = "Deploy K8s cluster" + type = bool + default = true +} + +variable "enable_monitoring" { + description = "Install monitoring agents on VMs" + type = bool + default = true +} + +variable "auto_start" { + description = "Auto-start VMs on Proxmox boot" + type = bool + default = true +}