You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
|`logs/`| Output from install, start, or any script |`$HOME/.coder-modules/coder/claude-code/logs/install.log`|
39
+
|`scripts/`| Scripts materialized at runtime (if any) |`$HOME/.coder-modules/coder/claude-code/scripts/install.sh`|
40
+
41
+
- Name log files after the script that produced them (`install.sh` writes to `logs/install.log`, `start.sh` writes to `logs/start.log`).
42
+
- Always `mkdir -p` the target directory before writing; do not assume it exists.
43
+
- Do not write module runtime data to `$HOME` directly, to ad-hoc paths like `~/.<module>-module/`, or to `/tmp/` for anything that must survive the session.
44
+
- Tool-specific data (config files, caches, state, etc.) lives wherever the tool expects; only standardize paths the module itself controls.
45
+
- READMEs and tests should reference paths under this root so troubleshooting has one place to look.
46
+
- New modules MUST follow this layout. Existing modules should migrate to it when they are next touched.
47
+
48
+
## Use `coder-utils` for Script Orchestration
49
+
50
+
For any new module that runs scripts (or when reworking an existing one), use the [`coder-utils`](registry/coder/modules/coder-utils) module to orchestrate `pre_install`, `install`, `post_install`, and `start` scripts instead of hand-rolling `coder_script` resources.
51
+
52
+
-`coder-utils` handles script ordering via `coder exp sync`, materializes scripts under `module_directory/scripts/` (e.g., `install.sh`, `start.sh`), and writes logs to `module_directory/logs/` automatically, which aligns with the Module Data Layout above.
53
+
- Set `module_directory = "$HOME/.coder-modules/<namespace>/<module-name>"` so the standard root, `scripts/`, and `logs/` subdirectories fall out for free.
54
+
55
+
### Passing scripts to `coder-utils`
56
+
57
+
Store each script as a `.tftpl` file under `scripts/`. Render it at **plan time** in a `locals` block using `templatefile()`, then pass the rendered string directly to the `coder-utils` module.
58
+
59
+
**Encoding rules for template variables:**
60
+
61
+
| Value type | Terraform side | Template (`.tftpl`) side |
start_script = var.start_script # optional; omit if the module does not start a process
90
+
}
91
+
```
92
+
93
+
Always expose the `scripts` output as a pass-through so upstream modules can serialize their own `coder_script` resources behind this module's install pipeline:
94
+
95
+
```tf
96
+
output "scripts" {
97
+
description = "Ordered list of coder exp sync names produced by this module, in run order."
98
+
value = module.coder_utils.scripts
99
+
}
100
+
```
101
+
24
102
## Code Style
25
103
26
104
- Every module MUST have `.tftest.hcl` tests; optional `main.test.ts` for container/script tests
@@ -31,6 +109,28 @@ bun test main.test.ts # Run single TS test (from
31
109
-**Do NOT include input/output variable tables in module or template READMEs.** The registry automatically generates these from the Terraform source (e.g., variable and output blocks in `main.tf`). Adding them to the README is redundant and creates maintenance drift.
32
110
- Usage examples (e.g., a `module "..." { }` block) are encouraged, but not tables enumerating inputs/outputs.
- Mark variables and outputs that hold secrets or tokens `sensitive = true`.
126
+
- Every `output` block must have a `description`.
127
+
- Use `count = condition ? 1 : 0` for optional singleton resources. Reserve `for_each` for maps/sets where resource identity matters.
128
+
129
+
### `.tftest.hcl` test commands
130
+
131
+
- Use `command = plan` only for assertions on **input-derived values** (variables, locals computed from inputs).
132
+
- Use `command = apply` for **computed attributes** (resource IDs, anything the provider generates), and for nested blocks of set type (they cannot be indexed with `[0]` under `plan`).
133
+
34
134
## PR Review Checklist
35
135
36
136
- Version bumped via `.github/scripts/version-bump.sh` if module changed (patch=bugfix, minor=feature, major=breaking)
0 commit comments