|
| 1 | +terraform { |
| 2 | + required_providers { |
| 3 | + coder = { |
| 4 | + source = "coder/coder" |
| 5 | + } |
| 6 | + docker = { |
| 7 | + source = "kreuzwerker/docker" |
| 8 | + version = "~> 3.0.0" |
| 9 | + } |
| 10 | + envbuilder = { |
| 11 | + source = "coder/envbuilder" |
| 12 | + } |
| 13 | + } |
| 14 | +} |
| 15 | + |
| 16 | +variable "jetbrains_ides" { |
| 17 | + type = list(string) |
| 18 | + description = "The list of IDE product codes." |
| 19 | + default = ["IU", "PS", "WS", "PY", "CL", "GO", "RM", "RD", "RR"] |
| 20 | + validation { |
| 21 | + condition = ( |
| 22 | + alltrue([ |
| 23 | + for code in var.jetbrains_ides : contains(["IU", "PS", "WS", "PY", "CL", "GO", "RM", "RD", "RR"], code) |
| 24 | + ]) |
| 25 | + ) |
| 26 | + error_message = "The jetbrains_ides must be a list of valid product codes. Valid product codes are ${join(",", ["IU", "PS", "WS", "PY", "CL", "GO", "RM", "RD", "RR"])}." |
| 27 | + } |
| 28 | + # check if the list is empty |
| 29 | + validation { |
| 30 | + condition = length(var.jetbrains_ides) > 0 |
| 31 | + error_message = "The jetbrains_ides must not be empty." |
| 32 | + } |
| 33 | + # check if the list contains duplicates |
| 34 | + validation { |
| 35 | + condition = length(var.jetbrains_ides) == length(toset(var.jetbrains_ides)) |
| 36 | + error_message = "The jetbrains_ides must not contain duplicates." |
| 37 | + } |
| 38 | +} |
| 39 | + |
| 40 | +variable "releases_base_link" { |
| 41 | + type = string |
| 42 | + description = "" |
| 43 | + default = "https://data.services.jetbrains.com" |
| 44 | + validation { |
| 45 | + condition = can(regex("^https?://.+$", var.releases_base_link)) |
| 46 | + error_message = "The releases_base_link must be a valid HTTP/S address." |
| 47 | + } |
| 48 | +} |
| 49 | + |
| 50 | +variable "channel" { |
| 51 | + type = string |
| 52 | + description = "JetBrains IDE release channel. Valid values are release and eap." |
| 53 | + default = "release" |
| 54 | + validation { |
| 55 | + condition = can(regex("^(release|eap)$", var.channel)) |
| 56 | + error_message = "The channel must be either release or eap." |
| 57 | + } |
| 58 | +} |
| 59 | + |
| 60 | + |
| 61 | +data "http" "jetbrains_ide_versions" { |
| 62 | + for_each = toset(var.jetbrains_ides) |
| 63 | + url = "${var.releases_base_link}/products/releases?code=${each.key}&latest=true&type=${var.channel}" |
| 64 | +} |
| 65 | + |
| 66 | +variable "download_base_link" { |
| 67 | + type = string |
| 68 | + description = "" |
| 69 | + default = "https://download.jetbrains.com" |
| 70 | + validation { |
| 71 | + condition = can(regex("^https?://.+$", var.download_base_link)) |
| 72 | + error_message = "The download_base_link must be a valid HTTP/S address." |
| 73 | + } |
| 74 | +} |
| 75 | + |
| 76 | +variable "arch" { |
| 77 | + type = string |
| 78 | + description = "The target architecture of the workspace" |
| 79 | + default = "amd64" |
| 80 | + validation { |
| 81 | + condition = contains(["amd64", "arm64"], var.arch) |
| 82 | + error_message = "Architecture must be either 'amd64' or 'arm64'." |
| 83 | + } |
| 84 | +} |
| 85 | + |
| 86 | +variable "jetbrains_ide_versions" { |
| 87 | + type = map(object({ |
| 88 | + build_number = string |
| 89 | + version = string |
| 90 | + })) |
| 91 | + description = "The set of versions for each jetbrains IDE" |
| 92 | + default = { |
| 93 | + "IU" = { |
| 94 | + build_number = "243.21565.193" |
| 95 | + version = "2024.3" |
| 96 | + } |
| 97 | + "PS" = { |
| 98 | + build_number = "243.21565.202" |
| 99 | + version = "2024.3" |
| 100 | + } |
| 101 | + "WS" = { |
| 102 | + build_number = "243.21565.180" |
| 103 | + version = "2024.3" |
| 104 | + } |
| 105 | + "PY" = { |
| 106 | + build_number = "243.21565.199" |
| 107 | + version = "2024.3" |
| 108 | + } |
| 109 | + "CL" = { |
| 110 | + build_number = "243.21565.238" |
| 111 | + version = "2024.1" |
| 112 | + } |
| 113 | + "GO" = { |
| 114 | + build_number = "243.21565.208" |
| 115 | + version = "2024.3" |
| 116 | + } |
| 117 | + "RM" = { |
| 118 | + build_number = "243.21565.197" |
| 119 | + version = "2024.3" |
| 120 | + } |
| 121 | + "RD" = { |
| 122 | + build_number = "243.21565.191" |
| 123 | + version = "2024.3" |
| 124 | + } |
| 125 | + "RR" = { |
| 126 | + build_number = "243.22562.230" |
| 127 | + version = "2024.3" |
| 128 | + } |
| 129 | + } |
| 130 | + validation { |
| 131 | + condition = ( |
| 132 | + alltrue([ |
| 133 | + for code in keys(var.jetbrains_ide_versions) : contains(["IU", "PS", "WS", "PY", "CL", "GO", "RM", "RD", "RR"], code) |
| 134 | + ]) |
| 135 | + ) |
| 136 | + error_message = "The jetbrains_ide_versions must contain a map of valid product codes. Valid product codes are ${join(",", ["IU", "PS", "WS", "PY", "CL", "GO", "RM", "RD", "RR"])}." |
| 137 | + } |
| 138 | +} |
| 139 | + |
| 140 | +locals { |
| 141 | + # AMD64 versions of the images just use the version string, while ARM64 |
| 142 | + # versions append "-aarch64". Eg: |
| 143 | + # |
| 144 | + # https://download.jetbrains.com/idea/ideaIU-2025.1.tar.gz |
| 145 | + # https://download.jetbrains.com/idea/ideaIU-2025.1.tar.gz |
| 146 | + # |
| 147 | + # We rewrite the data map above dynamically based on the user's architecture parameter. |
| 148 | + # |
| 149 | + effective_jetbrains_ide_versions = { |
| 150 | + for k, v in var.jetbrains_ide_versions : k => { |
| 151 | + build_number = v.build_number |
| 152 | + version = var.arch == "arm64" ? "${v.version}-aarch64" : v.version |
| 153 | + } |
| 154 | + } |
| 155 | + |
| 156 | + # When downloading the latest IDE, the download link in the JSON is either: |
| 157 | + # |
| 158 | + # linux.download_link |
| 159 | + # linuxARM64.download_link |
| 160 | + # |
| 161 | + download_key = var.arch == "arm64" ? "linuxARM64" : "linux" |
| 162 | + |
| 163 | + jetbrains_ides = { |
| 164 | + "GO" = { |
| 165 | + icon = "/icon/goland.svg", |
| 166 | + name = "GoLand", |
| 167 | + identifier = "GO", |
| 168 | + version = local.effective_jetbrains_ide_versions["GO"].version |
| 169 | + }, |
| 170 | + "WS" = { |
| 171 | + icon = "/icon/webstorm.svg", |
| 172 | + name = "WebStorm", |
| 173 | + identifier = "WS", |
| 174 | + version = local.effective_jetbrains_ide_versions["WS"].version |
| 175 | + }, |
| 176 | + "IU" = { |
| 177 | + icon = "/icon/intellij.svg", |
| 178 | + name = "IntelliJ IDEA Ultimate", |
| 179 | + identifier = "IU", |
| 180 | + version = local.effective_jetbrains_ide_versions["IU"].version |
| 181 | + }, |
| 182 | + "PY" = { |
| 183 | + icon = "/icon/pycharm.svg", |
| 184 | + name = "PyCharm Professional", |
| 185 | + identifier = "PY", |
| 186 | + version = local.effective_jetbrains_ide_versions["PY"].version |
| 187 | + }, |
| 188 | + "CL" = { |
| 189 | + icon = "/icon/clion.svg", |
| 190 | + name = "CLion", |
| 191 | + identifier = "CL", |
| 192 | + version = local.effective_jetbrains_ide_versions["CL"].version |
| 193 | + }, |
| 194 | + "PS" = { |
| 195 | + icon = "/icon/phpstorm.svg", |
| 196 | + name = "PhpStorm", |
| 197 | + identifier = "PS", |
| 198 | + version = local.effective_jetbrains_ide_versions["PS"].version |
| 199 | + }, |
| 200 | + "RM" = { |
| 201 | + icon = "/icon/rubymine.svg", |
| 202 | + name = "RubyMine", |
| 203 | + identifier = "RM", |
| 204 | + version = local.effective_jetbrains_ide_versions["RM"].version |
| 205 | + }, |
| 206 | + "RD" = { |
| 207 | + icon = "/icon/rider.svg", |
| 208 | + name = "Rider", |
| 209 | + identifier = "RD", |
| 210 | + version = local.effective_jetbrains_ide_versions["RD"].version |
| 211 | + }, |
| 212 | + "RR" = { |
| 213 | + icon = "/icon/rustrover.svg", |
| 214 | + name = "RustRover", |
| 215 | + identifier = "RR", |
| 216 | + version = local.effective_jetbrains_ide_versions["RR"].version |
| 217 | + } |
| 218 | + } |
| 219 | +} |
| 220 | +data "coder_parameter" "jetbrains_ide" { |
| 221 | + type = "string" |
| 222 | + name = "jetbrains_ide" |
| 223 | + display_name = "JetBrains IDE" |
| 224 | + icon = "/icon/gateway.svg" |
| 225 | + mutable = true |
| 226 | + default = var.jetbrains_ides[0] |
| 227 | + |
| 228 | + dynamic "option" { |
| 229 | + for_each = var.jetbrains_ides |
| 230 | + content { |
| 231 | + icon = local.jetbrains_ides[option.value].icon |
| 232 | + name = "${local.jetbrains_ides[option.value].name} ${local.jetbrains_ides[option.value].version}" |
| 233 | + value = option.value |
| 234 | + } |
| 235 | + } |
| 236 | +} |
0 commit comments