Skip to content

Commit fc66478

Browse files
authored
fix(jetbrains): scope HTTP version fetch to selected IDEs only (#822)
## Problem The `data "http" "jetbrains_ide_versions"` resource fetches release info from `data.services.jetbrains.com` for **all configured IDE options** at plan time, regardless of what the user actually selected. When the API is unreachable (air-gapped environments, DNS failures, transient outages), this causes a fatal Terraform error that blocks the workspace build — even when no JetBrains IDEs were selected. ## Fix Changed the `for_each` on the HTTP data source (and all dependent locals) from iterating over `var.options`/`var.default` to `local.selected_ides` — the user's actual selection. | Scenario | Before | After | |---|---|---| | No IDEs selected (`[]`) | 9 HTTP requests | 0 HTTP requests | | 1 IDE selected (`["GO"]`) | 9 HTTP requests | 1 HTTP request | | All IDEs selected | 9 HTTP requests | 9 HTTP requests | ## Validation - All 17 existing `terraform test` cases pass - Tested end-to-end on [dev.coder.com](https://dev.coder.com) with Docker template: - `jetbrains_ides=[]` — zero HTTP requests, build succeeds - `jetbrains_ides=["GO"]` — single HTTP request for GoLand only, `coder_app.jetbrains["GO"]` created Closes #821 > 🤖 This PR was created with the help of Coder Agents, and needs a human review. 🧑💻
1 parent 19f6dc9 commit fc66478

2 files changed

Lines changed: 18 additions & 16 deletions

File tree

registry/coder/modules/jetbrains/README.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ This module adds JetBrains IDE buttons to launch IDEs directly from the dashboar
1414
module "jetbrains" {
1515
count = data.coder_workspace.me.start_count
1616
source = "registry.coder.com/coder/jetbrains/coder"
17-
version = "1.3.0"
17+
version = "1.4.0"
1818
agent_id = coder_agent.main.id
1919
folder = "/home/coder/project"
2020
}
@@ -39,7 +39,7 @@ When `default` contains IDE codes, those IDEs are created directly without user
3939
module "jetbrains" {
4040
count = data.coder_workspace.me.start_count
4141
source = "registry.coder.com/coder/jetbrains/coder"
42-
version = "1.3.0"
42+
version = "1.4.0"
4343
agent_id = coder_agent.main.id
4444
folder = "/home/coder/project"
4545
default = ["PY", "IU"] # Pre-configure PyCharm and IntelliJ IDEA
@@ -52,7 +52,7 @@ module "jetbrains" {
5252
module "jetbrains" {
5353
count = data.coder_workspace.me.start_count
5454
source = "registry.coder.com/coder/jetbrains/coder"
55-
version = "1.3.0"
55+
version = "1.4.0"
5656
agent_id = coder_agent.main.id
5757
folder = "/home/coder/project"
5858
# Show parameter with limited options
@@ -66,7 +66,7 @@ module "jetbrains" {
6666
module "jetbrains" {
6767
count = data.coder_workspace.me.start_count
6868
source = "registry.coder.com/coder/jetbrains/coder"
69-
version = "1.3.0"
69+
version = "1.4.0"
7070
agent_id = coder_agent.main.id
7171
folder = "/home/coder/project"
7272
default = ["IU", "PY"]
@@ -81,7 +81,7 @@ module "jetbrains" {
8181
module "jetbrains" {
8282
count = data.coder_workspace.me.start_count
8383
source = "registry.coder.com/coder/jetbrains/coder"
84-
version = "1.3.0"
84+
version = "1.4.0"
8585
agent_id = coder_agent.main.id
8686
folder = "/workspace/project"
8787
@@ -108,7 +108,7 @@ module "jetbrains" {
108108
module "jetbrains_pycharm" {
109109
count = data.coder_workspace.me.start_count
110110
source = "registry.coder.com/coder/jetbrains/coder"
111-
version = "1.3.0"
111+
version = "1.4.0"
112112
agent_id = coder_agent.main.id
113113
folder = "/workspace/project"
114114
@@ -128,7 +128,7 @@ Add helpful tooltip text that appears when users hover over the IDE app buttons:
128128
module "jetbrains" {
129129
count = data.coder_workspace.me.start_count
130130
source = "registry.coder.com/coder/jetbrains/coder"
131-
version = "1.3.0"
131+
version = "1.4.0"
132132
agent_id = coder_agent.main.id
133133
folder = "/home/coder/project"
134134
default = ["IU", "PY"]

registry/coder/modules/jetbrains/main.tf

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ variable "download_base_link" {
125125
}
126126

127127
data "http" "jetbrains_ide_versions" {
128-
for_each = length(var.default) == 0 ? var.options : var.default
128+
for_each = local.selected_ides
129129
url = "${var.releases_base_link}/products/releases?code=${each.key}&type=${var.channel}${var.major_version == "latest" ? "&latest=true" : ""}"
130130
}
131131

@@ -174,31 +174,36 @@ variable "ide_config" {
174174
}
175175

176176
locals {
177+
# Determine the user's actual IDE selection.
178+
# This is computed before the HTTP data source so that version lookups
179+
# are only performed for IDEs the user chose — not every option.
180+
selected_ides = length(var.default) == 0 ? toset(jsondecode(coalesce(data.coder_parameter.jetbrains_ides[0].value, "[]"))) : toset(var.default)
181+
177182
# Parse HTTP responses once with error handling for air-gapped environments
178183
parsed_responses = {
179-
for code in length(var.default) == 0 ? var.options : var.default : code => try(
184+
for code in local.selected_ides : code => try(
180185
jsondecode(data.http.jetbrains_ide_versions[code].response_body),
181186
{} # Return empty object if API call fails
182187
)
183188
}
184189

185190
# Filter the parsed response for the requested major version if not "latest"
186191
filtered_releases = {
187-
for code in length(var.default) == 0 ? var.options : var.default : code => [
192+
for code in local.selected_ides : code => [
188193
for r in try(local.parsed_responses[code][keys(local.parsed_responses[code])[0]], []) :
189194
r if var.major_version == "latest" || r.majorVersion == var.major_version
190195
]
191196
}
192197

193198
# Select the latest release for the requested major version (first item in the filtered list)
194199
selected_releases = {
195-
for code in length(var.default) == 0 ? var.options : var.default : code =>
200+
for code in local.selected_ides : code =>
196201
length(local.filtered_releases[code]) > 0 ? local.filtered_releases[code][0] : null
197202
}
198203

199-
# Dynamically generate IDE configurations based on options with fallback to ide_config
204+
# Dynamically generate IDE configurations based on selected IDEs with fallback to ide_config
200205
options_metadata = {
201-
for code in length(var.default) == 0 ? var.options : var.default : code => {
206+
for code in local.selected_ides : code => {
202207
icon = var.ide_config[code].icon
203208
name = var.ide_config[code].name
204209
identifier = code
@@ -211,9 +216,6 @@ locals {
211216
json_data = local.selected_releases[code]
212217
}
213218
}
214-
215-
# Convert the parameter value to a set for for_each
216-
selected_ides = length(var.default) == 0 ? toset(jsondecode(coalesce(data.coder_parameter.jetbrains_ides[0].value, "[]"))) : toset(var.default)
217219
}
218220

219221
data "coder_parameter" "jetbrains_ides" {

0 commit comments

Comments
 (0)