Skip to content
Open
11 changes: 5 additions & 6 deletions registry/coder/modules/coder-utils/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ The Coder Utils module is a building block for modules that need to run multiple
```tf
module "coder_utils" {
source = "registry.coder.com/coder/coder-utils/coder"
version = "1.0.1"
version = "1.1.0"

agent_id = coder_agent.main.id
agent_name = "myagent"
Expand Down Expand Up @@ -56,10 +56,9 @@ module "coder_utils" {

The module orchestrates scripts in the following order:

1. **Log File Creation** - Creates module directory and log files
2. **Pre-Install Script** (optional) - Runs before installation
3. **Install Script** - Main installation
4. **Post-Install Script** (optional) - Runs after installation
5. **Start Script** - Starts the application
1. **Pre-Install Script** (optional) - Runs before installation
2. **Install Script** (required) - Main installation
3. **Post-Install Script** (optional) - Runs after installation
4. **Start Script** (optional) - Starts the application

Each script waits for its prerequisites to complete before running using `coder exp sync` dependency management.
2 changes: 1 addition & 1 deletion registry/coder/modules/coder-utils/main.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ describe("coder-utils", async () => {
agent_id: "test-agent-id",
agent_name: "test-agent",
module_dir_name: ".test-module",
start_script: "echo 'start'",
install_script: "echo 'install'",
});
});
35 changes: 20 additions & 15 deletions registry/coder/modules/coder-utils/main.tf
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
terraform {
required_version = ">= 1.0"
required_version = ">= 1.9"

required_providers {
coder = {
Expand Down Expand Up @@ -29,7 +29,6 @@ variable "pre_install_script" {
variable "install_script" {
type = string
description = "Script to install the agent used by AgentAPI."
default = null
}

variable "post_install_script" {
Expand All @@ -41,6 +40,7 @@ variable "post_install_script" {
variable "start_script" {
type = string
description = "Script that starts AgentAPI."
default = null
}

variable "agent_name" {
Expand All @@ -56,16 +56,16 @@ variable "module_dir_name" {

locals {
encoded_pre_install_script = var.pre_install_script != null ? base64encode(var.pre_install_script) : ""
encoded_install_script = var.install_script != null ? base64encode(var.install_script) : ""
encoded_install_script = base64encode(var.install_script)
encoded_post_install_script = var.post_install_script != null ? base64encode(var.post_install_script) : ""
encoded_start_script = base64encode(var.start_script)
encoded_start_script = var.start_script != null ? base64encode(var.start_script) : ""

pre_install_script_name = "${var.agent_name}-pre_install_script"
install_script_name = "${var.agent_name}-install_script"
post_install_script_name = "${var.agent_name}-post_install_script"
start_script_name = "${var.agent_name}-start_script"

module_dir_path = "$HOME/${var.module_dir_name}"
module_dir_path = "$HOME/.coder-modules/coder/coder-utils/${var.module_dir_name}"
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Ultimately this is a NIT and not a blocker.

I know we were debating on where we actually wanted all of this to live but did we finally decide that this is what we wanted over anything else?

I only ask because coder-registry/ comes to mind since we could isolate all of module related files into that one folder since they derive from here.

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.

there is also CODER_SCRIPT_BIN_DIR.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I only ask because coder-registry/ comes to mind since we could isolate all of module related files into that one folder since they derive from here.

like $HOME/coder-registry/author/module_name/* ?

also we also want this to be configurable, so I'll add a variable here as I'm planning to do with boundary, tasks , and other ai module.

locals{
    resolved_base_module_dir = var.base_module_dir ? var.base_module_dir : "$HOME/coder-registry"
    module_dir_path = "${local.resolved_base_module_dir}/author/${var.module_dir_name}"
}

@DevelopmentCats @matifali thoughts ?

Copy link
Copy Markdown
Collaborator Author

@35C4n0r 35C4n0r Apr 13, 2026

Choose a reason for hiding this comment

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

oof, that make author hardcoded, and other users won't be able to use it.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I know we were debating on where we actually wanted all of this to live but did we finally decide that this is what we wanted over anything else?

thread


pre_install_path = "${local.module_dir_path}/pre_install.sh"
install_path = "${local.module_dir_path}/install.sh"
Expand All @@ -76,6 +76,14 @@ locals {
install_log_path = "${local.module_dir_path}/install.log"
post_install_log_path = "${local.module_dir_path}/post_install.log"
start_log_path = "${local.module_dir_path}/start.log"

install_sync_deps = var.pre_install_script != null ? local.pre_install_script_name : null

start_sync_deps = (
var.post_install_script != null
? "${local.install_script_name} ${local.post_install_script_name}"
: local.install_script_name
)
}

resource "coder_script" "pre_install_script" {
Expand Down Expand Up @@ -112,8 +120,8 @@ resource "coder_script" "install_script" {
mkdir -p ${local.module_dir_path}

trap 'coder exp sync complete ${local.install_script_name}' EXIT
%{if var.pre_install_script != null~}
coder exp sync want ${local.install_script_name} ${local.pre_install_script_name}
%{if local.install_sync_deps != null~}
coder exp sync want ${local.install_script_name} ${local.install_sync_deps}
%{endif~}
coder exp sync start ${local.install_script_name}
echo -n '${local.encoded_install_script}' | base64 -d > ${local.install_path}
Expand Down Expand Up @@ -145,6 +153,7 @@ resource "coder_script" "post_install_script" {
}

resource "coder_script" "start_script" {
count = var.start_script != null ? 1 : 0
agent_id = var.agent_id
display_name = "Start Script"
run_on_start = true
Expand All @@ -155,11 +164,7 @@ resource "coder_script" "start_script" {

trap 'coder exp sync complete ${local.start_script_name}' EXIT

%{if var.post_install_script != null~}
coder exp sync want ${local.start_script_name} ${local.install_script_name} ${local.post_install_script_name}
%{else~}
coder exp sync want ${local.start_script_name} ${local.install_script_name}
%{endif~}
coder exp sync want ${local.start_script_name} ${local.start_sync_deps}
coder exp sync start ${local.start_script_name}

echo -n '${local.encoded_start_script}' | base64 -d > ${local.start_path}
Expand All @@ -171,7 +176,7 @@ resource "coder_script" "start_script" {

output "pre_install_script_name" {
description = "The name of the pre-install script for sync."
value = local.pre_install_script_name
value = var.pre_install_script != null ? local.pre_install_script_name : ""
}

output "install_script_name" {
Expand All @@ -181,10 +186,10 @@ output "install_script_name" {

output "post_install_script_name" {
description = "The name of the post-install script for sync."
value = local.post_install_script_name
value = var.post_install_script != null ? local.post_install_script_name : ""
}

output "start_script_name" {
description = "The name of the start script for sync."
value = local.start_script_name
value = var.start_script != null ? local.start_script_name : ""
}
Loading
Loading