Skip to content

Commit 1a70298

Browse files
mafredrijohnstcn
andauthored
feat: Add examples/templates/do-linux for Digital Ocean Droplets (#1749)
Co-authored-by: Cian Johnston <cian@coder.com>
1 parent 14cdd85 commit 1a70298

File tree

3 files changed

+209
-0
lines changed

3 files changed

+209
-0
lines changed

examples/templates/do-linux/README.md

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
---
2+
name: Develop in Linux on a Digital Ocean Droplet
3+
description: Get started with Linux development on a Digital Ocean Droplet.
4+
tags: [cloud, digitalocean]
5+
---
6+
7+
# do-linux
8+
9+
This is an example for deploying workspaces as Digital Ocean Droplets.
10+
11+
## Requirements
12+
13+
- Digital Ocean Personal Access Token (PAT)
14+
- Digital Ocean Project ID (e.g. `doctl projects list`)
15+
- Remove `variable "step2_do_project_id"` and `resource "digitalocean_project_resources" "project"` if you don't want project association.
16+
- (Optional) Digital Ocean SSH key ID (e.g. `doctl compute ssh-key list`)
17+
- Only required for Fedora images to work.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
#cloud-config
2+
users:
3+
- name: ${username}
4+
sudo: ["ALL=(ALL) NOPASSWD:ALL"]
5+
groups: sudo
6+
shell: /bin/bash
7+
packages:
8+
- git
9+
mounts:
10+
- [
11+
"LABEL=${home_volume_label}",
12+
"/home/${username}",
13+
auto,
14+
"defaults,uid=1000,gid=1000",
15+
]
16+
write_files:
17+
- path: /opt/coder/init
18+
permissions: "0755"
19+
encoding: b64
20+
content: ${init_script}
21+
- path: /etc/systemd/system/coder-agent.service
22+
permissions: "0644"
23+
content: |
24+
[Unit]
25+
Description=Coder Agent
26+
After=network-online.target
27+
Wants=network-online.target
28+
29+
[Service]
30+
User=${username}
31+
ExecStart=/opt/coder/init
32+
Environment=CODER_AGENT_TOKEN=${coder_agent_token}
33+
Restart=always
34+
RestartSec=10
35+
TimeoutStopSec=90
36+
KillMode=process
37+
38+
OOMScoreAdjust=-900
39+
SyslogIdentifier=coder-agent
40+
41+
[Install]
42+
WantedBy=multi-user.target
43+
runcmd:
44+
- chown ${username}:${username} /home/${username}
45+
- systemctl enable coder-agent
46+
- systemctl start coder-agent

examples/templates/do-linux/main.tf

+146
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
terraform {
2+
required_providers {
3+
coder = {
4+
source = "coder/coder"
5+
version = "0.4.1"
6+
}
7+
digitalocean = {
8+
source = "digitalocean/digitalocean"
9+
version = "~> 2.0"
10+
}
11+
}
12+
}
13+
14+
variable "step1_do_token" {
15+
type = string
16+
description = "Enter token (see documentation at https://docs.digitalocean.com/reference/api/create-personal-access-token/)"
17+
sensitive = true
18+
19+
validation {
20+
condition = length(var.step1_do_token) == 71 && substr(var.step1_do_token, 0, 4) == "dop_"
21+
error_message = "Invalid Digital Ocean Personal Access Token."
22+
}
23+
}
24+
25+
variable "step2_do_project_id" {
26+
type = string
27+
description = <<-EOF
28+
Enter project ID
29+
30+
$ doctl projects list
31+
EOF
32+
sensitive = true
33+
34+
validation {
35+
condition = length(var.step2_do_project_id) == 36
36+
error_message = "Invalid Digital Ocean Project ID."
37+
}
38+
}
39+
40+
variable "step3_do_admin_ssh_key" {
41+
type = number
42+
description = <<-EOF
43+
Enter admin SSH key ID (some Droplet images require an SSH key to be set):
44+
45+
Can be set to zero.
46+
47+
Note: Setting this to zero will break Fedora images and notify root passwords via email.
48+
49+
$ doctl compute ssh-key list
50+
EOF
51+
sensitive = true
52+
53+
validation {
54+
condition = var.step3_do_admin_ssh_key >= 0
55+
error_message = "Invalid Digital Ocean SSH key ID, a number is required."
56+
}
57+
}
58+
59+
variable "droplet_image" {
60+
type = string
61+
description = "Which Droplet image would you like to use for your workspace?"
62+
default = "ubuntu-22-04-x64"
63+
validation {
64+
condition = contains(["ubuntu-22-04-x64", "ubuntu-20-04-x64", "fedora-36-x64", "fedora-35-x64", "debian-11-x64", "debian-10-x64", "centos-stream-9-x64", "centos-stream-8-x64", "rockylinux-8-x64", "rockylinux-8-4-x64"], var.droplet_image)
65+
error_message = "Value must be ubuntu-22-04-x64, ubuntu-20-04-x64, fedora-36-x64, fedora-35-x64, debian-11-x64, debian-10-x64, centos-stream-9-x64, centos-stream-8-x64, rockylinux-8-x64 or rockylinux-8-4-x64."
66+
}
67+
}
68+
69+
variable "droplet_size" {
70+
type = string
71+
description = "Which Droplet configuration would you like to use?"
72+
default = "s-1vcpu-1gb"
73+
validation {
74+
condition = contains(["s-1vcpu-1gb", "s-1vcpu-2gb", "s-2vcpu-2gb", "s-2vcpu-4gb", "s-4vcpu-8gb", "s-8vcpu-16gb"], var.droplet_size)
75+
error_message = "Value must be s-1vcpu-1gb, s-1vcpu-2gb, s-2vcpu-2gb, s-2vcpu-4gb, s-4vcpu-8gb or s-8vcpu-16gb."
76+
}
77+
}
78+
79+
variable "home_volume_size" {
80+
type = number
81+
description = "How large would you like your home volume to be (in GB)?"
82+
default = 20
83+
validation {
84+
condition = var.home_volume_size >= 1
85+
error_message = "Value must be greater than or equal to 1."
86+
}
87+
}
88+
89+
variable "region" {
90+
type = string
91+
description = "Which region would you like to use?"
92+
default = "ams3"
93+
validation {
94+
condition = contains(["nyc1", "nyc2", "nyc3", "sfo1", "sfo2", "sfo3", "ams2", "ams3", "sgp1", "lon1", "fra1", "tor1", "blr1"], var.region)
95+
error_message = "Value must be nyc1, nyc2, nyc3, sfo1, sfo2, sfo3, ams2, ams3, sgp1, lon1, fra1, tor1 or blr1."
96+
}
97+
}
98+
99+
# Configure the DigitalOcean Provider
100+
provider "digitalocean" {
101+
token = var.step1_do_token
102+
}
103+
104+
data "coder_workspace" "me" {}
105+
106+
resource "coder_agent" "dev" {
107+
os = "linux"
108+
arch = "amd64"
109+
}
110+
111+
resource "digitalocean_volume" "home_volume" {
112+
region = var.region
113+
name = "coder-${data.coder_workspace.me.owner}-${data.coder_workspace.me.name}-home"
114+
size = var.home_volume_size
115+
initial_filesystem_type = "ext4"
116+
initial_filesystem_label = "coder-home"
117+
}
118+
119+
resource "digitalocean_droplet" "workspace" {
120+
region = var.region
121+
count = data.coder_workspace.me.start_count
122+
name = "coder-${data.coder_workspace.me.owner}-${data.coder_workspace.me.name}"
123+
image = var.droplet_image
124+
size = var.droplet_size
125+
volume_ids = [digitalocean_volume.home_volume.id]
126+
user_data = templatefile("cloud-config.yaml.tftpl", {
127+
username = data.coder_workspace.me.owner
128+
home_volume_label = digitalocean_volume.home_volume.initial_filesystem_label
129+
init_script = base64encode(coder_agent.dev.init_script)
130+
coder_agent_token = coder_agent.dev.token
131+
})
132+
# Required to provision Fedora.
133+
ssh_keys = var.step3_do_admin_ssh_key > 0 ? [var.step3_do_admin_ssh_key] : []
134+
}
135+
136+
# Temporarily disabled because it breaks SSH. (https://github.com/coder/coder/issues/1750)
137+
# resource "digitalocean_project_resources" "project" {
138+
# project = var.step2_do_project_id
139+
# # Workaround for terraform plan when using count.
140+
# resources = length(digitalocean_droplet.workspace) > 0 ? [
141+
# digitalocean_volume.home_volume.urn,
142+
# digitalocean_droplet.workspace[0].urn
143+
# ] : [
144+
# digitalocean_volume.home_volume.urn
145+
# ]
146+
# }

0 commit comments

Comments
 (0)