360 lines
7.7 KiB
HCL
360 lines
7.7 KiB
HCL
terraform {
|
|
required_providers {
|
|
coder = {
|
|
source = "coder/coder"
|
|
version = "~> 0.12.4"
|
|
}
|
|
hcloud = {
|
|
source = "hetznercloud/hcloud"
|
|
version = "1.44.1"
|
|
}
|
|
}
|
|
}
|
|
|
|
provider "hcloud" {
|
|
token = var.hcloud_token
|
|
}
|
|
|
|
provider "coder" {
|
|
}
|
|
|
|
variable "hcloud_token" {
|
|
description = <<EOF
|
|
Coder requires a Hetzner Cloud token to provision workspaces.
|
|
EOF
|
|
sensitive = true
|
|
validation {
|
|
condition = length(var.hcloud_token) == 64
|
|
error_message = "Please provide a valid Hetzner Cloud API token."
|
|
}
|
|
}
|
|
|
|
variable "use_subdomain" {
|
|
description = "If apps are published under a subdomain"
|
|
default = "true"
|
|
validation {
|
|
condition = contains(["true", "false"], var.use_subdomain)
|
|
error_message = "Your answer can only be yes or no!"
|
|
}
|
|
}
|
|
|
|
variable "private_network_id" {
|
|
description = "ID of private network the server will be joined to"
|
|
default = ""
|
|
}
|
|
|
|
data "coder_parameter" "dotfiles_uri" {
|
|
name = "dotfiles_uri"
|
|
display_name = "Dotfiles URI"
|
|
description = <<-EOF
|
|
Dotfiles repo URI (optional)
|
|
|
|
see https://dotfiles.github.io
|
|
EOF
|
|
|
|
default = ""
|
|
mutable = true
|
|
}
|
|
|
|
data "coder_parameter" "user_shell" {
|
|
name = "user_shell"
|
|
display_name = "Default Shell"
|
|
default = "/usr/bin/zsh"
|
|
mutable = true
|
|
}
|
|
|
|
data "coder_parameter" "instance_location" {
|
|
name = "instance_location"
|
|
display_name = "Instance location"
|
|
default = "fsn1"
|
|
mutable = false
|
|
|
|
option {
|
|
name = "Nuernberg"
|
|
value = "nbg1"
|
|
}
|
|
|
|
option {
|
|
name = "Falkenstein"
|
|
value = "fsn1"
|
|
}
|
|
|
|
option {
|
|
name = "Helsinki"
|
|
value = "hel1"
|
|
}
|
|
}
|
|
|
|
data "coder_parameter" "instance_type" {
|
|
name = "instance_type"
|
|
display_name = "Instance type"
|
|
default = "cpx11"
|
|
type = "string"
|
|
mutable = true
|
|
|
|
option {
|
|
name = "cx11"
|
|
value = "cx11"
|
|
}
|
|
|
|
option {
|
|
name = "cpx11"
|
|
value = "cpx11"
|
|
}
|
|
|
|
option {
|
|
name = "cax11"
|
|
value = "cax11"
|
|
}
|
|
|
|
option {
|
|
name = "cx21"
|
|
value = "cx21"
|
|
}
|
|
|
|
option {
|
|
name = "cpx21"
|
|
value = "cpx21"
|
|
}
|
|
|
|
option {
|
|
name = "cax21"
|
|
value = "cax21"
|
|
}
|
|
|
|
option {
|
|
name = "cx31"
|
|
value = "cx31"
|
|
}
|
|
|
|
option {
|
|
name = "cpx31"
|
|
value = "cpx31"
|
|
}
|
|
|
|
option {
|
|
name = "cax31"
|
|
value = "cax31"
|
|
}
|
|
|
|
option {
|
|
name = "cx41"
|
|
value = "cx41"
|
|
}
|
|
|
|
option {
|
|
name = "cpx41"
|
|
value = "cpx41"
|
|
}
|
|
|
|
option {
|
|
name = "cax41"
|
|
value = "cax41"
|
|
}
|
|
|
|
option {
|
|
name = "cx51"
|
|
value = "cx51"
|
|
}
|
|
|
|
option {
|
|
name = "cpx51"
|
|
value = "cpx51"
|
|
}
|
|
}
|
|
|
|
data "coder_parameter" "instance_os" {
|
|
name = "instance_os"
|
|
display_name = "Instance OS"
|
|
description = "Which operating system should your workspace use?"
|
|
default = "fedora-38"
|
|
type = "string"
|
|
mutable = false
|
|
|
|
option {
|
|
name = "Fedora37"
|
|
value = "fedora-37"
|
|
}
|
|
|
|
option {
|
|
name = "Fedora38"
|
|
value = "fedora-38"
|
|
}
|
|
}
|
|
|
|
data "coder_parameter" "volume_size" {
|
|
name = "volume_size"
|
|
display_name = "Volume Size"
|
|
description = "How much storage space do you need in GB (can't be less then 10)?"
|
|
default = 10
|
|
type = "number"
|
|
|
|
validation {
|
|
min = 10
|
|
max = 100
|
|
monotonic = "increasing"
|
|
}
|
|
}
|
|
|
|
data "coder_parameter" "fleet_version" {
|
|
name = "fleet_version"
|
|
display_name = "Fleet version"
|
|
description = "Which version of Fleet should be installed?"
|
|
default = "1.24.137"
|
|
type = "string"
|
|
mutable = true
|
|
}
|
|
|
|
data "coder_parameter" "remote_ide" {
|
|
name = "install_remote_ide"
|
|
description = "Which remote IDE should be installed"
|
|
default = "code_server"
|
|
type = "string"
|
|
mutable = true
|
|
|
|
|
|
option {
|
|
name = "None"
|
|
value = "none"
|
|
}
|
|
|
|
option {
|
|
name = "Code server"
|
|
value = "code_server"
|
|
}
|
|
|
|
option {
|
|
name = "Jetbrains Fleet"
|
|
value = "fleet"
|
|
}
|
|
}
|
|
|
|
data "coder_parameter" "install_podman" {
|
|
name = "install_podman"
|
|
description = "Should Podman be installed?"
|
|
default = "true"
|
|
type = "string"
|
|
mutable = true
|
|
option {
|
|
name = "Install"
|
|
value = "true"
|
|
}
|
|
|
|
option {
|
|
name = "Don't install"
|
|
value = "false"
|
|
}
|
|
}
|
|
|
|
data "coder_workspace" "me" {
|
|
}
|
|
|
|
resource "coder_agent" "dev" {
|
|
arch = "amd64"
|
|
os = "linux"
|
|
|
|
startup_script = data.coder_parameter.dotfiles_uri.value != "" ? "coder dotfiles -y ${data.coder_parameter.dotfiles_uri.value}" : null
|
|
|
|
env = {
|
|
DOCKER_HOST = data.coder_parameter.install_podman.value == "true" ? "unix:///run/user/1000/podman/podman.sock" : "unix:///var/run/docker.sock"
|
|
}
|
|
}
|
|
|
|
resource "coder_app" "code-server" {
|
|
display_name = "code-server"
|
|
count = data.coder_parameter.remote_ide.value == "code_server" ? 1 : 0
|
|
agent_id = coder_agent.dev.id
|
|
slug = "code-server"
|
|
icon = "/icon/code.svg"
|
|
url = "http://localhost:8080"
|
|
subdomain = var.use_subdomain
|
|
}
|
|
|
|
resource "coder_app" "fleet" {
|
|
display_name = "Jetbrains Fleet"
|
|
count = data.coder_parameter.remote_ide.value == "fleet" ? 1 : 0
|
|
agent_id = coder_agent.dev.id
|
|
slug = "fleet"
|
|
icon = "https://www.jetbrains.com/_assets/www/fleet/inc/overview-content/img/fleet-logo.65f4a04c59fc3ba93bb5e181050891c5.png"
|
|
url = "http://localhost:3500"
|
|
subdomain = var.use_subdomain
|
|
}
|
|
|
|
# Generate a dummy ssh key that is not accessible so Hetzner cloud does not spam the admin with emails.
|
|
resource "tls_private_key" "rsa_4096" {
|
|
algorithm = "RSA"
|
|
rsa_bits = 4096
|
|
}
|
|
|
|
resource "hcloud_ssh_key" "root" {
|
|
name = "coder-${data.coder_workspace.me.owner}-${data.coder_workspace.me.name}"
|
|
public_key = tls_private_key.rsa_4096.public_key_openssh
|
|
}
|
|
|
|
resource "hcloud_server" "root" {
|
|
count = data.coder_workspace.me.start_count
|
|
name = "coder-${data.coder_workspace.me.owner}-${data.coder_workspace.me.name}"
|
|
server_type = data.coder_parameter.instance_type.value
|
|
location = data.coder_parameter.instance_location.value
|
|
image = data.coder_parameter.instance_os.value
|
|
ssh_keys = [hcloud_ssh_key.root.id]
|
|
|
|
user_data = templatefile("cloud-config.yaml.tftpl", {
|
|
username = data.coder_workspace.me.owner
|
|
volume_path = "/dev/disk/by-id/scsi-0HC_Volume_${hcloud_volume.root.id}"
|
|
init_script = base64encode(coder_agent.dev.init_script)
|
|
coder_agent_token = coder_agent.dev.token
|
|
remote_ide_setup = data.coder_parameter.remote_ide.value
|
|
fleet_version = data.coder_parameter.fleet_version.value
|
|
install_podman_setup = data.coder_parameter.install_podman.value
|
|
user_shell = data.coder_parameter.user_shell.value
|
|
})
|
|
|
|
dynamic "network" {
|
|
for_each = var.private_network_id == "" ? [] : [""]
|
|
content {
|
|
network_id = var.private_network_id
|
|
}
|
|
}
|
|
|
|
public_net {
|
|
ipv4_enabled = true
|
|
ipv6_enabled = true
|
|
}
|
|
}
|
|
|
|
resource "hcloud_volume" "root" {
|
|
name = "coder-${data.coder_workspace.me.id}-home"
|
|
size = data.coder_parameter.volume_size.value
|
|
format = "ext4"
|
|
location = data.coder_parameter.instance_location.value
|
|
|
|
lifecycle {
|
|
ignore_changes = all
|
|
}
|
|
}
|
|
|
|
resource "hcloud_volume_attachment" "root" {
|
|
count = data.coder_workspace.me.start_count
|
|
volume_id = hcloud_volume.root.id
|
|
server_id = hcloud_server.root[count.index].id
|
|
automount = false
|
|
}
|
|
|
|
resource "hcloud_firewall" "root" {
|
|
name = "coder-${data.coder_workspace.me.owner_id}-${data.coder_workspace.me.id}-root"
|
|
rule {
|
|
direction = "in"
|
|
protocol = "icmp"
|
|
source_ips = [
|
|
"0.0.0.0/0",
|
|
"::/0"
|
|
]
|
|
}
|
|
}
|
|
|
|
resource "hcloud_firewall_attachment" "root_fw_attach" {
|
|
count = data.coder_workspace.me.start_count
|
|
firewall_id = hcloud_firewall.root.id
|
|
server_ids = [hcloud_server.root[count.index].id]
|
|
}
|