infra/.planning/codebase/STRUCTURE.md
2026-02-23 20:54:27 +00:00

255 lines
11 KiB
Markdown
Raw Permalink 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.

# Codebase Structure
**Analysis Date:** 2026-02-23
## Directory Layout
```
/Users/viktorbarzin/code/infra/
├── .claude/ # Project-level Claude knowledge (skills, reference docs)
├── .git/ # Git repository metadata
├── .git-crypt/ # git-crypt encryption keys
├── .planning/codebase/ # GSD codebase analysis documents
├── .terraform/ # Terraform cache (gitignored)
├── .woodpecker/ # CI/CD pipeline definitions
├── cli/ # Custom CLI tools (bash/python scripts)
├── diagram/ # Infrastructure diagram sources
├── docs/ # Documentation (deployment guides, design docs)
├── modules/ # Shared Terraform modules (Proxmox, K8s utilities)
├── playbooks/ # Ansible playbooks (infrastructure setup)
├── scripts/ # Maintenance scripts (healthcheck, DNS updates, etc.)
├── secrets/ # git-crypt encrypted files (NFS dirs, TLS certs, SSH keys)
├── stacks/ # Terragrunt stacks (platform + ~70 service stacks)
├── state/ # Terraform state files (local backend, gitignored)
├── terragrunt.hcl # Root Terragrunt config (DRY provider/backend setup)
├── terraform.tfvars # All variables + secrets (git-crypt encrypted, ~48KB)
├── config # Kubernetes config (kubeconfig file)
├── README.md # Project overview
└── package.json # Node.js deps (minimal; mostly for cli tools)
```
## Directory Purposes
**`.claude/`:**
- Purpose: Project-level Claude knowledge and execution skills
- Contains: `skills/` (setup-project, authentik workflows), `reference/` (inventory tables, API patterns)
- Key files: `CLAUDE.md` (this file's counterpart with full infrastructure context)
**`.planning/codebase/`:**
- Purpose: GSD codebase analysis output directory
- Contains: `ARCHITECTURE.md`, `STRUCTURE.md` (this file), and focus-specific docs
- Auto-generated: Yes (by /gsd:map-codebase)
**`modules/`:**
- Purpose: Reusable Terraform modules for VM creation and Kubernetes utilities
- Contains:
- `create-template-vm/`: Cloud-init Ubuntu template VM provisioning (K8s + non-K8s)
- `create-vm/`: VM instance creation from templates with cloud-init injection
- `docker-registry/`: Docker registry pull-through cache setup
- `kubernetes/`: K8s-specific utilities (ingress_factory, setup_tls_secret)
**`stacks/`:**
- Purpose: Terragrunt stacks with isolated state and per-service configuration
- Contains: 1 platform stack + ~70 application stacks
- Structure: Each stack is a directory with `terragrunt.hcl` + `main.tf` + optional `factory/` (for multi-instance services)
**`stacks/platform/`:**
- Purpose: Core infrastructure services (22 modules)
- Contains: Modules for MetalLB, DBaaS, Redis, Traefik, DNS, VPN, auth, monitoring, security
- Key subdirs: `modules/` (platform-specific modules like traefik, authentik, monitoring)
**`stacks/infra/`:**
- Purpose: Proxmox VM template and instance provisioning
- Contains: K8s node templates, docker-registry VM, Proxmox provider configuration
**`stacks/<service>/`:**
- Purpose: Single application stack with isolated state
- Pattern: `terragrunt.hcl` (includes root, declares dependencies) + `main.tf` (resources) + optional `factory/` + optional `chart_values.yaml`
- Examples: `nextcloud/`, `immich/`, `matrix/`, `actualbudget/` (multi-tenant), etc.
**`secrets/`:**
- Purpose: git-crypt encrypted sensitive files
- Contains: TLS certificates/keys, NFS export list, SSH keys, Dkim keys, Postfix config
- Key files:
- `nfs_directories.txt`: List of NFS shares (sorted); regenerate exports with `nfs_exports.sh`
- `tls/`: TLS certificate chain and keys
- `mailserver/`: OpenDKIM keys, Postfix SASL creds
**`scripts/`:**
- Purpose: Operational and maintenance automation
- Key scripts:
- `cluster_healthcheck.sh`: 24-point cluster health status
- `renew2.sh`: TLS certificate renewal via certbot + Cloudflare
- `setup_certs.sh`: Initial certificate setup
- `pve_*`: Proxmox management scripts
- `ha_*`: Home Assistant integration scripts
**`docs/`:**
- Purpose: Design and deployment documentation
- Contains: High-level architecture diagrams, deployment guides, troubleshooting
**`cli/`:**
- Purpose: Custom CLI utilities
- Contains: Python/bash scripts for common operations (DNS management, NFS, etc.)
## Key File Locations
**Entry Points:**
- `terragrunt.hcl`: Root Terragrunt config; invoked by `terragrunt apply` in any stack directory
- `stacks/platform/main.tf`: Platform stack; applies 22 core modules
- `stacks/infra/main.tf`: Infrastructure stack; creates VM templates and docker-registry VM
**Configuration:**
- `terraform.tfvars`: Central variables file (~48KB, git-crypt encrypted). Used by all stacks. Contains: Cloudflare credentials, DNS records, service secrets, TLS secret name
- `stacks/<service>/terragrunt.hcl`: Stack-specific Terragrunt config (includes root, declares `dependency` blocks)
- `stacks/platform/modules/<service>/main.tf`: Platform module implementation (22 modules)
**Core Logic:**
- `stacks/platform/main.tf`: 1000+ lines; instantiates all 22 platform modules
- `stacks/<service>/main.tf`: 30450 lines; creates namespaces, Helm releases, Kubernetes resources
- `stacks/<service>/factory/main.tf`: Multi-instance service pattern; called multiple times with different parameters
- `modules/kubernetes/ingress_factory/main.tf`: Traefik ingress + service template with security defaults
**Testing & Validation:**
- `.woodpecker/`: CI/CD pipeline (pushes platform apply on merge)
- `scripts/cluster_healthcheck.sh`: Manual cluster health validation
**Kubernetes & Cluster Config:**
- `config`: Kubeconfig file for cluster access
- Namespace pattern: One namespace per service stack
- TLS secret: `tls-secret` injected into all namespaces via `setup_tls_secret` module
## Naming Conventions
**Files:**
- `main.tf`: Primary Terraform resource file per stack
- `terragrunt.hcl`: Terragrunt-specific configuration (includes root, dependencies)
- `terraform.tfvars`: Global variables (git-crypt encrypted)
- `chart_values.yaml`: Helm chart values template (uses templatefile for variable substitution)
- `*_values.tpl`: Helm values template (evaluated with templatefile)
- `.terraform.lock.hcl`: Provider lock file (one per stack)
**Directories:**
- `stacks/<service>/`: Kebab-case service names (e.g., `real-estate-crawler`, `k8s-dashboard`)
- `stacks/platform/modules/<service>/`: Kebab-case module names
- `state/stacks/<service>/`: Mirrored state directory structure
- `secrets/`: Single top-level directory for all encrypted files
- `modules/kubernetes/`, `modules/create-template-vm/`: Category-based grouping
**Terraform Resources:**
- **Kubernetes**: `kubernetes_*` (namespace, deployment, service, configmap, etc.)
- **Helm**: `helm_release` (Helm chart deployments)
- **Local files**: `local_file` (for generated scripts and configs)
- **Module calls**: `module "<short-name>"` (e.g., `module "traefik"`, `module "redis"`)
**Variables:**
- Snake_case: `tls_secret_name`, `crowdsec_api_key`, `nextcloud_db_password`
- Service-prefixed: `<service>_<attribute>` (e.g., `authentik_secret_key`, `mailserver_accounts`)
## Where to Add New Code
**New Service Stack:**
1. Create `stacks/<service>/` directory
2. Add `terragrunt.hcl`:
```hcl
include "root" {
path = find_in_parent_folders()
}
dependency "platform" {
config_path = "../platform"
skip_outputs = true
}
```
3. Create `main.tf` with:
- Variable declarations for required inputs from `terraform.tfvars`
- `locals { tiers = { ... } }` (copy from existing stack)
- `kubernetes_namespace` resource with tier label
- `module "tls_secret"` call to `../../modules/kubernetes/setup_tls_secret`
- Service-specific resources (Helm releases, Deployments, etc.)
4. Add Cloudflare DNS records in `terraform.tfvars` if needed
5. Create optional `secrets/` symlink: `ln -s ../../secrets secrets`
6. Apply: `cd stacks/<service> && terragrunt apply --non-interactive`
**Multi-Tenant Service (using Factory Pattern):**
1. Create parent stack: `stacks/<service>/main.tf` with namespace + TLS setup
2. Create `stacks/<service>/factory/main.tf` with single-instance logic
3. In parent, call factory multiple times:
```hcl
module "instance1" {
source = "./factory"
name = "instance1"
# ... other params
}
```
4. Example: `stacks/actualbudget/` has factory instantiated for viktor, anca, emo
**New Platform Module:**
1. Create `stacks/platform/modules/<service>/` directory
2. Add `main.tf` with resources (Helm chart, namespace, ConfigMaps, etc.)
3. Add `variables.tf` or declare variables in `main.tf`
4. In `stacks/platform/main.tf`, add module call:
```hcl
module "<service>" {
source = "./modules/<service>"
tier = local.tiers.<tier>
# ... pass required variables
}
```
5. Add variable declarations in `stacks/platform/main.tf`
**New Shared Module:**
1. Create `modules/kubernetes/<module_name>/` or `modules/terraform/<module_name>/`
2. Add `main.tf` with reusable resources
3. Declare clear variable inputs and output any useful values
4. Call from service stacks: `module "<name>" { source = "../../modules/kubernetes/<module_name>" ... }`
**Utilities & Scripts:**
- Shared helpers: `scripts/` directory
- Custom CLI tools: `cli/` directory
- CI/CD pipelines: `.woodpecker/`
## Special Directories
**`state/`:**
- Purpose: Terraform state files (local backend)
- Generated: Yes (automatically by Terragrunt)
- Committed: No (gitignored; backed up separately)
- Structure: `state/stacks/<service>/terraform.tfstate`
**`secrets/`:**
- Purpose: git-crypt encrypted secrets and sensitive config
- Generated: No (managed manually or via scripts)
- Committed: Yes (encrypted via git-crypt)
- Contents: TLS certs, SSH keys, NFS export list, mailserver config, Dkim keys
**`.terraform/`:**
- Purpose: Terraform provider cache
- Generated: Yes (by Terraform during init)
- Committed: No (gitignored)
**`node_modules/`:**
- Purpose: Node.js dependencies for CLI tools
- Generated: Yes (by npm install)
- Committed: No (gitignored; use lockfile)
## File Patterns & Imports
**Terragrunt Patterns:**
- Include root: `include "root" { path = find_in_parent_folders() }`
- Declare dependencies: `dependency "platform" { config_path = "../platform"; skip_outputs = true }`
- Variable access: `var.<name>` in `main.tf` (variables sourced from `terraform.tfvars`)
**Kubernetes Resource Patterns:**
- Namespace per service: `kubernetes_namespace.<service>` with tier label
- Helm releases: `helm_release.<chart_name>` with `templatefile` for values
- Inline NFS volumes: `volume { name = "data"; nfs { server = "10.0.10.15"; path = "/mnt/main/<service>" } }`
- TLS injection: Every stack calls `module "tls_secret"` to populate namespace secret
**Module Call Pattern:**
- Standard: `module "<name>" { source = "./modules/<module>" ... }`
- Platform modules: `source = "./modules/<service>"`
- Shared modules: `source = "../../modules/kubernetes/<module>"`
---
*Structure analysis: 2026-02-23*