# Agent Guide ## Project Summary Incus cluster managed with OpenTofu. The cluster has 2 hypervisors and 1 witness for quorum. ## CLI Always use `tofu`, never `terraform`. ## Architecture Two-role cluster: hypervisors run workloads, witnesses maintain database quorum. Every cluster-wide resource (network, storage pool) follows a three-layer pattern: 1. Per-hypervisor target resources 2. Per-witness target resources 3. Cluster-wide resource that `depends_on` both ## Module Conventions Modules live in `modules//`. Each module accepts: - `name` — resource name - A resource-specific type/driver string - `hypervisors` / `witnesses` — sets of node names - `hypervisor_config` / `witness_config` — free-form `map(string)` for per-role provider config The root module iterates with `for_each` over a variable map and fans values into the module. ## File Layout One root `.tf` file per concern: - `provider.tf` — provider configuration - `groups.tf` — cluster groups - `network.tf` — network resources - `storage.tf` — storage pool resources - `variables.tf` — variable declarations Variable values live in `.auto.tfvars` files, one per concern. ## Validation After any change: 1. `tofu validate` 2. `tofu plan` Plan output should show no unexpected replacements or destroys for existing resources.