mirror of
https://github.com/coder/coder.git
synced 2026-11-06 08:12:45 +08:00
This PR changes template names and docs to follow the `<provider>-<os/whatever>` format for all templates. I've decided not to split this into multiple PRs because I'd have to edit rebase the other PRs once one of them gets merged, this should be relatively low-impact anyways. This aligns with our goals to make templates more user-friendly. Closes #15754
330 lines
8.2 KiB
Terraform
330 lines
8.2 KiB
Terraform
terraform {
|
|
required_providers {
|
|
coder = {
|
|
source = "coder/coder"
|
|
}
|
|
digitalocean = {
|
|
source = "digitalocean/digitalocean"
|
|
}
|
|
}
|
|
}
|
|
|
|
provider "coder" {
|
|
}
|
|
|
|
variable "step1_do_project_id" {
|
|
type = string
|
|
description = <<-EOF
|
|
Enter project ID
|
|
|
|
$ doctl projects list
|
|
EOF
|
|
sensitive = true
|
|
|
|
validation {
|
|
# make sure length of alphanumeric string is 36
|
|
condition = length(var.step1_do_project_id) == 36
|
|
error_message = "Invalid Digital Ocean Project ID."
|
|
}
|
|
|
|
}
|
|
|
|
variable "step2_do_admin_ssh_key" {
|
|
type = number
|
|
description = <<-EOF
|
|
Enter admin SSH key ID (some Droplet images require an SSH key to be set):
|
|
|
|
Can be set to "0" for no key.
|
|
|
|
Note: Setting this to zero will break Fedora images and notify root passwords via email.
|
|
|
|
$ doctl compute ssh-key list
|
|
EOF
|
|
sensitive = true
|
|
|
|
validation {
|
|
condition = var.step2_do_admin_ssh_key >= 0
|
|
error_message = "Invalid Digital Ocean SSH key ID, a number is required."
|
|
}
|
|
}
|
|
|
|
data "coder_parameter" "droplet_image" {
|
|
name = "droplet_image"
|
|
display_name = "Droplet image"
|
|
description = "Which Droplet image would you like to use?"
|
|
default = "ubuntu-22-04-x64"
|
|
type = "string"
|
|
mutable = false
|
|
option {
|
|
name = "AlmaLinux 9"
|
|
value = "almalinux-9-x64"
|
|
icon = "/icon/almalinux.svg"
|
|
}
|
|
option {
|
|
name = "AlmaLinux 8"
|
|
value = "almalinux-8-x64"
|
|
icon = "/icon/almalinux.svg"
|
|
}
|
|
option {
|
|
name = "Fedora 39"
|
|
value = "fedora-39-x64"
|
|
icon = "/icon/fedora.svg"
|
|
}
|
|
option {
|
|
name = "Fedora 38"
|
|
value = "fedora-38-x64"
|
|
icon = "/icon/fedora.svg"
|
|
}
|
|
option {
|
|
name = "CentOS Stream 9"
|
|
value = "centos-stream-9-x64"
|
|
icon = "/icon/centos.svg"
|
|
}
|
|
option {
|
|
name = "CentOS Stream 8"
|
|
value = "centos-stream-8-x64"
|
|
icon = "/icon/centos.svg"
|
|
}
|
|
option {
|
|
name = "Debian 12"
|
|
value = "debian-12-x64"
|
|
icon = "/icon/debian.svg"
|
|
}
|
|
option {
|
|
name = "Debian 11"
|
|
value = "debian-11-x64"
|
|
icon = "/icon/debian.svg"
|
|
}
|
|
option {
|
|
name = "Debian 10"
|
|
value = "debian-10-x64"
|
|
icon = "/icon/debian.svg"
|
|
}
|
|
option {
|
|
name = "Rocky Linux 9"
|
|
value = "rockylinux-9-x64"
|
|
icon = "/icon/rockylinux.svg"
|
|
}
|
|
option {
|
|
name = "Rocky Linux 8"
|
|
value = "rockylinux-8-x64"
|
|
icon = "/icon/rockylinux.svg"
|
|
}
|
|
option {
|
|
name = "Ubuntu 22.04 (LTS)"
|
|
value = "ubuntu-22-04-x64"
|
|
icon = "/icon/ubuntu.svg"
|
|
}
|
|
option {
|
|
name = "Ubuntu 20.04 (LTS)"
|
|
value = "ubuntu-20-04-x64"
|
|
icon = "/icon/ubuntu.svg"
|
|
}
|
|
}
|
|
|
|
data "coder_parameter" "droplet_size" {
|
|
name = "droplet_size"
|
|
display_name = "Droplet size"
|
|
description = "Which Droplet configuration would you like to use?"
|
|
default = "s-1vcpu-1gb"
|
|
type = "string"
|
|
icon = "/icon/memory.svg"
|
|
mutable = false
|
|
# s-1vcpu-512mb-10gb is unsupported in tor1, blr1, lon1, sfo2, and nyc3 regions
|
|
# s-8vcpu-16gb access requires a support ticket with Digital Ocean
|
|
option {
|
|
name = "1 vCPU, 1 GB RAM"
|
|
value = "s-1vcpu-1gb"
|
|
}
|
|
option {
|
|
name = "1 vCPU, 2 GB RAM"
|
|
value = "s-1vcpu-2gb"
|
|
}
|
|
option {
|
|
name = "2 vCPU, 2 GB RAM"
|
|
value = "s-2vcpu-2gb"
|
|
}
|
|
option {
|
|
name = "2 vCPU, 4 GB RAM"
|
|
value = "s-2vcpu-4gb"
|
|
}
|
|
option {
|
|
name = "4 vCPU, 8 GB RAM"
|
|
value = "s-4vcpu-8gb"
|
|
}
|
|
}
|
|
|
|
data "coder_parameter" "home_volume_size" {
|
|
name = "home_volume_size"
|
|
display_name = "Home volume size"
|
|
description = "How large would you like your home volume to be (in GB)?"
|
|
type = "number"
|
|
default = "20"
|
|
mutable = false
|
|
validation {
|
|
min = 1
|
|
max = 100 # Sizes larger than 100 GB require a support ticket with Digital Ocean
|
|
}
|
|
}
|
|
|
|
data "coder_parameter" "region" {
|
|
name = "region"
|
|
display_name = "Region"
|
|
description = "This is the region where your workspace will be created."
|
|
icon = "/emojis/1f30e.png"
|
|
type = "string"
|
|
default = "ams3"
|
|
mutable = false
|
|
# nyc1, sfo1, and ams2 regions were excluded because they do not support volumes, which are used to persist data while decreasing cost
|
|
option {
|
|
name = "Canada (Toronto)"
|
|
value = "tor1"
|
|
icon = "/emojis/1f1e8-1f1e6.png"
|
|
}
|
|
option {
|
|
name = "Germany (Frankfurt)"
|
|
value = "fra1"
|
|
icon = "/emojis/1f1e9-1f1ea.png"
|
|
}
|
|
option {
|
|
name = "India (Bangalore)"
|
|
value = "blr1"
|
|
icon = "/emojis/1f1ee-1f1f3.png"
|
|
}
|
|
option {
|
|
name = "Netherlands (Amsterdam)"
|
|
value = "ams3"
|
|
icon = "/emojis/1f1f3-1f1f1.png"
|
|
}
|
|
option {
|
|
name = "Singapore"
|
|
value = "sgp1"
|
|
icon = "/emojis/1f1f8-1f1ec.png"
|
|
}
|
|
option {
|
|
name = "United Kingdom (London)"
|
|
value = "lon1"
|
|
icon = "/emojis/1f1ec-1f1e7.png"
|
|
}
|
|
option {
|
|
name = "United States (California - 2)"
|
|
value = "sfo2"
|
|
icon = "/emojis/1f1fa-1f1f8.png"
|
|
}
|
|
option {
|
|
name = "United States (California - 3)"
|
|
value = "sfo3"
|
|
icon = "/emojis/1f1fa-1f1f8.png"
|
|
}
|
|
option {
|
|
name = "United States (New York - 1)"
|
|
value = "nyc1"
|
|
icon = "/emojis/1f1fa-1f1f8.png"
|
|
}
|
|
option {
|
|
name = "United States (New York - 3)"
|
|
value = "nyc3"
|
|
icon = "/emojis/1f1fa-1f1f8.png"
|
|
}
|
|
}
|
|
|
|
# Configure the DigitalOcean Provider
|
|
provider "digitalocean" {
|
|
# Recommended: use environment variable DIGITALOCEAN_TOKEN with your personal access token when starting coderd
|
|
# alternatively, you can pass the token via a variable.
|
|
}
|
|
|
|
data "coder_workspace" "me" {}
|
|
data "coder_workspace_owner" "me" {}
|
|
|
|
resource "coder_agent" "main" {
|
|
os = "linux"
|
|
arch = "amd64"
|
|
|
|
metadata {
|
|
key = "cpu"
|
|
display_name = "CPU Usage"
|
|
interval = 5
|
|
timeout = 5
|
|
script = "coder stat cpu"
|
|
}
|
|
metadata {
|
|
key = "memory"
|
|
display_name = "Memory Usage"
|
|
interval = 5
|
|
timeout = 5
|
|
script = "coder stat mem"
|
|
}
|
|
metadata {
|
|
key = "home"
|
|
display_name = "Home Usage"
|
|
interval = 600 # every 10 minutes
|
|
timeout = 30 # df can take a while on large filesystems
|
|
script = "coder stat disk --path /home/${lower(data.coder_workspace_owner.me.name)}"
|
|
}
|
|
}
|
|
|
|
resource "digitalocean_volume" "home_volume" {
|
|
region = data.coder_parameter.region.value
|
|
name = "coder-${data.coder_workspace.me.id}-home"
|
|
size = data.coder_parameter.home_volume_size.value
|
|
initial_filesystem_type = "ext4"
|
|
initial_filesystem_label = "coder-home"
|
|
# Protect the volume from being deleted due to changes in attributes.
|
|
lifecycle {
|
|
ignore_changes = all
|
|
}
|
|
}
|
|
|
|
resource "digitalocean_droplet" "workspace" {
|
|
region = data.coder_parameter.region.value
|
|
count = data.coder_workspace.me.start_count
|
|
name = "coder-${lower(data.coder_workspace_owner.me.name)}-${lower(data.coder_workspace.me.name)}"
|
|
image = data.coder_parameter.droplet_image.value
|
|
size = data.coder_parameter.droplet_size.value
|
|
|
|
volume_ids = [digitalocean_volume.home_volume.id]
|
|
user_data = templatefile("cloud-config.yaml.tftpl", {
|
|
username = lower(data.coder_workspace_owner.me.name)
|
|
home_volume_label = digitalocean_volume.home_volume.initial_filesystem_label
|
|
init_script = base64encode(coder_agent.main.init_script)
|
|
coder_agent_token = coder_agent.main.token
|
|
})
|
|
# Required to provision Fedora.
|
|
ssh_keys = var.step2_do_admin_ssh_key > 0 ? [var.step2_do_admin_ssh_key] : []
|
|
}
|
|
|
|
resource "digitalocean_project_resources" "project" {
|
|
project = var.step1_do_project_id
|
|
# Workaround for terraform plan when using count.
|
|
resources = length(digitalocean_droplet.workspace) > 0 ? [
|
|
digitalocean_volume.home_volume.urn,
|
|
digitalocean_droplet.workspace[0].urn
|
|
] : [
|
|
digitalocean_volume.home_volume.urn
|
|
]
|
|
}
|
|
|
|
resource "coder_metadata" "workspace-info" {
|
|
count = data.coder_workspace.me.start_count
|
|
resource_id = digitalocean_droplet.workspace[0].id
|
|
|
|
item {
|
|
key = "region"
|
|
value = digitalocean_droplet.workspace[0].region
|
|
}
|
|
item {
|
|
key = "image"
|
|
value = digitalocean_droplet.workspace[0].image
|
|
}
|
|
}
|
|
|
|
resource "coder_metadata" "volume-info" {
|
|
resource_id = digitalocean_volume.home_volume.id
|
|
|
|
item {
|
|
key = "size"
|
|
value = "${digitalocean_volume.home_volume.size} GiB"
|
|
}
|
|
}
|