Fixes#835
## Problem
The `data "http"` resource always fires for every selected IDE, even
when the user has pinned versions via `ide_config`. In air-gapped or
caching scenarios, this causes:
- **30-second hangs** when `releases_base_link` is set to a dummy URL
like `https://localhost`
- **Fatal errors** with `https://localhost:1` (connection refused)
- The documented "air-gapped fallback" via `try()` never actually worked
— the `http` data source fails before `try()` can catch anything
## Fix
When `ide_config` is provided, the module now skips all HTTP calls and
uses the pinned build numbers directly.
| Scenario | `ide_config` | HTTP calls | Build source | On API failure |
|---|---|---|---|---|
| User wants latest | `null` (default) | Yes | JetBrains API | Terraform
error (fail loudly) |
| User pins versions | Set | **None** | `ide_config.build` | N/A |
### Changes
- `ide_config` default changed from a full map to `null`
- `name` and `icon` are now `optional(string)` in `ide_config` — falls
back to built-in metadata
- `data.http.jetbrains_ide_versions` `for_each` is empty when
`ide_config` is set
- Static `ide_metadata` local provides name/icon when `ide_config` is
null
- Removed `try()` fallback from `parsed_responses` — API errors are now
explicit instead of silently using stale builds
- Cross-variable validation rejects `major_version`, `channel`, and
`releases_base_link` when `ide_config` is set
- Validation for `ide_config ⊇ default` added (previously only
`ide_config ⊇ options` was checked)
- Version bumped `1.3.1` → `1.4.0`
### Usage
```tf
module "jetbrains" {
source = "registry.coder.com/coder/jetbrains/coder"
version = "1.4.0"
agent_id = coder_agent.main.id
folder = "/home/coder/project"
# Zero HTTP calls — only build is required.
ide_config = {
"GO" = { build = "261.22158.291" }
"PY" = { build = "261.22158.340" }
}
options = ["GO", "PY"]
}
```
> 🤖 This PR was created with the help of Coder Agents, and needs a human
review. 🧑💻