# Coding Conventions **Analysis Date:** 2026-02-23 ## Naming Patterns **Terraform Files:** - `main.tf` - Primary resource definitions and module calls - `terragrunt.hcl` - Stack-specific Terragrunt configuration - `variables.tf` - Variable declarations for a stack - `providers.tf` - Generated by Terragrunt root `terragrunt.hcl` - `backend.tf` - Generated by Terragrunt for state backend configuration **Terraform Variables:** - snake_case for variable names: `var.tls_secret_name`, `var.dbaas_root_password` - snake_case for resource names: `resource "kubernetes_namespace" "nextcloud"` - snake_case for local values: `local.tiers` - UPPERCASE for environment-like globals in shell: `KUBECONFIG_PATH`, `PASS_COUNT` **Resource/Module Names:** - kebab-case for Kubernetes resources: `nextcloud`, `whiteboard`, `kms-web-page` - Leading underscore for prefixed resource names (internal/private pattern): resource names with underscores are module-internal - Descriptive names matching functionality: `kubernetes_namespace`, `kubernetes_deployment`, `helm_release` **Shell Functions:** - snake_case for function names: `parse_args()`, `count_lines()`, `check_nodes()` - CamelCase for utility color variables: `RED`, `GREEN`, `YELLOW`, `BLUE`, `BOLD`, `NC` **Go Package/Test Names:** - Package-level test functions: `TestContainsVideoMarkers()`, `TestIsDirectVideoContentType()` - Table-driven test pattern with struct fields: `name`, `body`, `ct`, `want` ## Code Style **Terraform Formatting:** - Use `terraform fmt -recursive` for consistent formatting - No explicit linter/formatter config file (tflint/terraform-lint not present) - Indentation: 2 spaces (standard Terraform convention) - Multi-line strings use heredoc syntax: `<&1) || { fail "message"; return 0; }` - `set -euo pipefail` prevents silent failures and undefined var issues - Error status captured: `$?` implicit via `||` pattern - Graceful degradation with fallback values or skip-able steps **Go:** - Standard testing error reporting: `t.Errorf()` with formatted messages - Table-driven test pattern allows multiple related test cases - Error messages include actual vs expected: `got = %v, want = %v` ## Logging **Framework:** Not formally configured; uses `echo` and `echo -e` for output **Bash Logging Patterns:** - Color-coded output with status prefixes: `${BLUE}[INFO]${NC}`, `${GREEN}[PASS]${NC}`, `${YELLOW}[WARN]${NC}`, `${RED}[FAIL]${NC}` - Helper functions: `info()`, `pass()`, `warn()`, `fail()` - each increments counters and respects `--quiet` flag - Section headers: `section()` for verbose output, `section_always()` for always-shown sections - Conditional logging: functions check `$JSON`, `$QUIET` flags and skip output as needed - JSON output option available via `json_add()` for machine-readable logging - Detail strings accumulated in variables for final reporting **Terraform Logging:** - Relies on Terraform's built-in CLI output - Human-readable variable values in descriptions (Terraform renders these on errors) ## Comments **When to Comment:** Terraform: - Section dividers: Major logical groups separated by `# =============================================================================` - Feature group headers: `# --- Feature Name ---` before variable/module blocks - Commented-out code: Temporarily disabled resources/modules include explanation (e.g., "Do not use until issue #X is solved") - Clarifying arbitrary choices: `# anything secret is fine` explains non-obvious variable usage Bash: - Function-level comments: Each check function has purpose on first line - Complex logic: Comments before conditional blocks explain intent - Inline comments for edge cases: `# Skip nodes where metrics are not yet available` - Header comments: Scripts include usage documentation at top **JSDoc/TSDoc:** - Not used in this codebase (Terraform, Bash, Go only) ## Function Design **Size:** - Terraform modules typically 20-50 lines for simple services, variable declaration blocks 30-100+ lines - Bash functions average 20-40 lines, check functions 10-30 lines - Go test functions 10-60 lines (table + loop) **Parameters:** - Terraform: via `variable` declarations and module input variables - Bash: positional parameters passed via `$1`, `$2`, etc. with validation in `parse_args()` - Go: test functions accept `*testing.T` parameter **Return Values:** - Terraform: no explicit returns; resource state is the "return" - Bash: `return 0` for success, implicit via `echo` output for values, status codes for error handling - Go: functions tested for boolean returns or calculated values **Variables:** - Terraform: module variables, locals, and resource attributes (computed values) - Bash: Global state tracked via counters (`PASS_COUNT`, `WARN_COUNT`, `FAIL_COUNT`), local variables in functions with `local` keyword - Go: table-driven tests use struct fields (no getter/setter pattern) ## Module Design **Exports:** - Terraform: outputs typically omitted unless another stack depends on them (implicit via dependency blocks) - Modules called with `source = "./modules/"` or `source = "../../modules/kubernetes/"` - Module version pinning used for Terraform registry modules: `version = "0.1.5"` **Barrel Files:** - Not applicable (no aggregating re-exports in this codebase) - Directories: `stacks//` is a unit, `stacks/platform/modules//` groups related modules **Module Organization:** - Single responsibility per module directory - Each module typically contains: `main.tf` (resources) and optional `variables.tf` for input variables - Shared Kubernetes utility modules in `modules/kubernetes/`: `ingress_factory/`, `setup_tls_secret/` - Platform services grouped in `stacks/platform/modules//` ## Special Patterns **Locals for Configuration:** - Tier definitions centralized as map in locals (each service defines same tiers locally) ```hcl locals { tiers = { core = "0-core" cluster = "1-cluster" gpu = "2-gpu" edge = "3-edge" aux = "4-aux" } } ``` - Tier applied to `kubernetes_namespace` labels and `priority_class_name` for resource governance **Inline Config Blocks:** - YAML/config data stored in `<