Files
coder/examples/templates/quickstart/main.tf
T
dependabot[bot] 88d9ce57e1 chore: bump the coder-modules group across 6 directories with 2 updates (#26031)
Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-03 18:56:19 +00:00

451 lines
11 KiB
Terraform

terraform {
required_providers {
coder = {
source = "coder/coder"
}
docker = {
source = "kreuzwerker/docker"
}
external = {
source = "hashicorp/external"
}
}
}
variable "docker_socket" {
default = ""
description = "(Optional) Docker socket URI"
type = string
}
provider "docker" {
host = var.docker_socket != "" ? var.docker_socket : null
}
data "coder_provisioner" "me" {}
data "coder_workspace" "me" {}
data "coder_workspace_owner" "me" {}
# --- Parameters ---
data "coder_parameter" "languages" {
name = "languages"
display_name = "Programming Languages"
description = "Select the languages to pre-install in your workspace"
type = "list(string)"
form_type = "multi-select"
default = jsonencode(["python"])
mutable = true
icon = "/icon/code.svg"
order = 1
option {
name = "Python"
value = "python"
icon = "/icon/python.svg"
}
option {
name = "Node.js"
value = "nodejs"
icon = "/icon/nodejs.svg"
}
option {
name = "Go"
value = "go"
icon = "/icon/go.svg"
}
option {
name = "Rust"
value = "rust"
icon = "/icon/rust.svg"
}
option {
name = "Java"
value = "java"
icon = "/icon/java.svg"
}
option {
name = "C/C++"
value = "cpp"
icon = "/icon/cpp.svg"
}
}
data "coder_parameter" "ides" {
name = "ides"
display_name = "IDEs & Editors"
description = "Select the development environments for your workspace"
type = "list(string)"
form_type = "multi-select"
default = jsonencode(["code-server"])
mutable = true
icon = "/icon/code.svg"
order = 2
option {
name = "VS Code (Browser)"
value = "code-server"
icon = "/icon/code.svg"
}
option {
name = "VS Code Desktop"
value = "vscode-desktop"
icon = "/icon/code.svg"
}
option {
name = "Cursor"
value = "cursor"
icon = "/icon/cursor.svg"
}
option {
name = "JetBrains IDEs"
value = "jetbrains"
icon = "/icon/jetbrains.svg"
}
option {
name = "Zed"
value = "zed"
icon = "/icon/zed.svg"
}
option {
name = "Windsurf"
value = "windsurf"
icon = "/icon/windsurf.svg"
}
}
# Shown only when "JetBrains IDEs" is selected in the IDEs parameter.
# Pre-selects IDEs that match the chosen languages.
data "coder_parameter" "jetbrains_ides" {
count = contains(local.ides, "jetbrains") ? 1 : 0
name = "jetbrains_ides"
display_name = "JetBrains IDEs"
description = "Select the JetBrains IDEs to install"
type = "list(string)"
form_type = "multi-select"
default = jsonencode(local.jetbrains_ides_from_languages)
mutable = true
icon = "/icon/jetbrains.svg"
order = 3
option {
name = "IntelliJ IDEA"
value = "IU"
icon = "/icon/intellij.svg"
}
option {
name = "PyCharm"
value = "PY"
icon = "/icon/pycharm.svg"
}
option {
name = "GoLand"
value = "GO"
icon = "/icon/goland.svg"
}
option {
name = "WebStorm"
value = "WS"
icon = "/icon/webstorm.svg"
}
option {
name = "RustRover"
value = "RR"
icon = "/icon/rustrover.svg"
}
option {
name = "CLion"
value = "CL"
icon = "/icon/clion.svg"
}
option {
name = "PhpStorm"
value = "PS"
icon = "/icon/phpstorm.svg"
}
option {
name = "RubyMine"
value = "RM"
icon = "/icon/rubymine.svg"
}
option {
name = "Rider"
value = "RD"
icon = "/icon/rider.svg"
}
}
data "coder_parameter" "git_repo" {
name = "git_repo"
display_name = "Git Repository (Optional)"
description = "URL of a Git repository to clone into your workspace (leave empty to skip)"
type = "string"
default = ""
mutable = true
icon = "/icon/git.svg"
order = 4
}
# --- Locals ---
locals {
username = data.coder_workspace_owner.me.name
languages = jsondecode(data.coder_parameter.languages.value)
ides = jsondecode(data.coder_parameter.ides.value)
# Map selected languages to the relevant JetBrains IDE product codes.
# Used as the default for the JetBrains IDE selector parameter.
jetbrains_by_language = {
python = ["PY"]
go = ["GO"]
java = ["IU"]
nodejs = ["WS"]
rust = ["RR"]
cpp = ["CL"]
}
jetbrains_ides_from_languages = distinct(flatten([
for lang in local.languages : lookup(local.jetbrains_by_language, lang, [])
]))
# The actual JetBrains IDEs to install, from the user's selection
# in the conditional JetBrains parameter (or empty if not shown).
jetbrains_selected = contains(local.ides, "jetbrains") ? jsondecode(data.coder_parameter.jetbrains_ides[0].value) : []
}
# --- Agent ---
resource "coder_agent" "main" {
arch = data.coder_provisioner.me.arch
os = "linux"
startup_script = <<-EOT
set -e
if [ ! -f ~/.init_done ]; then
cp -rT /etc/skel ~
touch ~/.init_done
fi
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}"
}
metadata {
display_name = "CPU Usage"
key = "0_cpu_usage"
script = "coder stat cpu"
interval = 10
timeout = 1
}
metadata {
display_name = "RAM Usage"
key = "1_ram_usage"
script = "coder stat mem"
interval = 10
timeout = 1
}
metadata {
display_name = "Home Disk"
key = "3_home_disk"
script = "coder stat disk --path $${HOME}"
interval = 60
timeout = 1
}
}
# --- Language installation ---
# All languages install in a single script to avoid apt-get lock
# conflicts (coder_script resources run in parallel).
resource "coder_script" "install_languages" {
count = length(local.languages) > 0 ? 1 : 0
agent_id = coder_agent.main.id
display_name = "Install Languages"
icon = "/icon/code.svg"
run_on_start = true
start_blocks_login = true
script = templatefile("${path.module}/install-languages.sh.tftpl", {
LANGUAGES = join(",", local.languages)
})
}
# --- IDE modules ---
module "code-server" {
count = data.coder_workspace.me.start_count * (contains(local.ides, "code-server") ? 1 : 0)
source = "registry.coder.com/coder/code-server/coder"
version = "~> 1.0"
agent_id = coder_agent.main.id
order = 1
}
module "vscode-desktop" {
count = data.coder_workspace.me.start_count * (contains(local.ides, "vscode-desktop") ? 1 : 0)
source = "registry.coder.com/coder/vscode-desktop/coder"
version = "~> 1.0"
agent_id = coder_agent.main.id
folder = "/home/coder"
order = 2
}
module "cursor" {
count = data.coder_workspace.me.start_count * (contains(local.ides, "cursor") ? 1 : 0)
source = "registry.coder.com/coder/cursor/coder"
version = "~> 1.0"
agent_id = coder_agent.main.id
folder = "/home/coder"
order = 3
}
# TODO: Re-add the coder/jetbrains module once Coder's dynamic
# parameter system respects module count for parameter visibility.
# The module's internal coder_parameter appears even when count = 0,
# creating a ghost parameter in the workspace creation form.
# module "jetbrains" {
# count = data.coder_workspace.me.start_count * (contains(local.ides, "jetbrains") && length(local.jetbrains_selected) > 0 ? 1 : 0)
# source = "registry.coder.com/coder/jetbrains/coder"
# version = "~> 1.0"
# agent_id = coder_agent.main.id
# folder = "/home/coder"
# default = toset(local.jetbrains_selected)
# }
module "zed" {
count = data.coder_workspace.me.start_count * (contains(local.ides, "zed") ? 1 : 0)
source = "registry.coder.com/coder/zed/coder"
version = "~> 1.0"
agent_id = coder_agent.main.id
folder = "/home/coder"
order = 5
}
module "windsurf" {
count = data.coder_workspace.me.start_count * (contains(local.ides, "windsurf") ? 1 : 0)
source = "registry.coder.com/coder/windsurf/coder"
version = "~> 1.0"
agent_id = coder_agent.main.id
folder = "/home/coder"
order = 6
}
# --- Git clone ---
module "git-clone" {
count = data.coder_workspace.me.start_count * (data.coder_parameter.git_repo.value != "" ? 1 : 0)
source = "registry.coder.com/coder/git-clone/coder"
version = "~> 2.0"
agent_id = coder_agent.main.id
url = data.coder_parameter.git_repo.value
}
# --- Presets ---
data "coder_workspace_preset" "web_dev" {
name = "Web Development"
icon = "/icon/nodejs.svg"
parameters = {
languages = jsonencode(["python", "nodejs"])
ides = jsonencode(["code-server"])
git_repo = ""
}
}
data "coder_workspace_preset" "backend_go" {
name = "Backend (Go)"
icon = "/icon/go.svg"
parameters = {
languages = jsonencode(["go"])
ides = jsonencode(["code-server", "jetbrains"])
jetbrains_ides = jsonencode(["GO"])
git_repo = ""
}
}
data "coder_workspace_preset" "data_science" {
name = "Data Science"
icon = "/icon/python.svg"
parameters = {
languages = jsonencode(["python"])
ides = jsonencode(["code-server"])
git_repo = ""
}
}
data "coder_workspace_preset" "full_stack" {
name = "Full Stack"
icon = "/icon/code.svg"
parameters = {
languages = jsonencode(["python", "nodejs", "go"])
ides = jsonencode(["code-server", "cursor"])
git_repo = ""
}
}
# --- Docker resources ---
resource "docker_volume" "home_volume" {
name = "coder-${data.coder_workspace.me.id}-home"
lifecycle {
ignore_changes = all
}
labels {
label = "coder.owner"
value = data.coder_workspace_owner.me.name
}
labels {
label = "coder.owner_id"
value = data.coder_workspace_owner.me.id
}
labels {
label = "coder.workspace_id"
value = data.coder_workspace.me.id
}
labels {
label = "coder.workspace_name_at_creation"
value = data.coder_workspace.me.name
}
depends_on = []
}
resource "docker_container" "workspace" {
count = data.coder_workspace.me.start_count
image = "codercom/enterprise-base:ubuntu"
name = "coder-${data.coder_workspace_owner.me.name}-${lower(data.coder_workspace.me.name)}"
hostname = data.coder_workspace.me.name
entrypoint = [
"sh", "-c",
replace(coder_agent.main.init_script, "/localhost|127\\.0\\.0\\.1/", "host.docker.internal"),
]
env = ["CODER_AGENT_TOKEN=${coder_agent.main.token}"]
host {
host = "host.docker.internal"
ip = "host-gateway"
}
volumes {
container_path = "/home/coder"
volume_name = docker_volume.home_volume.name
read_only = false
}
labels {
label = "coder.owner"
value = data.coder_workspace_owner.me.name
}
labels {
label = "coder.owner_id"
value = data.coder_workspace_owner.me.id
}
labels {
label = "coder.workspace_id"
value = data.coder_workspace.me.id
}
labels {
label = "coder.workspace_name"
value = data.coder_workspace.me.name
}
depends_on = []
}