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. 🧑💻
This commit is contained in:
parent
19f6dc947f
commit
fc66478b94
@ -14,7 +14,7 @@ This module adds JetBrains IDE buttons to launch IDEs directly from the dashboar
|
||||
module "jetbrains" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/jetbrains/coder"
|
||||
version = "1.3.0"
|
||||
version = "1.4.0"
|
||||
agent_id = coder_agent.main.id
|
||||
folder = "/home/coder/project"
|
||||
}
|
||||
@ -39,7 +39,7 @@ When `default` contains IDE codes, those IDEs are created directly without user
|
||||
module "jetbrains" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/jetbrains/coder"
|
||||
version = "1.3.0"
|
||||
version = "1.4.0"
|
||||
agent_id = coder_agent.main.id
|
||||
folder = "/home/coder/project"
|
||||
default = ["PY", "IU"] # Pre-configure PyCharm and IntelliJ IDEA
|
||||
@ -52,7 +52,7 @@ module "jetbrains" {
|
||||
module "jetbrains" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/jetbrains/coder"
|
||||
version = "1.3.0"
|
||||
version = "1.4.0"
|
||||
agent_id = coder_agent.main.id
|
||||
folder = "/home/coder/project"
|
||||
# Show parameter with limited options
|
||||
@ -66,7 +66,7 @@ module "jetbrains" {
|
||||
module "jetbrains" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/jetbrains/coder"
|
||||
version = "1.3.0"
|
||||
version = "1.4.0"
|
||||
agent_id = coder_agent.main.id
|
||||
folder = "/home/coder/project"
|
||||
default = ["IU", "PY"]
|
||||
@ -81,7 +81,7 @@ module "jetbrains" {
|
||||
module "jetbrains" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/jetbrains/coder"
|
||||
version = "1.3.0"
|
||||
version = "1.4.0"
|
||||
agent_id = coder_agent.main.id
|
||||
folder = "/workspace/project"
|
||||
|
||||
@ -108,7 +108,7 @@ module "jetbrains" {
|
||||
module "jetbrains_pycharm" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/jetbrains/coder"
|
||||
version = "1.3.0"
|
||||
version = "1.4.0"
|
||||
agent_id = coder_agent.main.id
|
||||
folder = "/workspace/project"
|
||||
|
||||
@ -128,7 +128,7 @@ Add helpful tooltip text that appears when users hover over the IDE app buttons:
|
||||
module "jetbrains" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/jetbrains/coder"
|
||||
version = "1.3.0"
|
||||
version = "1.4.0"
|
||||
agent_id = coder_agent.main.id
|
||||
folder = "/home/coder/project"
|
||||
default = ["IU", "PY"]
|
||||
|
||||
@ -125,7 +125,7 @@ variable "download_base_link" {
|
||||
}
|
||||
|
||||
data "http" "jetbrains_ide_versions" {
|
||||
for_each = length(var.default) == 0 ? var.options : var.default
|
||||
for_each = local.selected_ides
|
||||
url = "${var.releases_base_link}/products/releases?code=${each.key}&type=${var.channel}${var.major_version == "latest" ? "&latest=true" : ""}"
|
||||
}
|
||||
|
||||
@ -174,9 +174,14 @@ variable "ide_config" {
|
||||
}
|
||||
|
||||
locals {
|
||||
# Determine the user's actual IDE selection.
|
||||
# This is computed before the HTTP data source so that version lookups
|
||||
# are only performed for IDEs the user chose — not every option.
|
||||
selected_ides = length(var.default) == 0 ? toset(jsondecode(coalesce(data.coder_parameter.jetbrains_ides[0].value, "[]"))) : toset(var.default)
|
||||
|
||||
# Parse HTTP responses once with error handling for air-gapped environments
|
||||
parsed_responses = {
|
||||
for code in length(var.default) == 0 ? var.options : var.default : code => try(
|
||||
for code in local.selected_ides : code => try(
|
||||
jsondecode(data.http.jetbrains_ide_versions[code].response_body),
|
||||
{} # Return empty object if API call fails
|
||||
)
|
||||
@ -184,7 +189,7 @@ locals {
|
||||
|
||||
# Filter the parsed response for the requested major version if not "latest"
|
||||
filtered_releases = {
|
||||
for code in length(var.default) == 0 ? var.options : var.default : code => [
|
||||
for code in local.selected_ides : code => [
|
||||
for r in try(local.parsed_responses[code][keys(local.parsed_responses[code])[0]], []) :
|
||||
r if var.major_version == "latest" || r.majorVersion == var.major_version
|
||||
]
|
||||
@ -192,13 +197,13 @@ locals {
|
||||
|
||||
# Select the latest release for the requested major version (first item in the filtered list)
|
||||
selected_releases = {
|
||||
for code in length(var.default) == 0 ? var.options : var.default : code =>
|
||||
for code in local.selected_ides : code =>
|
||||
length(local.filtered_releases[code]) > 0 ? local.filtered_releases[code][0] : null
|
||||
}
|
||||
|
||||
# Dynamically generate IDE configurations based on options with fallback to ide_config
|
||||
# Dynamically generate IDE configurations based on selected IDEs with fallback to ide_config
|
||||
options_metadata = {
|
||||
for code in length(var.default) == 0 ? var.options : var.default : code => {
|
||||
for code in local.selected_ides : code => {
|
||||
icon = var.ide_config[code].icon
|
||||
name = var.ide_config[code].name
|
||||
identifier = code
|
||||
@ -211,9 +216,6 @@ locals {
|
||||
json_data = local.selected_releases[code]
|
||||
}
|
||||
}
|
||||
|
||||
# Convert the parameter value to a set for for_each
|
||||
selected_ides = length(var.default) == 0 ? toset(jsondecode(coalesce(data.coder_parameter.jetbrains_ides[0].value, "[]"))) : toset(var.default)
|
||||
}
|
||||
|
||||
data "coder_parameter" "jetbrains_ides" {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user