11 KiB
11 KiB
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 injectiondocker-registry/: Docker registry pull-through cache setupkubernetes/: 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+ optionalfactory/(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) + optionalfactory/+ optionalchart_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 withnfs_exports.shtls/: TLS certificate chain and keysmailserver/: OpenDKIM keys, Postfix SASL creds
scripts/:
- Purpose: Operational and maintenance automation
- Key scripts:
cluster_healthcheck.sh: 24-point cluster health statusrenew2.sh: TLS certificate renewal via certbot + Cloudflaresetup_certs.sh: Initial certificate setuppve_*: Proxmox management scriptsha_*: 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 byterragrunt applyin any stack directorystacks/platform/main.tf: Platform stack; applies 22 core modulesstacks/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 namestacks/<service>/terragrunt.hcl: Stack-specific Terragrunt config (includes root, declaresdependencyblocks)stacks/platform/modules/<service>/main.tf: Platform module implementation (22 modules)
Core Logic:
stacks/platform/main.tf: 1000+ lines; instantiates all 22 platform modulesstacks/<service>/main.tf: 30–450 lines; creates namespaces, Helm releases, Kubernetes resourcesstacks/<service>/factory/main.tf: Multi-instance service pattern; called multiple times with different parametersmodules/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-secretinjected into all namespaces viasetup_tls_secretmodule
Naming Conventions
Files:
main.tf: Primary Terraform resource file per stackterragrunt.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 namesstate/stacks/<service>/: Mirrored state directory structuresecrets/: Single top-level directory for all encrypted filesmodules/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:
- Create
stacks/<service>/directory - Add
terragrunt.hcl:include "root" { path = find_in_parent_folders() } dependency "platform" { config_path = "../platform" skip_outputs = true } - Create
main.tfwith:- Variable declarations for required inputs from
terraform.tfvars locals { tiers = { ... } }(copy from existing stack)kubernetes_namespaceresource with tier labelmodule "tls_secret"call to../../modules/kubernetes/setup_tls_secret- Service-specific resources (Helm releases, Deployments, etc.)
- Variable declarations for required inputs from
- Add Cloudflare DNS records in
terraform.tfvarsif needed - Create optional
secrets/symlink:ln -s ../../secrets secrets - Apply:
cd stacks/<service> && terragrunt apply --non-interactive
Multi-Tenant Service (using Factory Pattern):
- Create parent stack:
stacks/<service>/main.tfwith namespace + TLS setup - Create
stacks/<service>/factory/main.tfwith single-instance logic - In parent, call factory multiple times:
module "instance1" { source = "./factory" name = "instance1" # ... other params } - Example:
stacks/actualbudget/has factory instantiated for viktor, anca, emo
New Platform Module:
- Create
stacks/platform/modules/<service>/directory - Add
main.tfwith resources (Helm chart, namespace, ConfigMaps, etc.) - Add
variables.tfor declare variables inmain.tf - In
stacks/platform/main.tf, add module call:module "<service>" { source = "./modules/<service>" tier = local.tiers.<tier> # ... pass required variables } - Add variable declarations in
stacks/platform/main.tf
New Shared Module:
- Create
modules/kubernetes/<module_name>/ormodules/terraform/<module_name>/ - Add
main.tfwith reusable resources - Declare clear variable inputs and output any useful values
- 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>inmain.tf(variables sourced fromterraform.tfvars)
Kubernetes Resource Patterns:
- Namespace per service:
kubernetes_namespace.<service>with tier label - Helm releases:
helm_release.<chart_name>withtemplatefilefor 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