diff --git a/incus-lxc-container/.terraform.lock.hcl b/incus-lxc-container/.terraform.lock.hcl new file mode 100644 index 0000000..c686fea --- /dev/null +++ b/incus-lxc-container/.terraform.lock.hcl @@ -0,0 +1,45 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/coder/coder" { + version = "0.13.0" + constraints = ">= 0.12.0" + hashes = [ + "h1:szTaWezPHC12Dknjj1tq1myHehroctMWyp0casICfVU=", + "zh:1d3151298b4c96ad2f10e910b7f2bb85841915800c4919eb8629f57622a73eb3", + "zh:214034bf1058dbfea357a4dc2d05f204845c9a291a28cc16b00f60424d7ab98e", + "zh:30c0a11ba78166a109a54e319add42d3e04655c59bb16c750bc70ecde8e96f21", + "zh:52148b5dd252242b11ec60dd37359808b3f147e7d8a963c2a90e737204e3472e", + "zh:5e268b53fba2cda3463726f3f5d60bb0617f11bbbd75a1995c4f42c09a05dced", + "zh:5f6e2b9858649ad4666163816b03b474e29935470bc565bba2fed2afc8718a67", + "zh:871dc76e9f1cf1e08d5214d15c1eb6d2630de3d6a1d513a468ede014ad4ce5d7", + "zh:c2f3fb68891e830fc224ef496257ba43b7612c3df5c24efd3c9e7d6044f3d0e9", + "zh:ccf6bcf72d3e5955de6cf44d104a18daf7bad9d76fc45f5b097749960b169ecb", + "zh:ce6f280d7f5a39de5d31e2c94ef514c6e52ab1204fa0887ac45495433dafb1bd", + "zh:d888d239b97c1eab91b0f1a9e74acb7e5dd777254f21970fa880c7bc8be5f46e", + "zh:d9a9e90fedf98ade4f31e132be98dd3c7e2a4edfc964b50756f893cbf064192e", + "zh:e8f4fa7af6ed13941d97a7089c45b3fe2617ddfbe4d727136f07b55e24c506df", + "zh:ed3d07621ebac383fcd89eb9ecbf97e7a391db180dae79d9451952685f0eac93", + "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + ] +} + +provider "registry.terraform.io/lxc/incus" { + version = "0.0.2" + hashes = [ + "h1:Prx78AlBNCfgvysp8zc639O0i83sg/MWXMKtCEsNNgs=", + "zh:071e40262143b9304ae7630fecd0798954d1ccdb8baf3ce84d3e1c08094cec89", + "zh:0b73e53c73260aece4ceb45737a43492bb36338f28159c69f1ab9f460f669c95", + "zh:15c75306de3886d516a023c9524fe223209c6842e200671b15e4649464638ee0", + "zh:2e86e7f0d54fad513eec83fce2e434c4f13ed0ab4a266ccfa1200c7c5f34ddff", + "zh:4c3453998460c363d20b2987e294be698e003ed889e8dfcc5eba689a77772cc3", + "zh:62c7fb8fd5069a29bc8d982367d2d9bf3cad24949c35b3a978b569f052d38947", + "zh:6dda9870de9f5453b5158997d800fe1d3e9fdfd319cad7fc32a942ddc8a8fee3", + "zh:7b629d89c05363b39388f5fcfb84a9c4cc015215ed2cc9a5e244060df5d07dc7", + "zh:8668285c1b7e6b352212815eb3c08d1c72a8f1d9139ea19b6661e41bac4eac0a", + "zh:90b5fef8591a824693c7f67fc3c1afcce0fd288164e83f9220b50eead47eb0fd", + "zh:9a9ab52719c9cc8f8e6d243f9dd10e725d7ceffcce6dae6ba9098c7a355f0cb8", + "zh:a7f412dc87a917a9ed475d5df41d4f10bb6867d1d20515c6abac52e92aff31b8", + "zh:cacb04151261fc4c5075df5bcb1ce5a62babb22c3de68aa80d2e3c20f0944f18", + ] +} diff --git a/incus-lxc-container/main.tf b/incus-lxc-container/main.tf new file mode 100644 index 0000000..9ae769d --- /dev/null +++ b/incus-lxc-container/main.tf @@ -0,0 +1,169 @@ +terraform { + required_providers { + coder = { + source = "coder/coder" + } + incus = { + source = "lxc/incus" + } + } +} + +data "coder_provisioner" "me" {} + +provider "incus" {} + +data "coder_workspace" "me" {} + + +data "coder_parameter" "cpu" { + name = "cpu" + display_name = "CPU" + description = "The number of CPUs to allocate to the workspace (1-8)" + type = "number" + default = "1" + icon = "https://raw.githubusercontent.com/matifali/logos/main/cpu-3.svg" + mutable = true + validation { + min = 1 + max = 8 + } +} + +data "coder_parameter" "memory" { + name = "memory" + display_name = "Memory" + description = "The amount of memory to allocate to the workspace in GB (up to 16GB)" + type = "number" + default = "2" + icon = "/icon/memory.svg" + mutable = true + validation { + min = 1 + max = 16 + } +} + +resource "coder_agent" "main" { + arch = data.coder_provisioner.me.arch + os = "linux" + dir = "/home/${local.workspace_user}" + + metadata { + display_name = "CPU Usage" + key = "0_cpu_usage" + script = "coder stat cpu" + interval = 10 + timeout = 1 + } + + metadata { + display_name = "RAM Usage" + key = "1_ram_usage" + script = "coder stat mem" + interval = 10 + timeout = 1 + } + + metadata { + display_name = "Home Disk" + key = "3_home_disk" + script = "coder stat disk --path /home/${lower(data.coder_workspace.me.owner)}" + interval = 60 + timeout = 1 + } +} + +module "code-server" { + source = "registry.coder.com/modules/code-server/coder" + version = "1.0.2" + agent_id = coder_agent.main.id + folder = "/home/${lower(data.coder_workspace.me.owner)}" +} + + +resource "incus_volume" "home" { + name = "coder-${data.coder_workspace.me.id}-home" + pool = local.pool +} + +resource "incus_volume" "docker" { + name = "coder-${data.coder_workspace.me.id}-docker" + pool = local.pool +} + +resource "incus_cached_image" "ubuntu" { + source_remote = "ubuntu" + source_image = "jammy/amd64" +} + +resource "incus_instance" "dev" { + count = data.coder_workspace.me.start_count + name = "coder-${lower(data.coder_workspace.me.owner)}-${lower(data.coder_workspace.me.name)}" + image = incus_cached_image.ubuntu.fingerprint + + config = { + "security.nesting" = true + "security.syscalls.intercept.mknod" = true + "security.syscalls.intercept.setxattr" = true + "boot.autostart" = true + "cloud-init.user-data" = <&1 >/dev/null + usermod -aG docker ${local.workspace_user} + newgrp docker + - chown -R ${local.workspace_user}:${local.workspace_user} /home/${local.workspace_user} + - ["su", "-", "${local.workspace_user}", "-c", "export CODER_AGENT_TOKEN=${coder_agent.main.token} && echo ${base64encode(coder_agent.main.init_script)} | base64 -d | sh"] +EOF + } + + limits = { + cpu = data.coder_parameter.cpu.value + memory = "${data.coder_parameter.cpu.value}GiB" + } + + device { + name = "home" + type = "disk" + properties = { + path = "/home/${local.workspace_user}" + pool = local.pool + source = incus_volume.home.name + } + } + + device { + name = "docker" + type = "disk" + properties = { + path = "/var/lib/docker" + pool = local.pool + source = incus_volume.docker.name + } + } + + device { + name = "root" + type = "disk" + properties = { + path = "/" + pool = local.pool + } + } +} + +locals { + workspace_user = lower(data.coder_workspace.me.owner) + pool = "coder" +}