# prx-iac Documentation

## Proxmox Infrastructure as Code

**Technical Documentation v1.0**

---

## Table of Contents

1. [Overview](#1-overview)
2. [Architecture](#2-architecture)
3. [Project Structure](#3-project-structure)
4. [Prerequisites](#4-prerequisites)
5. [Configuration](#5-configuration)
6. [Deployment Guide](#6-deployment-guide)
7. [Stack Reference](#7-stack-reference)
8. [Adding New Containers](#8-adding-new-containers)
9. [Jenkins Pipeline](#9-jenkins-pipeline)
10. [Troubleshooting](#10-troubleshooting)

---

## 1. Overview

**prx-iac** is a comprehensive automation framework for deploying and managing LXC containers across a Proxmox VE cluster.

### Key Features

- **Dynamic node assignment** via Jenkins parameters
- **Auto-generated VM IDs** based on stack patterns
- **Automatic template resolution** per Proxmox node
- **Stack-based organization** (media, monitoring, infra, home-automation)
- **Reusable Terraform modules**
- **Selective deployment** of individual containers or entire stacks

### Supported Stacks

| Stack | Base VMID | Containers |
|-------|-----------|------------|
| media | 12000 | sonarr, radarr, prowlarr, qbittorrent, bazarr, jellyfin, sabnzbd |
| monitoring | 15000 | grafana, influxdb, uptime_kuma |
| home-automation | 16000 | homeassistant |
| infra | 20000 | nextcloud, gitlab, passgen |

---

## 2. Architecture

### System Flow

```
Jenkins Pipeline (STACK, NODE, ROLES, ACTION)
                    │
                    ▼
              deploy.sh
                    │
    ┌───────────────┼───────────────┐
    │               │               │
    ▼               ▼               ▼
Terraform       Wait IPs        Ansible
(provision)   (inject SSH)    (configure)
                    │
                    ▼
           Proxmox Cluster
    ┌───────┬───────┬───────┐
    │  pve  │arthas │hellscream│
    └───────┴───────┴───────┘
```

### Deployment Sequence

1. User triggers Jenkins pipeline with parameters
2. Jenkins executes `deploy.sh`
3. Terraform provisions LXC containers
4. Script waits for containers to boot and get IPs
5. SSH keys are injected into containers
6. Dynamic Ansible inventory is generated
7. Ansible playbooks configure the containers

### Node Configuration

| Node | Template VMID | Description |
|------|---------------|-------------|
| pve | 9001 | Primary node |
| arthas | 9002 | Secondary node (default) |
| hellscream | 9003 | Tertiary node |

---

## 3. Project Structure

```
prx-iac/
├── Jenkinsfile                    # Main CI/CD pipeline
├── scripts/
│   ├── deploy.sh                  # Deployment orchestrator
│   └── destroy.sh                 # Cleanup script
├── terraform/
│   ├── modules/
│   │   └── container/             # Reusable LXC module
│   │       ├── main.tf
│   │       ├── variables.tf
│   │       └── outputs.tf
│   └── stacks/
│       ├── media-stack/
│       │   ├── main.tf
│       │   ├── variables.tf
│       │   ├── outputs.tf
│       │   └── roles.txt
│       ├── monitoring-stack/
│       ├── infra-stack/
│       └── home-automation-stack/
└── ansible/
    ├── ansible.cfg
    ├── playbooks/
    │   ├── media-stack.yml
    │   ├── monitoring-stack.yml
    │   ├── infra-stack.yml
    │   └── home-automation-stack.yml
    └── roles/
        ├── sonarr/
        ├── radarr/
        ├── prowlarr/
        ├── qbittorrent/
        ├── bazarr/
        ├── jellyfin/
        ├── sabnzbd/
        ├── grafana/
        └── ...
```

---

## 4. Prerequisites

### Infrastructure Requirements

- Proxmox VE 7.x or 8.x cluster
- LXC template on each node
- API token with appropriate permissions
- Network connectivity between Jenkins and Proxmox

### Software Requirements

| Software | Version | Purpose |
|----------|---------|---------|
| Terraform | >= 1.3.0 | Infrastructure provisioning |
| Ansible | >= 2.10 | Configuration management |
| Jenkins | >= 2.400 | CI/CD orchestration |
| bpg/proxmox | ~> 0.45.0 | Terraform Proxmox provider |

### Proxmox API Token Permissions

- `VM.Allocate`, `VM.Clone`, `VM.Config.*`, `VM.Audit`
- `Datastore.Allocate`, `Datastore.AllocateSpace`
- `Sys.Audit`, `Sys.Modify`

Token format: `user@pam!tokenid=secret-uuid-here`

---

## 5. Configuration

### Jenkins Credentials

| Credential ID | Type | Description |
|---------------|------|-------------|
| `proxmox-token` | Secret text | Proxmox API token |
| `ssh-key` | Secret text | SSH public key |
| `SSH_PRIVATE` | SSH Username with private key | SSH private key |

### Terraform Variables

| Variable | Default | Description |
|----------|---------|-------------|
| `proxmox_endpoint` | `https://192.168.0.100:8006/api2/json` | API URL |
| `proxmox_token` | (required) | API token |
| `target_node` | `arthas` | Deployment node |

### Environment Variables (for manual deployment)

```bash
export PROXMOX_TOKEN='user@pam!tokenid=secret'
export SSH_KEY='ssh-rsa AAAA... user@host'
export SSH_KEY_FILE='/path/to/private/key'
export SSH_USER='root'
```

---

## 6. Deployment Guide

### Manual Deployment

```bash
# Deploy entire stack
./scripts/deploy.sh media arthas

# Deploy specific containers
./scripts/deploy.sh media arthas sonarr,radarr

# Deploy to different node
./scripts/deploy.sh monitoring pve

# Destroy stack
./scripts/destroy.sh media arthas
```

### Jenkins Deployment

1. Navigate to Jenkins → prx-iac pipeline
2. Click **Build with Parameters**
3. Select:
   - **STACK**: media, monitoring, infra, home-automation
   - **NODE**: arthas, pve, hellscream
   - **ROLES**: container names or `all`
   - **ACTION**: deploy or destroy
4. Click **Build**

### Deployment Output

```
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
🚀 Deployment Summary
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
   Stack:      media
   Node:       arthas
   Containers: sonarr radarr prowlarr qbittorrent bazarr
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

📦 Initializing Terraform...
📋 Planning deployment...
🔨 Applying Terraform...
📊 Fetching container information...
   ✅ sonarr → VMID 12001
   ✅ radarr → VMID 12002
🌐 Waiting for containers to boot...
   🌐 sonarr → 192.168.0.50
   🔐 Injecting SSH key...
📝 Generating Ansible inventory...
🛠️  Running Ansible...

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✅ Deployment Complete!
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
```

---

## 7. Stack Reference

### Media Stack (Base VMID: 12000)

| Container | VMID | Cores | Memory | Port | Description |
|-----------|------|-------|--------|------|-------------|
| sonarr | 12001 | 2 | 2048 MB | 8989 | TV automation |
| radarr | 12002 | 2 | 2048 MB | 7878 | Movie automation |
| prowlarr | 12003 | 2 | 2048 MB | 9696 | Indexer manager |
| qbittorrent | 12004 | 2 | 2048 MB | 8080 | Torrent client |
| bazarr | 12005 | 2 | 1024 MB | 6767 | Subtitle automation |
| jellyfin | 12006 | 4 | 4096 MB | 8096 | Media server |
| sabnzbd | 12007 | 2 | 2048 MB | 7777 | Usenet client |

### Monitoring Stack (Base VMID: 15000)

| Container | VMID | Cores | Memory | Port | Description |
|-----------|------|-------|--------|------|-------------|
| grafana | 15001 | 2 | 1024 MB | 3000 | Visualization |
| influxdb | 15002 | 2 | 2048 MB | 8086 | Time series DB |
| uptime_kuma | 15003 | 1 | 512 MB | 3001 | Status monitoring |

### Infrastructure Stack (Base VMID: 20000)

| Container | VMID | Cores | Memory | Port | Description |
|-----------|------|-------|--------|------|-------------|
| nextcloud | 20001 | 2 | 2048 MB | 80 | File sync |
| gitlab | 20002 | 4 | 4096 MB | 80 | Git repository |
| passgen | 20003 | 1 | 512 MB | 80 | Password generator |

### Home Automation Stack (Base VMID: 16000)

| Container | VMID | Cores | Memory | Port | Description |
|-----------|------|-------|--------|------|-------------|
| homeassistant | 16001 | 2 | 2048 MB | 8123 | Smart home hub |

---

## 8. Adding New Containers

### Step 1: Edit Terraform main.tf

```hcl
# terraform/stacks/media-stack/main.tf
locals {
  containers = {
    sonarr   = { offset = 1, cores = 2, memory = 2048, description = "..." }
    # Add new container:
    jellyfin = { offset = 6, cores = 4, memory = 4096, description = "Jellyfin media server" }
  }
}
```

### Step 2: Add Terraform Output

```hcl
# terraform/stacks/media-stack/outputs.tf
output "jellyfin_vmid" {
  value = module.containers["jellyfin"].id
}
```

### Step 3: Update roles.txt

```
sonarr
radarr
prowlarr
qbittorrent
bazarr
jellyfin
```

### Step 4: Create Ansible Role

```bash
mkdir -p ansible/roles/jellyfin/{tasks,handlers}
```

Create `ansible/roles/jellyfin/tasks/main.yml`:
```yaml
---
- name: Install dependencies
  apt:
    name: [curl, gnupg]
    state: present
    update_cache: true

# ... installation steps ...

- name: Ensure service is running
  systemd:
    name: jellyfin
    enabled: true
    state: started
```

### Step 5: Update Playbook

```yaml
# ansible/playbooks/media-stack.yml
roles:
  - { role: jellyfin, tags: ['jellyfin'] }
```

### Step 6: Deploy

```bash
./scripts/deploy.sh media arthas jellyfin
```

---

## 9. Jenkins Pipeline

### Parameters

| Parameter | Type | Options | Description |
|-----------|------|---------|-------------|
| STACK | Choice | media, monitoring, infra, home-automation | Stack to deploy |
| NODE | Choice | arthas, pve, hellscream | Target node |
| ROLES | String | Default: `all` | Containers to deploy |
| ACTION | Choice | deploy, destroy | Action to perform |

### Pipeline Stages

1. **Validate Parameters** - Display summary
2. **Checkout** - Pull from Git
3. **Deploy** - Run deploy.sh
4. **Destroy** - Run destroy.sh

### Setting Up

1. Create new Pipeline job in Jenkins
2. Select "Pipeline script from SCM"
3. Set Repository URL
4. Set Script Path to `Jenkinsfile`
5. Save and run "Build with Parameters"

---

## 10. Troubleshooting

### Common Issues

**Terraform connection failed:**
```bash
# Test API connectivity
curl -k https://192.168.0.100:8006/api2/json/version
```

**Container no IP:**
```bash
# Check container status
ssh root@proxmox "pct status 12001"
ssh root@proxmox "pct exec 12001 -- ip a"
```

**Ansible connection failed:**
```bash
# Test SSH
ssh -i /path/to/key root@container_ip

# Test Ansible
ansible -i inventory.ini all -m ping
```

### Debug Commands

```bash
# Terraform
cd terraform/stacks/media-stack
terraform state list
terraform output

# Proxmox
ssh root@192.168.0.100 'pct list'

# Ansible
ansible-playbook -i inventory.ini playbooks/media-stack.yml -vvv
```

### Reset

```bash
# Destroy stack
./scripts/destroy.sh media arthas

# Clean Terraform state
cd terraform/stacks/media-stack
rm -rf .terraform terraform.tfstate*

# Clean inventory
rm -f inventory.ini
```

---

## Quick Reference

### Deploy Commands

```bash
./scripts/deploy.sh <stack> <node> [containers]
./scripts/destroy.sh <stack> <node> [containers]
```

### Stack → VMID

```
media:           12001-12099
monitoring:      15001-15099
home-automation: 16001-16099
infra:           20001-20099
```

### Node → Template

```
pve        → 9001
arthas     → 9002
hellscream → 9003
```

---

*End of Documentation*
