Skip to content

feat(coder/modules/boundary): add boundary module#840

Draft
35C4n0r wants to merge 57 commits intomainfrom
35C4n0r/feat-boundary-module
Draft

feat(coder/modules/boundary): add boundary module#840
35C4n0r wants to merge 57 commits intomainfrom
35C4n0r/feat-boundary-module

Conversation

@35C4n0r
Copy link
Copy Markdown
Collaborator

@35C4n0r 35C4n0r commented Apr 13, 2026

Description

Extracts boundary installation and wrapper logic into a standalone coder/boundary module, decoupling it from agentapi.

Why

Boundary is currently embedded inside agentapi (scripts/boundary.sh) and duplicated in claude-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:

  • Installs boundary via one of three strategies:
    1. coder boundary subcommand (default, zero-install)
    2. Direct binary from release (use_boundary_directly = true)
    3. Compiled from source (compile_boundary_from_source = true)
  • Creates a wrapper script at $HOME/.coder-modules/coder/boundary/boundary-wrapper.sh
  • Exports BOUNDARY_WRAPPER_PATH as a coder_env so any workspace process can use it
  • Strips CAP_NET_ADMIN from the coder binary (copies to coder-no-caps) to allow execution inside network namespaces without sys_admin
  • Supports pre_install_script / post_install_script hooks
  • Exposes boundary_wrapper_path output and sync_script_names for script coordination

Usage

module "boundary" {
  count    = data.coder_workspace.me.start_count
  source   = "registry.coder.com/coder/boundary/coder"
  version  = "0.0.1"
  agent_id = coder_agent.main.id
}

Works standalone with any agent — no agentapi dependency required.

Testing

  • Terraform variable validation (boundary.tftest.hcl)
  • TypeScript integration tests (main.test.ts): state verification, coder subcommand happy path, custom hooks, env var correctness, wrapper execution, idempotent installation

Type of Change

  • New module

Module Information

Path: registry/coder/modules/boundary
New version: v0.0.1
Breaking change: No

Related Issues

Closes #844

🤖 Generated by Coder Agents

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread registry/coder/modules/boundary/scripts/install.sh Outdated
Comment thread registry/coder/modules/boundary/scripts/install.sh Outdated
Comment thread registry/coder/modules/boundary/scripts/install.sh Outdated
Comment thread registry/coder/modules/boundary/scripts/install.sh Outdated
Comment thread registry/coder/modules/boundary/scripts/install.sh
Comment thread registry/coder/modules/boundary/main.tf Outdated
Comment thread registry/coder/modules/boundary/README.md
@35C4n0r 35C4n0r marked this pull request as draft April 13, 2026 03:38
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 7 comments.

Comment thread registry/coder/modules/boundary/main.tf Outdated
Comment thread registry/coder/modules/boundary/main.tf Outdated
Comment thread registry/coder/modules/boundary/main.test.ts Outdated
Comment thread registry/coder/modules/boundary/testdata/boundary-mock.sh Outdated
Comment thread registry/coder/modules/boundary/scripts/install.sh Outdated
Comment thread registry/coder/modules/boundary/scripts/install.sh Outdated
Comment thread registry/coder/modules/boundary/scripts/install.sh Outdated
Jay Kumar and others added 8 commits April 14, 2026 18:19
…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
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
@35C4n0r 35C4n0r marked this pull request as ready for review April 15, 2026 17:27
@matifali matifali requested review from SasSwart, dannykopping and jcjiang and removed request for matifali April 16, 2026 04:50
@35C4n0r 35C4n0r force-pushed the 35C4n0r/feat-boundary-module branch from eed787d to 4dd0176 Compare April 23, 2026 18:06
35C4n0r and others added 10 commits April 24, 2026 21:35
- 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
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also include OpenAI end points.

@@ -0,0 +1,211 @@
allowlist:
# Your Coder deployment domain (required — replace with your own).
- domain=your-deployment.coder.com
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we not prefill this using data.coder_workspace.me.access-url?

Comment thread registry/coder/modules/boundary/main.tf Outdated
# 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"
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How does this play with unlicensed Coder deployments?

Comment thread registry/coder/modules/boundary/main.tf Outdated

resource "coder_env" "boundary_wrapper_path" {
agent_id = var.agent_id
name = "BOUNDARY_WRAPPER_PATH"
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@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" {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this enough and we can drop BOUNDARY_WRAPPER_PATH?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

??

Jay Kumar and others added 7 commits April 28, 2026 09:51
- 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
…help

'coder boundary --help' succeeds even on unlicensed deployments.
Use 'coder boundary -- true' instead to catch license entitlement
errors and surface an actionable message.
@matifali matifali requested a review from SasSwart April 28, 2026 15:30
@35C4n0r 35C4n0r marked this pull request as draft April 28, 2026 17:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Decouple boundary into its own standalone module

4 participants