feat: initial template version
This commit is contained in:
commit
21ffbe33e7
3 changed files with 331 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
*.tar
|
65
cloud-config.yaml.tftpl
Normal file
65
cloud-config.yaml.tftpl
Normal file
|
@ -0,0 +1,65 @@
|
|||
#cloud-config
|
||||
users:
|
||||
- name: ${username}
|
||||
sudo: ["ALL=(ALL) NOPASSWD:ALL"]
|
||||
groups: sudo
|
||||
shell: /bin/bash
|
||||
packages:
|
||||
- zsh
|
||||
- git
|
||||
- curl
|
||||
- jq
|
||||
- podman
|
||||
- golang
|
||||
- dotnet-sdk-6.0
|
||||
- dotnet-sdk-7.0
|
||||
mounts:
|
||||
- [
|
||||
"${volume_path}",
|
||||
"/home/${username}",
|
||||
ext4,
|
||||
"discard,defaults",
|
||||
]
|
||||
write_files:
|
||||
- path: /opt/coder/init
|
||||
permissions: "0755"
|
||||
encoding: b64
|
||||
content: ${init_script}
|
||||
- path: /etc/systemd/system/coder-agent.service
|
||||
permissions: "0644"
|
||||
content: |
|
||||
[Unit]
|
||||
Description=Coder Agent
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
User=${username}
|
||||
ExecStart=/opt/coder/init
|
||||
Environment=CODER_AGENT_TOKEN=${coder_agent_token}
|
||||
Restart=always
|
||||
RestartSec=10
|
||||
TimeoutStopSec=90
|
||||
KillMode=process
|
||||
|
||||
OOMScoreAdjust=-900
|
||||
SyslogIdentifier=coder-agent
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
%{ if code_server_setup ~}
|
||||
- path: /home/${username}/.config/code-server/config.yaml
|
||||
permissions: "0644"
|
||||
content: |
|
||||
bind-addr: 127.0.0.1:8080
|
||||
auth: none
|
||||
cert: false
|
||||
%{ endif ~}
|
||||
runcmd:
|
||||
- chown ${username}:${username} /home/${username}
|
||||
- systemctl enable coder-agent
|
||||
- systemctl start coder-agent
|
||||
%{ if code_server_setup ~}
|
||||
- dnf install -y $(curl -sL https://api.github.com/repos/coder/code-server/releases/latest | jq -r '.assets[].browser_download_url' | grep "amd64.rpm")
|
||||
- systemctl enable --now code-server@${username}
|
||||
%{ endif }
|
265
main.tf
Normal file
265
main.tf
Normal file
|
@ -0,0 +1,265 @@
|
|||
terraform {
|
||||
required_providers {
|
||||
coder = {
|
||||
source = "coder/coder"
|
||||
version = "~> 0.7.0"
|
||||
}
|
||||
hcloud = {
|
||||
source = "hetznercloud/hcloud"
|
||||
version = "1.40.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
provider "hcloud" {
|
||||
token = var.hcloud_token
|
||||
}
|
||||
|
||||
provider "coder" {
|
||||
feature_use_managed_variables = "true"
|
||||
}
|
||||
|
||||
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" "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 = false
|
||||
|
||||
option {
|
||||
name = "cx11"
|
||||
value = "cx11"
|
||||
}
|
||||
|
||||
option {
|
||||
name = "cpx11"
|
||||
value = "cpx11"
|
||||
}
|
||||
|
||||
option {
|
||||
name = "cx21"
|
||||
value = "cx21"
|
||||
}
|
||||
|
||||
option {
|
||||
name = "cpx21"
|
||||
value = "cpx21"
|
||||
}
|
||||
|
||||
option {
|
||||
name = "cx31"
|
||||
value = "cx31"
|
||||
}
|
||||
|
||||
option {
|
||||
name = "cpx31"
|
||||
value = "cpx31"
|
||||
}
|
||||
|
||||
option {
|
||||
name = "cx41"
|
||||
value = "cx41"
|
||||
}
|
||||
|
||||
option {
|
||||
name = "cpx41"
|
||||
value = "cpx41"
|
||||
}
|
||||
|
||||
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" "code_server" {
|
||||
name = "install_code_server"
|
||||
description = "Should Code Server be installed?"
|
||||
default = "true"
|
||||
type = "string"
|
||||
|
||||
option {
|
||||
name = "Install"
|
||||
value = "true"
|
||||
}
|
||||
|
||||
option {
|
||||
name = "Don't install"
|
||||
value = "false"
|
||||
}
|
||||
}
|
||||
|
||||
data "coder_workspace" "me" {
|
||||
}
|
||||
|
||||
resource "coder_agent" "dev" {
|
||||
arch = "amd64"
|
||||
os = "linux"
|
||||
}
|
||||
|
||||
resource "coder_app" "code-server" {
|
||||
display_name = "code-server"
|
||||
count = data.coder_parameter.code_server.value ? 1 : 0
|
||||
agent_id = coder_agent.dev.id
|
||||
slug = "code-server"
|
||||
icon = "/icon/code.svg"
|
||||
url = "http://localhost:8080"
|
||||
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}-root"
|
||||
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}-root"
|
||||
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
|
||||
code_server_setup = data.coder_parameter.code_server.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.owner}-${data.coder_workspace.me.name}-root"
|
||||
size = data.coder_parameter.volume_size.value
|
||||
format = "ext4"
|
||||
location = data.coder_parameter.instance_location.value
|
||||
}
|
||||
|
||||
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}-${data.coder_workspace.me.name}-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]
|
||||
}
|
Loading…
Reference in a new issue