From 0976d62b8f419ddae05fdcd43aa277a237c8886b Mon Sep 17 00:00:00 2001 From: Tao Chen Date: Mon, 15 Dec 2025 14:47:54 +0800 Subject: [PATCH 01/11] try to deploy coder on existed linux system --- registry/coder/templates/ssh-linux/README.md | 1 + registry/coder/templates/ssh-linux/main.tf | 232 +++++++++++++++++++ 2 files changed, 233 insertions(+) create mode 100644 registry/coder/templates/ssh-linux/README.md create mode 100644 registry/coder/templates/ssh-linux/main.tf diff --git a/registry/coder/templates/ssh-linux/README.md b/registry/coder/templates/ssh-linux/README.md new file mode 100644 index 000000000..25590f2a5 --- /dev/null +++ b/registry/coder/templates/ssh-linux/README.md @@ -0,0 +1 @@ +# Deploy Coder on existed Linux system \ No newline at end of file diff --git a/registry/coder/templates/ssh-linux/main.tf b/registry/coder/templates/ssh-linux/main.tf new file mode 100644 index 000000000..ba633a366 --- /dev/null +++ b/registry/coder/templates/ssh-linux/main.tf @@ -0,0 +1,232 @@ +terraform { + required_providers { + coder = { + source = "coder/coder" + version = ">= 2.4.0" + } + } +} + +provider "coder" {} +data "coder_workspace" "me" {} +data "coder_workspace_owner" "me" {} + + +data "coder_parameter" "host" { + description = "Remote Host or IP" + display_name = "Host" + name = "host" + type = "string" + default = "192.168.1.1" + mutable = false + order = 1 + validation { + regex = "^[a-zA-Z0-9:.%\\-]+$" + error = "Please enter a valid hostname, IPv4, or IPv6 address." +} +} + +data "coder_parameter" "username" { + default = data.coder_workspace_owner.me.name + description = "SSH Username" + display_name = "Username" + name = "username" + mutable = false + order = 2 +} + +data "coder_parameter" "auth_type" { + name = "auth_type" + display_name = "SSH Auth Type" + description = "Authentication method for SSH" + type = "string" + + form_type = "dropdown" + default = "password" + mutable = true + order = 3 + option { + name = "password" + value = "password" + } + + option { + name = "SSH Key" + value = "ssh_key" + } +} + +data "coder_parameter" "ssh_password" { + count = data.coder_parameter.auth_type.value == "password" ? 1 : 0 + name = "ssh_password" + display_name = "SSH Password" + description = "Password for SSH login" + type = "string" + mutable = true + styling = jsonencode({ + mask_input = true + }) + order = 4 +} + +data "coder_parameter" "ssh_key" { + count = data.coder_parameter.auth_type.value == "ssh_key" ? 1 : 0 + name = "ssh_key" + display_name = "SSH Private Key" + description = "Paste SSH private key" + type = "string" + mutable = true + form_type = "textarea" + styling = jsonencode({ + mask_input = true + }) + order = 4 +} + + +data "coder_parameter" "port" { + default = 22 + description = "SSH Port" + display_name = "Port" + name = "port" + type = "number" + mutable = true + order = 5 + validation { + min = 1 + max = 65535 + error = "Port must be between 1 and 65535" + } +} + +data "coder_parameter" "apps" { + name = "apps" + display_name = "Choose any APPs for your workspace." + type = "list(string)" + form_type = "multi-select" + mutable = true + default = jsonencode(["VS Code Desktop"]) + dynamic "option" { + for_each = local.apps_candidate + content { + name = option.value + value = option.value + } + } +} + +locals { + username = data.coder_parameter.username.value + home_dir = "/home/${lower(local.username)}" + coder_cache_dir = "${local.home_dir}/.coder" + use_password = data.coder_parameter.auth_type.value == "password" + use_key = data.coder_parameter.auth_type.value == "ssh_key" + ssh_password = local.use_password ? data.coder_parameter.ssh_password[0].value : null + ssh_private_key = local.use_key ? data.coder_parameter.ssh_key[0].value : null + apps_candidate = ["VS Code Desktop","VS Code Web", "Cursor"] + apps_selected = (can(data.coder_parameter.apps.value) && data.coder_parameter.apps.value != "") ? jsondecode(data.coder_parameter.apps.value) : [] +} + +resource "coder_agent" "main" { + os = "linux" + arch = "amd64" + + startup_script = <<-EOT + #!/bin/bash + set -euo pipefail + EOT + + env = { + GIT_AUTHOR_NAME = coalesce(data.coder_workspace_owner.me.full_name, data.coder_workspace_owner.me.name) + GIT_AUTHOR_EMAIL = "${data.coder_workspace_owner.me.email}" + GIT_COMMITTER_NAME = coalesce(data.coder_workspace_owner.me.full_name, data.coder_workspace_owner.me.name) + GIT_COMMITTER_EMAIL = "${data.coder_workspace_owner.me.email}" + } + + display_apps { + port_forwarding_helper = true + vscode = contains(local.apps_selected, "VS Code Desktop") + vscode_insiders = contains(local.apps_selected, "VS Code Desktop") + web_terminal = true + ssh_helper = true + } + + metadata { + key = "cpu" + display_name = "CPU Usage" + interval = 5 + timeout = 5 + script = "coder stat cpu" + } + metadata { + key = "memory" + display_name = "Memory Usage" + interval = 5 + timeout = 5 + script = "coder stat mem" + } + metadata { + key = "disk" + display_name = "Home Disk Usage" + interval = 600 + timeout = 30 + script = "coder stat disk --path ${lower(local.home_dir)}" + } +} + +resource "null_resource" "deploy_coder_agent" { + triggers = { + init_script = sha256(coder_agent.main.init_script) + token = coder_agent.main.token + } + +connection { + type = "ssh" + host = data.coder_parameter.host.value + user = data.coder_parameter.username.value + port = data.coder_parameter.port.value + password = local.ssh_password + private_key = local.ssh_private_key + timeout = "5m" +} + +provisioner "remote-exec" { + inline = [ + "mkdir -p ${local.coder_cache_dir}", + "timestamp=$(date +%s)", + "coder_sh=${local.coder_cache_dir}/coder_$timestamp.sh", + "cat > $coder_sh << 'EOF'", + "${coder_agent.main.init_script}", + "EOF", + "chmod +x $coder_sh", + "echo \"$(date) : create $coder_sh\" >> ${local.coder_cache_dir}/debug.log", + "nohup env CODER_AGENT_TOKEN='${coder_agent.main.token}' $coder_sh > ${local.coder_cache_dir}/coder_log_$timestamp.log 2>&1 &", + "echo \"$(date) : run $coder_sh\" >> ${local.coder_cache_dir}/debug.log", + "rm $coder_sh" + ] +} +} + + +module "coder-login" { + count = data.coder_workspace.me.start_count + source = "registry.coder.com/coder/coder-login/coder" + version = "1.1.1" + agent_id = coder_agent.main.id +} + +module "cursor" { + count = contains(local.apps_selected, "Cursor") ? data.coder_workspace.me.start_count : 0 + source = "registry.coder.com/coder/cursor/coder" + version = "1.4.0" + agent_id = coder_agent.main.id +} + +module "vscode-web" { + count = contains(local.apps_selected, "VS Code Web") ? data.coder_workspace.me.start_count : 0 + source = "registry.coder.com/coder/vscode-web/coder" + version = "1.4.3" + agent_id = coder_agent.main.id + folder = local.home_dir + accept_license = true +} From 32ebb2126dd9cda801ccced283ae691d06f36cb7 Mon Sep 17 00:00:00 2001 From: Tao Chen Date: Mon, 15 Dec 2025 15:08:19 +0800 Subject: [PATCH 02/11] fix deploy scripts --- registry/coder/templates/ssh-linux/main.tf | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/registry/coder/templates/ssh-linux/main.tf b/registry/coder/templates/ssh-linux/main.tf index ba633a366..de2e140cf 100644 --- a/registry/coder/templates/ssh-linux/main.tf +++ b/registry/coder/templates/ssh-linux/main.tf @@ -194,15 +194,15 @@ provisioner "remote-exec" { inline = [ "mkdir -p ${local.coder_cache_dir}", "timestamp=$(date +%s)", - "coder_sh=${local.coder_cache_dir}/coder_$timestamp.sh", + "coder_sh=${local.coder_cache_dir}/coder.sh", + "log_file=${local.coder_cache_dir}/coder_$timestamp.log", "cat > $coder_sh << 'EOF'", "${coder_agent.main.init_script}", "EOF", "chmod +x $coder_sh", "echo \"$(date) : create $coder_sh\" >> ${local.coder_cache_dir}/debug.log", - "nohup env CODER_AGENT_TOKEN='${coder_agent.main.token}' $coder_sh > ${local.coder_cache_dir}/coder_log_$timestamp.log 2>&1 &", - "echo \"$(date) : run $coder_sh\" >> ${local.coder_cache_dir}/debug.log", - "rm $coder_sh" + "nohup env CODER_AGENT_TOKEN='${coder_agent.main.token}' $coder_sh > $log_file 2>&1 &", + "echo \"$(date) : run $coder_sh and log at $log_file\" >> ${local.coder_cache_dir}/debug.log", ] } } From 17bb5cf15217c34fbaf023ce836aa2a192ac58c8 Mon Sep 17 00:00:00 2001 From: Tao Chen Date: Mon, 15 Dec 2025 16:03:25 +0800 Subject: [PATCH 03/11] make display_apps.vscode_insiders =false --- registry/coder/templates/ssh-linux/main.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/registry/coder/templates/ssh-linux/main.tf b/registry/coder/templates/ssh-linux/main.tf index de2e140cf..b9251bf9e 100644 --- a/registry/coder/templates/ssh-linux/main.tf +++ b/registry/coder/templates/ssh-linux/main.tf @@ -146,7 +146,7 @@ resource "coder_agent" "main" { display_apps { port_forwarding_helper = true vscode = contains(local.apps_selected, "VS Code Desktop") - vscode_insiders = contains(local.apps_selected, "VS Code Desktop") + vscode_insiders = false web_terminal = true ssh_helper = true } From cafa17a948e83e680f2126f026613951bbf9f162 Mon Sep 17 00:00:00 2001 From: Tao Chen Date: Tue, 16 Dec 2025 03:18:20 +0800 Subject: [PATCH 04/11] add count for deploy_coder_agent --- registry/coder/templates/ssh-linux/main.tf | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/registry/coder/templates/ssh-linux/main.tf b/registry/coder/templates/ssh-linux/main.tf index b9251bf9e..7247e09b0 100644 --- a/registry/coder/templates/ssh-linux/main.tf +++ b/registry/coder/templates/ssh-linux/main.tf @@ -175,6 +175,8 @@ resource "coder_agent" "main" { } resource "null_resource" "deploy_coder_agent" { + count = data.coder_workspace.me.start_count + triggers = { init_script = sha256(coder_agent.main.init_script) token = coder_agent.main.token @@ -204,7 +206,7 @@ provisioner "remote-exec" { "nohup env CODER_AGENT_TOKEN='${coder_agent.main.token}' $coder_sh > $log_file 2>&1 &", "echo \"$(date) : run $coder_sh and log at $log_file\" >> ${local.coder_cache_dir}/debug.log", ] -} + } } From de7bffff4f768655035e82ca3ec8e4226fa19078 Mon Sep 17 00:00:00 2001 From: Tao Chen Date: Tue, 16 Dec 2025 04:59:07 +0800 Subject: [PATCH 05/11] kill agent while workspace stopped --- registry/coder/templates/ssh-linux/main.tf | 38 +++++++++++++++++++--- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/registry/coder/templates/ssh-linux/main.tf b/registry/coder/templates/ssh-linux/main.tf index 7247e09b0..fa46be096 100644 --- a/registry/coder/templates/ssh-linux/main.tf +++ b/registry/coder/templates/ssh-linux/main.tf @@ -118,13 +118,14 @@ data "coder_parameter" "apps" { locals { username = data.coder_parameter.username.value home_dir = "/home/${lower(local.username)}" - coder_cache_dir = "${local.home_dir}/.coder" + coder_cache_dir = "${local.home_dir}/.coder/${data.coder_workspace.me.id}" + agent_id_file = "${local.coder_cache_dir}/agent.id" use_password = data.coder_parameter.auth_type.value == "password" use_key = data.coder_parameter.auth_type.value == "ssh_key" ssh_password = local.use_password ? data.coder_parameter.ssh_password[0].value : null ssh_private_key = local.use_key ? data.coder_parameter.ssh_key[0].value : null apps_candidate = ["VS Code Desktop","VS Code Web", "Cursor"] - apps_selected = (can(data.coder_parameter.apps.value) && data.coder_parameter.apps.value != "") ? jsondecode(data.coder_parameter.apps.value) : [] + apps_selected = (can(data.coder_parameter.apps.value) && data.coder_parameter.apps.value != "") ? jsondecode(data.coder_parameter.apps.value) : [] } resource "coder_agent" "main" { @@ -195,20 +196,49 @@ connection { provisioner "remote-exec" { inline = [ "mkdir -p ${local.coder_cache_dir}", - "timestamp=$(date +%s)", "coder_sh=${local.coder_cache_dir}/coder.sh", - "log_file=${local.coder_cache_dir}/coder_$timestamp.log", + "log_file=${local.coder_cache_dir}/coder.log", "cat > $coder_sh << 'EOF'", "${coder_agent.main.init_script}", "EOF", "chmod +x $coder_sh", "echo \"$(date) : create $coder_sh\" >> ${local.coder_cache_dir}/debug.log", "nohup env CODER_AGENT_TOKEN='${coder_agent.main.token}' $coder_sh > $log_file 2>&1 &", + "echo $! > ${local.agent_id_file}", "echo \"$(date) : run $coder_sh and log at $log_file\" >> ${local.coder_cache_dir}/debug.log", ] } } +resource "null_resource" "coder_stop" { + count = data.coder_workspace.me.start_count > 0 ? 0 : 1 + +connection { + type = "ssh" + host = data.coder_parameter.host.value + user = data.coder_parameter.username.value + port = data.coder_parameter.port.value + password = local.ssh_password + private_key = local.ssh_private_key + timeout = "5m" +} + + provisioner "remote-exec" { + inline = [ + "PID_FILE=${local.agent_id_file}", + "if [ -f \"$PID_FILE\" ]; then", + " PID=$(cat \"$PID_FILE\")", + " if kill -0 \"$PID\" 2>/dev/null; then", + " kill -TERM \"$PID\" || true", + " sleep 5", + " kill -KILL \"$PID\" || true", + " fi", + " rm -r ${local.coder_cache_dir}", + "fi", + ] + } +} + module "coder-login" { count = data.coder_workspace.me.start_count From 1cc00d2444db6f4ad75e15269eea64e8dfac6526 Mon Sep 17 00:00:00 2001 From: Tao Chen Date: Tue, 16 Dec 2025 06:46:07 +0800 Subject: [PATCH 06/11] fix count --- registry/coder/templates/ssh-linux/main.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/registry/coder/templates/ssh-linux/main.tf b/registry/coder/templates/ssh-linux/main.tf index fa46be096..39d37e780 100644 --- a/registry/coder/templates/ssh-linux/main.tf +++ b/registry/coder/templates/ssh-linux/main.tf @@ -211,7 +211,7 @@ provisioner "remote-exec" { } resource "null_resource" "coder_stop" { - count = data.coder_workspace.me.start_count > 0 ? 0 : 1 + count = (try(data.coder_workspace.me.start_count, 1) > 0 ? 0 : 1) connection { type = "ssh" From a5df5b7174d13594f37dfc483fb129608f3bb92b Mon Sep 17 00:00:00 2001 From: Tao Chen Date: Wed, 17 Dec 2025 19:45:20 +0800 Subject: [PATCH 07/11] relocation --- .icons/linux.svg | 438 ++++++++++++++++++ registry/IamTaoChen/.images/avatar.png | Bin 0 -> 55432 bytes registry/IamTaoChen/README.md | 18 + .../IamTaoChen/templates/ssh-linux/README.md | 66 +++ .../templates/ssh-linux/main.tf | 10 + registry/coder/templates/ssh-linux/README.md | 1 - 6 files changed, 532 insertions(+), 1 deletion(-) create mode 100644 .icons/linux.svg create mode 100644 registry/IamTaoChen/.images/avatar.png create mode 100644 registry/IamTaoChen/README.md create mode 100644 registry/IamTaoChen/templates/ssh-linux/README.md rename registry/{coder => IamTaoChen}/templates/ssh-linux/main.tf (97%) delete mode 100644 registry/coder/templates/ssh-linux/README.md diff --git a/.icons/linux.svg b/.icons/linux.svg new file mode 100644 index 000000000..6b558e7b7 --- /dev/null +++ b/.icons/linux.svg @@ -0,0 +1,438 @@ + + + Tux + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/registry/IamTaoChen/.images/avatar.png b/registry/IamTaoChen/.images/avatar.png new file mode 100644 index 0000000000000000000000000000000000000000..f14100c4a7e280c29ea6416127e94e611046d678 GIT binary patch literal 55432 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/debug.log` on the remote host. +- **Agent Not Starting**: Inspect the log file at `~/.coder//coder.log` on the remote host for errors. +- **App Not Appearing**: Ensure the app is selected in parameters and the workspace is restarted if changes are made. +- **Validation Errors**: Parameters like host and port have built-in validations—ensure inputs match the requirements. + +For more advanced customization, refer to the [Coder Terraform provider documentation](https://registry.terraform.io/providers/coder/coder/latest/docs). \ No newline at end of file diff --git a/registry/coder/templates/ssh-linux/main.tf b/registry/IamTaoChen/templates/ssh-linux/main.tf similarity index 97% rename from registry/coder/templates/ssh-linux/main.tf rename to registry/IamTaoChen/templates/ssh-linux/main.tf index 39d37e780..3e7818c31 100644 --- a/registry/coder/templates/ssh-linux/main.tf +++ b/registry/IamTaoChen/templates/ssh-linux/main.tf @@ -4,6 +4,10 @@ terraform { source = "coder/coder" version = ">= 2.4.0" } + random = { + source = "hashicorp/random" + version = ">= 3.6" + } } } @@ -128,6 +132,11 @@ locals { apps_selected = (can(data.coder_parameter.apps.value) && data.coder_parameter.apps.value != "") ? jsondecode(data.coder_parameter.apps.value) : [] } +resource "random_integer" "vs_code_port" { + min = 54000 + max = 55999 +} + resource "coder_agent" "main" { os = "linux" arch = "amd64" @@ -260,5 +269,6 @@ module "vscode-web" { version = "1.4.3" agent_id = coder_agent.main.id folder = local.home_dir + port = random_integer.vs_code_port.result accept_license = true } diff --git a/registry/coder/templates/ssh-linux/README.md b/registry/coder/templates/ssh-linux/README.md deleted file mode 100644 index 25590f2a5..000000000 --- a/registry/coder/templates/ssh-linux/README.md +++ /dev/null @@ -1 +0,0 @@ -# Deploy Coder on existed Linux system \ No newline at end of file From a6483f1d4617bf7cb53c7f7d32bed5a1b9686949 Mon Sep 17 00:00:00 2001 From: Tao Chen Date: Wed, 17 Dec 2025 19:51:31 +0800 Subject: [PATCH 08/11] run 'bun fmt' --- .../IamTaoChen/templates/ssh-linux/README.md | 2 +- .../IamTaoChen/templates/ssh-linux/main.tf | 114 +++++++++--------- 2 files changed, 58 insertions(+), 58 deletions(-) diff --git a/registry/IamTaoChen/templates/ssh-linux/README.md b/registry/IamTaoChen/templates/ssh-linux/README.md index bf2d253ef..888725f04 100644 --- a/registry/IamTaoChen/templates/ssh-linux/README.md +++ b/registry/IamTaoChen/templates/ssh-linux/README.md @@ -63,4 +63,4 @@ The template includes the following configurable parameters: - **App Not Appearing**: Ensure the app is selected in parameters and the workspace is restarted if changes are made. - **Validation Errors**: Parameters like host and port have built-in validations—ensure inputs match the requirements. -For more advanced customization, refer to the [Coder Terraform provider documentation](https://registry.terraform.io/providers/coder/coder/latest/docs). \ No newline at end of file +For more advanced customization, refer to the [Coder Terraform provider documentation](https://registry.terraform.io/providers/coder/coder/latest/docs). diff --git a/registry/IamTaoChen/templates/ssh-linux/main.tf b/registry/IamTaoChen/templates/ssh-linux/main.tf index 3e7818c31..1c2677b4d 100644 --- a/registry/IamTaoChen/templates/ssh-linux/main.tf +++ b/registry/IamTaoChen/templates/ssh-linux/main.tf @@ -27,7 +27,7 @@ data "coder_parameter" "host" { validation { regex = "^[a-zA-Z0-9:.%\\-]+$" error = "Please enter a valid hostname, IPv4, or IPv6 address." -} + } } data "coder_parameter" "username" { @@ -45,10 +45,10 @@ data "coder_parameter" "auth_type" { description = "Authentication method for SSH" type = "string" - form_type = "dropdown" - default = "password" - mutable = true - order = 3 + form_type = "dropdown" + default = "password" + mutable = true + order = 3 option { name = "password" value = "password" @@ -70,7 +70,7 @@ data "coder_parameter" "ssh_password" { styling = jsonencode({ mask_input = true }) - order = 4 + order = 4 } data "coder_parameter" "ssh_key" { @@ -84,7 +84,7 @@ data "coder_parameter" "ssh_key" { styling = jsonencode({ mask_input = true }) - order = 4 + order = 4 } @@ -97,19 +97,19 @@ data "coder_parameter" "port" { mutable = true order = 5 validation { - min = 1 - max = 65535 - error = "Port must be between 1 and 65535" + min = 1 + max = 65535 + error = "Port must be between 1 and 65535" } } data "coder_parameter" "apps" { - name = "apps" - display_name = "Choose any APPs for your workspace." - type = "list(string)" - form_type = "multi-select" - mutable = true - default = jsonencode(["VS Code Desktop"]) + name = "apps" + display_name = "Choose any APPs for your workspace." + type = "list(string)" + form_type = "multi-select" + mutable = true + default = jsonencode(["VS Code Desktop"]) dynamic "option" { for_each = local.apps_candidate content { @@ -128,7 +128,7 @@ locals { use_key = data.coder_parameter.auth_type.value == "ssh_key" ssh_password = local.use_password ? data.coder_parameter.ssh_password[0].value : null ssh_private_key = local.use_key ? data.coder_parameter.ssh_key[0].value : null - apps_candidate = ["VS Code Desktop","VS Code Web", "Cursor"] + apps_candidate = ["VS Code Desktop", "VS Code Web", "Cursor"] apps_selected = (can(data.coder_parameter.apps.value) && data.coder_parameter.apps.value != "") ? jsondecode(data.coder_parameter.apps.value) : [] } @@ -146,7 +146,7 @@ resource "coder_agent" "main" { set -euo pipefail EOT - env = { + env = { GIT_AUTHOR_NAME = coalesce(data.coder_workspace_owner.me.full_name, data.coder_workspace_owner.me.name) GIT_AUTHOR_EMAIL = "${data.coder_workspace_owner.me.email}" GIT_COMMITTER_NAME = coalesce(data.coder_workspace_owner.me.full_name, data.coder_workspace_owner.me.name) @@ -154,11 +154,11 @@ resource "coder_agent" "main" { } display_apps { - port_forwarding_helper = true - vscode = contains(local.apps_selected, "VS Code Desktop") - vscode_insiders = false - web_terminal = true - ssh_helper = true + port_forwarding_helper = true + vscode = contains(local.apps_selected, "VS Code Desktop") + vscode_insiders = false + web_terminal = true + ssh_helper = true } metadata { @@ -186,51 +186,51 @@ resource "coder_agent" "main" { resource "null_resource" "deploy_coder_agent" { count = data.coder_workspace.me.start_count - + triggers = { init_script = sha256(coder_agent.main.init_script) token = coder_agent.main.token } -connection { - type = "ssh" - host = data.coder_parameter.host.value - user = data.coder_parameter.username.value - port = data.coder_parameter.port.value - password = local.ssh_password - private_key = local.ssh_private_key - timeout = "5m" -} + connection { + type = "ssh" + host = data.coder_parameter.host.value + user = data.coder_parameter.username.value + port = data.coder_parameter.port.value + password = local.ssh_password + private_key = local.ssh_private_key + timeout = "5m" + } -provisioner "remote-exec" { - inline = [ - "mkdir -p ${local.coder_cache_dir}", - "coder_sh=${local.coder_cache_dir}/coder.sh", - "log_file=${local.coder_cache_dir}/coder.log", - "cat > $coder_sh << 'EOF'", - "${coder_agent.main.init_script}", - "EOF", - "chmod +x $coder_sh", - "echo \"$(date) : create $coder_sh\" >> ${local.coder_cache_dir}/debug.log", - "nohup env CODER_AGENT_TOKEN='${coder_agent.main.token}' $coder_sh > $log_file 2>&1 &", - "echo $! > ${local.agent_id_file}", - "echo \"$(date) : run $coder_sh and log at $log_file\" >> ${local.coder_cache_dir}/debug.log", - ] - } + provisioner "remote-exec" { + inline = [ + "mkdir -p ${local.coder_cache_dir}", + "coder_sh=${local.coder_cache_dir}/coder.sh", + "log_file=${local.coder_cache_dir}/coder.log", + "cat > $coder_sh << 'EOF'", + "${coder_agent.main.init_script}", + "EOF", + "chmod +x $coder_sh", + "echo \"$(date) : create $coder_sh\" >> ${local.coder_cache_dir}/debug.log", + "nohup env CODER_AGENT_TOKEN='${coder_agent.main.token}' $coder_sh > $log_file 2>&1 &", + "echo $! > ${local.agent_id_file}", + "echo \"$(date) : run $coder_sh and log at $log_file\" >> ${local.coder_cache_dir}/debug.log", + ] + } } resource "null_resource" "coder_stop" { count = (try(data.coder_workspace.me.start_count, 1) > 0 ? 0 : 1) -connection { - type = "ssh" - host = data.coder_parameter.host.value - user = data.coder_parameter.username.value - port = data.coder_parameter.port.value - password = local.ssh_password - private_key = local.ssh_private_key - timeout = "5m" -} + connection { + type = "ssh" + host = data.coder_parameter.host.value + user = data.coder_parameter.username.value + port = data.coder_parameter.port.value + password = local.ssh_password + private_key = local.ssh_private_key + timeout = "5m" + } provisioner "remote-exec" { inline = [ From 4561e43133475393dfc8afbe33e13339dd720968 Mon Sep 17 00:00:00 2001 From: Tao Chen Date: Wed, 17 Dec 2025 19:59:39 +0800 Subject: [PATCH 09/11] fix spell --- registry/IamTaoChen/README.md | 2 +- registry/IamTaoChen/templates/ssh-linux/README.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/registry/IamTaoChen/README.md b/registry/IamTaoChen/README.md index 40f4e8016..ed82ca0d9 100644 --- a/registry/IamTaoChen/README.md +++ b/registry/IamTaoChen/README.md @@ -15,4 +15,4 @@ status: "community" ### ssh-linux -Provision an existing Linux system as a by deploying the Coder agent via SSH with this example template. +Provision an existing Linux system as a workspace by deploying the Coder agent via SSH with this example template. diff --git a/registry/IamTaoChen/templates/ssh-linux/README.md b/registry/IamTaoChen/templates/ssh-linux/README.md index 888725f04..a74826021 100644 --- a/registry/IamTaoChen/templates/ssh-linux/README.md +++ b/registry/IamTaoChen/templates/ssh-linux/README.md @@ -1,6 +1,6 @@ --- display_name: Deploy Coder on existing Linux System -description: Provision an existing Linux system as a by deploying the Coder agent via SSH with this example template. +description: Provision an existing Linux system as a workspace by deploying the Coder agent via SSH with this example template. icon: "../../../../.icons/linux.svg" verified: false tags: ["linux"] @@ -52,7 +52,7 @@ The template includes the following configurable parameters: 1. Create a new workspace in Coder using this template. 2. Fill in the parameters with your Linux system's details. -3. Start the workspace—Coden will connect via SSH and deploy the agent. +3. Start the workspace—Codenr will connect via SSH and deploy the agent. 4. Access the workspace through the Coder dashboard. Selected apps (e.g., VS Code) will be available. 5. On stop, the agent process is terminated and cleaned up. From 025c5444923dccc37e852b8240130ed7f25121e0 Mon Sep 17 00:00:00 2001 From: Tao Chen Date: Wed, 17 Dec 2025 20:03:20 +0800 Subject: [PATCH 10/11] add 'Security Considerations' into README.md --- registry/IamTaoChen/templates/ssh-linux/README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/registry/IamTaoChen/templates/ssh-linux/README.md b/registry/IamTaoChen/templates/ssh-linux/README.md index a74826021..78cb83db1 100644 --- a/registry/IamTaoChen/templates/ssh-linux/README.md +++ b/registry/IamTaoChen/templates/ssh-linux/README.md @@ -36,6 +36,10 @@ This setup does not provision new infrastructure; it remotely deploys and manage The agent is ephemeral by design (started on workspace start, stopped on stop). If you need a persistently running agent, modify the template to remove the stop logic or run the agent manually on the host. +## Security Considerations + +Warning: This template stores SSH credentials (password or private key) in the Terraform state file and passes them as environment variables during deployment. In production environments, this can introduce security risks, as the state file contains sensitive information in plain text and may be accessible if not properly secured. + ## Parameters The template includes the following configurable parameters: From 17497a6e6c9c6e414f67927a68de70a284df07bc Mon Sep 17 00:00:00 2001 From: Tao Chen Date: Wed, 17 Dec 2025 20:18:07 +0800 Subject: [PATCH 11/11] optimize msg --- registry/IamTaoChen/templates/ssh-linux/README.md | 2 +- registry/IamTaoChen/templates/ssh-linux/main.tf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/registry/IamTaoChen/templates/ssh-linux/README.md b/registry/IamTaoChen/templates/ssh-linux/README.md index 78cb83db1..4ec625fbf 100644 --- a/registry/IamTaoChen/templates/ssh-linux/README.md +++ b/registry/IamTaoChen/templates/ssh-linux/README.md @@ -56,7 +56,7 @@ The template includes the following configurable parameters: 1. Create a new workspace in Coder using this template. 2. Fill in the parameters with your Linux system's details. -3. Start the workspace—Codenr will connect via SSH and deploy the agent. +3. Start the workspace—Coder will connect via SSH and deploy the agent. 4. Access the workspace through the Coder dashboard. Selected apps (e.g., VS Code) will be available. 5. On stop, the agent process is terminated and cleaned up. diff --git a/registry/IamTaoChen/templates/ssh-linux/main.tf b/registry/IamTaoChen/templates/ssh-linux/main.tf index 1c2677b4d..90b2b485e 100644 --- a/registry/IamTaoChen/templates/ssh-linux/main.tf +++ b/registry/IamTaoChen/templates/ssh-linux/main.tf @@ -26,7 +26,7 @@ data "coder_parameter" "host" { order = 1 validation { regex = "^[a-zA-Z0-9:.%\\-]+$" - error = "Please enter a valid hostname, IPv4, or IPv6 address." + error = "Please enter a valid hostname, IPv4, or IPv6 address. Examples: example.com, 192.168.1.1, or fe80::1" } }