feat(coder/modules/boundary): add boundary module#840
Conversation
There was a problem hiding this comment.
Pull request overview
Adds a new coder/boundary registry module intended to set up Boundary-related tooling for Coder workspaces.
Changes:
- Introduces a Boundary install/setup shell script that can compile from source, install from release, or rely on
coder boundary. - Adds a Terraform module (
main.tf) that deploys and runs the install script on an agent. - Adds module README and Terraform native tests (
.tftest.hcl).
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 7 comments.
| File | Description |
|---|---|
registry/coder/modules/boundary/scripts/install.sh |
Installs Boundary (or validates coder boundary) and generates a wrapper script. |
registry/coder/modules/boundary/main.tf |
Defines module variables and a coder_script to deliver/execute install.sh. |
registry/coder/modules/boundary/README.md |
Documents module usage and examples. |
registry/coder/modules/boundary/boundary.tftest.hcl |
Adds Terraform plan-time assertions for basic module wiring. |
…lation and execution
…missing mock support Three root causes: 1. boundary_script_destination used 'install.sh' - same filename that coder-utils writes to. This caused the running script to overwrite itself, corrupting bash's incremental read and producing empty install.log / no wrapper. Fix: rename to 'boundary-install.sh'. 2. coder-mock.sh didn't handle 'coder exp sync' commands used by coder-utils for script ordering. With set -o errexit, scripts failed immediately. Fix: add exp sync as no-op (exit 0). 3. Test setup used setupUtil which only extracts ONE coder_script, but coder-utils creates multiple (pre_install, install, post_install). Fix: extract all coder_scripts from terraform state and run them sequentially in lifecycle order. 4. wrapper-script-execution test called 'wrapper.sh --help' which the mock couldn't handle after the '--' separator (tried to exec '--help'). Fix: test with 'echo boundary-test' instead.
The boundary command (both 'coder boundary' and standalone 'boundary') expects a '--' separator before the command to execute. The wrapper scripts were passing arguments directly without this separator, causing the wrapper-script-execution test to fail. 🤖 Generated by Coder Agents
This reverts commit 81df58f.
The boundary wrapper scripts pass arguments directly without a '--' separator. Updated the coder mock to match this behavior and adjusted the test comment accordingly. 🤖 Generated by Coder Agents
eed787d to
4dd0176
Compare
- Renamed scripts/install.sh → scripts/install.sh.tftpl - Use templatefile() to inject variables at plan time instead of base64-encoding the script and passing env vars at runtime - Removed boundary_script/boundary_script_destination locals - Fixed /home/coder expansion in MODULE_DIR and BOUNDARY_WRAPPER_PATH (double quotes for shell expansion) - Updated custom module_directory test paths to match coder-utils validation pattern ($HOME/.coder-modules/<ns>/<name>) - Updated script name references (coder_boundary → coder-boundary) - Fixed coder-utils source to use branch ref 🤖 Generated by Coder Agents
🤖 Generated by Coder Agents
🤖 Generated by Coder Agents
- Remove scaffold comment from main.tf - Add description to 'scripts' output - Add sample config.yaml with allowlist skeleton - Add Configuration section to README with coder_script example - Add Claude Code + boundary example showing coder exp sync wait pattern and $BOUNDARY_WRAPPER_PATH -- claude launcher - Simplify usage examples to use -- separator without config flags 🤖 Generated by Coder Agents
- Add boundary_config (string) for inline config content - Add boundary_config_path (string) for external config file path - Cross-variable validation (mutually exclusive, requires TF >= 1.9) - Ship comprehensive default config based on Coder dogfood allowlist - Write config to ~/.config/coder_boundary/config.yaml by default - Export BOUNDARY_CONFIG env var pointing to the effective config path - Add boundary_config_path output - Tests: 13 pass, 67 assertions (8 HCL plan tests pass)
| # Your Coder deployment domain (required — replace with your own). | ||
| - domain=your-deployment.coder.com | ||
|
|
||
| # Anthropic Services |
There was a problem hiding this comment.
Also include OpenAI end points.
| @@ -0,0 +1,211 @@ | |||
| allowlist: | |||
| # Your Coder deployment domain (required — replace with your own). | |||
| - domain=your-deployment.coder.com | |||
There was a problem hiding this comment.
Can we not prefill this using data.coder_workspace.me.access-url?
| # BOUNDARY_CONFIG points to. | ||
| default_boundary_config = file("${path.module}/config.yaml") | ||
| boundary_config_content = var.boundary_config != null ? var.boundary_config : local.default_boundary_config | ||
| boundary_config_dir = "$HOME/.config/coder_boundary" |
There was a problem hiding this comment.
I think this should live in the .coder-modules/coder/boundary right i.e. module_directory
|
|
||
| validate_boundary_subcommand() { | ||
| if command -v coder > /dev/null 2>&1; then | ||
| if coder boundary --help > /dev/null 2>&1; then |
There was a problem hiding this comment.
How does this play with unlicensed Coder deployments?
|
|
||
| validate_boundary_subcommand() { | ||
| if command -v coder > /dev/null 2>&1; then | ||
| if coder boundary --help > /dev/null 2>&1; then |
There was a problem hiding this comment.
How does this play with unlicensed Coder deployments?
|
|
||
| resource "coder_env" "boundary_wrapper_path" { | ||
| agent_id = var.agent_id | ||
| name = "BOUNDARY_WRAPPER_PATH" |
There was a problem hiding this comment.
Why are we setting both an ENV and an output for the boundary wrapper path. I think a module output is enough and we can remove the ENV
There was a problem hiding this comment.
@35C4n0r, can you respond to this? And please avoid resolving conversations on your own. This confuses the reviewer to see what has been added and how.
Thanks
| value = local.effective_boundary_config_path | ||
| } | ||
|
|
||
| output "boundary_wrapper_path" { |
There was a problem hiding this comment.
Isn't this enough and we can drop BOUNDARY_WRAPPER_PATH?
- Remove BOUNDARY_WRAPPER_PATH env var, keep output only - Move config path into module_directory (config/config.yaml) - Auto-fill Coder deployment domain via data.coder_workspace.me - Add OpenAI endpoints to default config allowlist
…config_path outputs
…help 'coder boundary --help' succeeds even on unlicensed deployments. Use 'coder boundary -- true' instead to catch license entitlement errors and surface an actionable message.
…oder boundary failures
Description
Extracts boundary installation and wrapper logic into a standalone
coder/boundarymodule, decoupling it fromagentapi.Why
Boundary is currently embedded inside
agentapi(scripts/boundary.sh) and duplicated inclaude-code. This couples network isolation to the AI/Tasks stack, but boundary is a general-purpose primitive — users running a plain agent with no agentapi or tasks should be able to use it too.What this adds
registry/coder/modules/boundary/— a new first-class module that:coder boundarysubcommand (default, zero-install)use_boundary_directly = true)compile_boundary_from_source = true)$HOME/.coder-modules/coder/boundary/boundary-wrapper.shBOUNDARY_WRAPPER_PATHas acoder_envso any workspace process can use itCAP_NET_ADMINfrom the coder binary (copies tocoder-no-caps) to allow execution inside network namespaces withoutsys_adminpre_install_script/post_install_scripthooksboundary_wrapper_pathoutput andsync_script_namesfor script coordinationUsage
Works standalone with any agent — no agentapi dependency required.
Testing
boundary.tftest.hcl)main.test.ts): state verification, coder subcommand happy path, custom hooks, env var correctness, wrapper execution, idempotent installationType of Change
Module Information
Path:
registry/coder/modules/boundaryNew version:
v0.0.1Breaking change: No
Related Issues
Closes #844
🤖 Generated by Coder Agents