coder-template/hetzner-cloud/main.tf

359 lines
8.4 KiB
HCL

terraform {
required_providers {
coder = {
source = "coder/coder"
version = "~> 0.21.0"
}
hcloud = {
source = "hetznercloud/hcloud"
version = "1.47.0"
}
}
}
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-40"
type = "string"
mutable = false
option {
name = "Fedora38"
value = "fedora-38"
}
option {
name = "Fedora39"
value = "fedora-39"
}
option {
name = "Fedora40"
value = "fedora-40"
}
}
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.34.94"
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 = startswith(data.coder_parameter.instance_type.value, "cax") ? "arm64" : "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
}
resource "hcloud_ssh_key" "root" {
name = "coder-${data.coder_workspace.me.owner}-${data.coder_workspace.me.name}"
public_key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDQoNCLuHgcaDn4JTjCeQKJsIsYU0Jmub5PUMzIIZbUBb+TGMh6mCAY/UbYaq/n4jVnskXopzPGJbx4iPBG5HrNzqYZqMjkk8uIeeT0mdIcNv9bXxuCxCH1iHZF8LlzIZCmQ0w3X6VQ1izcJgvjrAYzbHN3gqCHOXtNkqIUkwaadIWCEjg33OVSlM4yrIDElr6+LHzv84VNh/PhemixCVVEMJ83GjhDtpApMg9WWW3es6rpJn4TlYEMV+aPNU4ZZEWFen/DFBKoX+ulkiJ8CwpY3eJxSzlBijs5ZKH89OOk/MXN1lnREElFqli+jE8EbZKQzi59Zmx8ZOb52qVNot8XZT0Un4EttAIEeE8cETqUC4jK+6RbUrsXtclVbU9i57LWRpl65LYSIJEFmkTxvYdkPXqGbvlW024IjgSo8kds121w95+Rpo6419cSYsQWowS8+aXfEv2Q8SE81QH7ObYfWFXsPBAmmNleQNN3E5HOoaxpWQjv3aTUGuxm4PCzKLdP0LsHmTfGJB7Priaj+9i8xLjDWe7zXDde2Gp9FmdedDr06uEkVSRFnS35Dwfd7M7xP6NsilfMOdWzJWWy/BAYxtnWcrEFxhaEr4vgs8Ub+KBtKhr740x3Mr8up+mythConAs4LOj37lWK4kJ8cI7TXjcSJi9nTIPd39us7tp3Aw== cardno:24_781_961"
}
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]
}