From 7ab2d50edb320b4f00ba5b86a823289dbe1a47ae Mon Sep 17 00:00:00 2001 From: mossylion <222695950+mossylion@users.noreply.github.com> Date: Tue, 30 Sep 2025 16:57:58 +0100 Subject: [PATCH 1/3] Add Scaleway-instance template for scaleway compute instances --- .icons/scaleway.svg | 1 + registry/mossylion/.images/avatar.png | Bin 0 -> 21077 bytes registry/mossylion/README.md | 15 + .../templates/scaleway-instance/README.md | 156 ++++++ .../cloud-init/cloud-config.yaml.tftpl | 35 ++ .../cloud-init/userdata.sh.tftpl | 2 + .../templates/scaleway-instance/main.tf | 271 +++++++++++ .../scaleway-instance/scaleway-config.json | 450 ++++++++++++++++++ 8 files changed, 930 insertions(+) create mode 100644 .icons/scaleway.svg create mode 100644 registry/mossylion/.images/avatar.png create mode 100644 registry/mossylion/README.md create mode 100644 registry/mossylion/templates/scaleway-instance/README.md create mode 100644 registry/mossylion/templates/scaleway-instance/cloud-init/cloud-config.yaml.tftpl create mode 100644 registry/mossylion/templates/scaleway-instance/cloud-init/userdata.sh.tftpl create mode 100644 registry/mossylion/templates/scaleway-instance/main.tf create mode 100644 registry/mossylion/templates/scaleway-instance/scaleway-config.json diff --git a/.icons/scaleway.svg b/.icons/scaleway.svg new file mode 100644 index 000000000..e5d0f39f7 --- /dev/null +++ b/.icons/scaleway.svg @@ -0,0 +1 @@ + diff --git a/registry/mossylion/.images/avatar.png b/registry/mossylion/.images/avatar.png new file mode 100644 index 0000000000000000000000000000000000000000..a7f00f17998e4a6c83810c436e11bb1d4d2e759e GIT binary patch literal 21077 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 **API Keys** in the Scaleway Console + - Create a new API key + - Note down the **Access Key** and **Secret Key** + - Copy your **Project ID** from the project settings + - Give permissions for **BlockStorageFullAccess**, **ProjectReadOnly**, **InstancesFullAccess** as a starting point + +## Architecture + +This template creates the following resources for each workspace: + +### Persistent Resources + +- **Block Volume**: Mounted as user's home directory (preserves all data, configs, and projects) + +### Ephemeral Resources (destroyed when workspace stops) + +- **Scaleway Instance**: Virtual machine created fresh on each workspace start +- **IPv4 Address**: Routed IPv4 address assigned dynamically +- **IPv6 Address**: Routed IPv6 address assigned dynamically +- **Cloud-init Configuration**: Automated setup of the Coder agent and persistent storage mounting + +## Configuration Options + +### Region Selection + +Choose from three available regions: + +- **France - Paris (fr-par)**: Default, lowest latency for European users +- **Netherlands - Amsterdam (nl-ams)**: Alternative European location +- **Poland - Warsaw (pl-waw)**: Eastern European option + +### Instance Types + +The template supports a comprehensive range of Scaleway instance types: + +#### Development Instances + +- **STARDUST1-S**: 1 CPU, 1GB RAM - Basic development +- **DEV1-S/M/L/XL**: 2-4 CPUs, 2-12GB RAM - Standard development + +#### Production Instances + +- **ENT1 Series**: 2-96 CPUs, 8-384GB RAM - Enterprise workloads +- **GP1 Series**: 4-48 CPUs, 16-256GB RAM - General purpose +- **PRO2 Series**: 2-32 CPUs, 8-128GB RAM - Professional workloads + +#### Specialized Instances + +- **L4 Series**: GPU-enabled instances for AI/ML workloads +- **COPARM1 Series**: ARM64 architecture for specific use cases + +### Operating System Options + +- **Debian 13 (Trixie)**: Latest Debian release +- **Debian 12 (Bookworm)**: Stable Debian LTS +- **Ubuntu 24.04 (Noble)**: Latest Ubuntu LTS +- **Fedora 41**: Cutting-edge features and packages + +### Storage Configuration + +- **Home Directory Size**: 10-500GB adjustable via slider (your entire home directory) +- **IOPS**: 5,000 or 15,000 IOPS options for performance tuning + +## Template Components + +### Included Tools + +- **VS Code Server**: Browser-based IDE with full extension support +- **System Monitoring**: CPU, RAM, and disk usage metrics +- **Dotfiles Support**: Automatic dotfiles synchronization on workspace start +- **Custom Environment Variables**: Pre-configured welcome message + +### Cloud-init Setup + +The template uses cloud-init for: + +- Automatic Coder agent installation and configuration +- User account setup with proper permissions +- Persistent home directory mounting (automatic disk partitioning and filesystem creation) +- Development tools initialization + +## Usage + +### Creating a Workspace + +1. **Select Template**: Choose "Scaleway Instance" from your Coder templates +2. **Configure Region**: Pick your preferred Scaleway region +3. **Choose Instance**: Select instance type based on your performance needs +4. **Select OS**: Pick your preferred operating system +5. **Set Home Directory Size**: Adjust storage size (10-500GB) for your persistent home directory +6. **Create**: Launch your workspace + +### Managing Costs + +- **VM instances are destroyed** when workspace stops (zero compute costs when not in use) +- **IP addresses are released** when workspace stops (no static IP charges) +- **Home directory persists** on dedicated block volume (small storage cost only) +- **Fresh OS** on each workspace start with persistent user data +- Choose appropriate instance sizes for your workload requirements + +## Customization + +### Extending the Template + +You can customize this template by: + +1. **Adding Software**: Modify cloud-init scripts to install additional tools +2. **Custom Modules**: Include additional Coder modules from the registry +3. **Network Configuration**: Adjust security groups or network settings +4. **Startup Scripts**: Add custom initialization logic + +## Maintenance + +### Updating Instance Types + +To update the available instance types, regenerate the `scaleway-config.json` file: + +```bash +scw instance server-type list -o json | jq 'map({name, cpu, gpu, ram, arch})' > scaleway-config.json.json +``` + +This pulls the latest instance types from Scaleway and formats them for use in the template. + +## References + +- [Scaleway Documentation](https://www.scaleway.com/en/docs/) +- [Scaleway Instance Types](https://www.scaleway.com/en/pricing/#instances) +- [Coder Templates Documentation](https://coder.com/docs/templates) +- [Terraform Scaleway Provider](https://registry.terraform.io/providers/scaleway/scaleway/latest/docs) diff --git a/registry/mossylion/templates/scaleway-instance/cloud-init/cloud-config.yaml.tftpl b/registry/mossylion/templates/scaleway-instance/cloud-init/cloud-config.yaml.tftpl new file mode 100644 index 000000000..3aeb35ce0 --- /dev/null +++ b/registry/mossylion/templates/scaleway-instance/cloud-init/cloud-config.yaml.tftpl @@ -0,0 +1,35 @@ +#cloud-config +cloud_final_modules: + - [scripts-user, always] +hostname: ${hostname} +users: + - name: ${linux_user} + sudo: ALL=(ALL) NOPASSWD:ALL + shell: /bin/bash + +# Setup persistent storage disk +disk_setup: + /dev/sdb: + table_type: gpt + layout: true + overwrite: false + +fs_setup: + - label: persistent-home + filesystem: ext4 + device: /dev/sdb1 + partition: auto + +mounts: + - ["/dev/sdb1", "/home/${linux_user}", "ext4", "defaults", "0", "2"] + +# Fix ownership after mounting +runcmd: + - chown -R ${linux_user}:${linux_user} /home/${linux_user} + - chmod 755 /home/${linux_user} + +# Automatically grow the partition +growpart: + mode: auto + devices: ['/'] + ignore_growroot_disabled: false diff --git a/registry/mossylion/templates/scaleway-instance/cloud-init/userdata.sh.tftpl b/registry/mossylion/templates/scaleway-instance/cloud-init/userdata.sh.tftpl new file mode 100644 index 000000000..2070bc0a7 --- /dev/null +++ b/registry/mossylion/templates/scaleway-instance/cloud-init/userdata.sh.tftpl @@ -0,0 +1,2 @@ +#!/bin/bash +sudo -u '${linux_user}' CODER_AGENT_TOKEN=${coder_agent_token} sh -c '${init_script}' diff --git a/registry/mossylion/templates/scaleway-instance/main.tf b/registry/mossylion/templates/scaleway-instance/main.tf new file mode 100644 index 000000000..041bf123e --- /dev/null +++ b/registry/mossylion/templates/scaleway-instance/main.tf @@ -0,0 +1,271 @@ + +terraform { + required_providers { + coder = { + source = "coder/coder" + version = "~> 2" + } + scaleway = { + source = "scaleway/scaleway" + version = "~> 2" + } + cloudinit = { + source = "hashicorp/cloudinit" + version = "~> 2" + } + } + required_version = ">= 1.0" +} + +provider "scaleway" { + access_key = var.access_key + secret_key = var.secret_key + region = data.coder_parameter.region.value +} + +locals { + hostname = lower(data.coder_workspace.me.name) + linux_user = "coder" +} + +data "cloudinit_config" "user_data" { + gzip = false + base64_encode = false + + boundary = "//" + + part { + filename = "cloud-config.yaml" + content_type = "text/cloud-config" + + content = templatefile("${path.module}/cloud-init/cloud-config.yaml.tftpl", { + hostname = local.hostname + linux_user = local.linux_user + }) + } + + part { + filename = "userdata.sh" + content_type = "text/x-shellscript" + + content = templatefile("${path.module}/cloud-init/userdata.sh.tftpl", { + linux_user = local.linux_user + init_script = coder_agent.main.init_script + coder_agent_token = coder_agent.main.token + }) + } +} +data "coder_provisioner" "me" {} + +data "coder_workspace" "me" {} + +resource "coder_agent" "main" { + arch = data.coder_provisioner.me.arch + os = data.coder_provisioner.me.os + auth = "token" + + 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 = "Disk Usage" + key = "1_disk_usage" + script = "coder stat disk" + interval = 10 + timeout = 1 + } +} + +module "code-server" { + source = "registry.coder.com/modules/code-server/coder" + version = "1.3.1" + agent_id = coder_agent.main.id +} + +# Runs a script at workspace start/stop or on a cron schedule +# details: https://registry.terraform.io/providers/coder/coder/latest/docs/resources/script + +module "dotfiles" { + count = data.coder_workspace.me.start_count + source = "registry.coder.com/coder/dotfiles/coder" + version = "1.2.1" + agent_id = coder_agent.main.id +} + +data "coder_parameter" "region" { + name = "Scaleway Region" + description = "Region to deploy server into" + type = "string" + default = "fr-par" + option { + name = "France - Paris (fr-par)" + value = "fr-par" + icon = "/emojis/1f1eb-1f1f7.png" + } + option { + name = "Netherlands - Amsterdam (nl-ams)" + value = "nl-ams" + icon = "/emojis/1f1f3-1f1f1.png" + } + option { + name = "Poland - Warsaw (pl-waw)" + value = "pl-waw" + icon = "/emojis/1f1f5-1f1f1.png" + } +} + +data "coder_parameter" "base_image" { + name = "Image" + description = "Which base image would you like to use?" + type = "string" + form_type = "radio" + default = "debian_trixie" + + option { + name = "Debian 13 (Trixie)" + value = "debian_trixie" + icon = "/icon/debian.svg" + } + + option { + name = "Debian 12 (Bookworm)" + value = "debian_bookworm" + icon = "/icon/debian.svg" + } + + option { + name = "Ubuntu 24.04 (Noble)" + value = "ubuntu_noble" + icon = "/icon/fedora.svg" + } + + option { + name = "Fedora 41" + value = "fedora_41" + icon = "/icon/fedora.svg" + } +} + +data "coder_parameter" "disk_size" { + name = "Disk Size" + type = "number" + form_type = "slider" + default = "10" + order = 8 + validation { + min = 10 + max = 500 + monotonic = "increasing" + } +} + +locals { + scaleway_config_raw = jsondecode(file("${path.module}/scaleway-config.json")) + + scaleway_instance_options = { + for instance in local.scaleway_config_raw : + instance.name => { + name = "${instance.name} (${instance.cpu} CPU, ${instance.gpu} GPU, ${floor(instance.ram / 1073741824)} GB RAM)" + value = instance.name + } + } +} + +data "coder_parameter" "instance_size" { + name = "instance_size" + display_name = "Instance Size" + description = "Which Instance Size should be used?" + default = "STARDUST1-S" + type = "string" + icon = "/icon/memory.svg" + mutable = false + form_type = "dropdown" + + dynamic "option" { + for_each = local.scaleway_instance_options + content { + name = option.value.name + value = option.value.value + } + } +} + +data "coder_parameter" "volume_iops" { + name = "Volume IOPS" + description = "IOPS to provision for disk" + type = "number" + default = 5000 + option { + name = "5000" + value = 5000 + } + option { + name = "15000" + value = 15000 + } +} + +resource "scaleway_instance_server" "workspace" { + count = data.coder_workspace.me.start_count + name = data.coder_workspace.me.name + type = data.coder_parameter.instance_size.value + image = data.coder_parameter.base_image.value + ip_ids = [scaleway_instance_ip.server_ip[0].id, scaleway_instance_ip.v4_server_ip[0].id] + project_id = var.project_id + user_data = { + cloud-init = data.cloudinit_config.user_data.rendered + } + additional_volume_ids = [scaleway_block_volume.persistent_storage.id] +} + +resource "scaleway_block_volume" "persistent_storage" { + iops = data.coder_parameter.volume_iops.value + name = "${data.coder_workspace.me.name}-home" + size_in_gb = data.coder_parameter.disk_size.value + project_id = var.project_id +} + + +resource "scaleway_instance_ip" "server_ip" { + count = data.coder_workspace.me.start_count + type = "routed_ipv6" + project_id = var.project_id +} + +resource "scaleway_instance_ip" "v4_server_ip" { + count = data.coder_workspace.me.start_count + type = "routed_ipv4" + project_id = var.project_id +} + +variable "project_id" { + type = string + description = "ID of the project to deploy into" +} + +variable "access_key" { + type = string + description = "Access key to use to deploy" +} + +variable "secret_key" { + type = string + description = "Secret key to use to deploy" +} + +variable "region" { + type = string + description = "Region to deploy into" +} diff --git a/registry/mossylion/templates/scaleway-instance/scaleway-config.json b/registry/mossylion/templates/scaleway-instance/scaleway-config.json new file mode 100644 index 000000000..e48fb05c6 --- /dev/null +++ b/registry/mossylion/templates/scaleway-instance/scaleway-config.json @@ -0,0 +1,450 @@ +[ + { + "name": "COPARM1-2C-8G", + "cpu": 2, + "gpu": 0, + "ram": 8589934592, + "arch": "arm64" + }, + { + "name": "COPARM1-4C-16G", + "cpu": 4, + "gpu": 0, + "ram": 17179869184, + "arch": "arm64" + }, + { + "name": "COPARM1-8C-32G", + "cpu": 8, + "gpu": 0, + "ram": 34359738368, + "arch": "arm64" + }, + { + "name": "COPARM1-16C-64G", + "cpu": 16, + "gpu": 0, + "ram": 68719476736, + "arch": "arm64" + }, + { + "name": "COPARM1-32C-128G", + "cpu": 32, + "gpu": 0, + "ram": 137438953472, + "arch": "arm64" + }, + { + "name": "DEV1-S", + "cpu": 2, + "gpu": 0, + "ram": 2147483648, + "arch": "x86_64" + }, + { + "name": "DEV1-M", + "cpu": 3, + "gpu": 0, + "ram": 4294967296, + "arch": "x86_64" + }, + { + "name": "DEV1-L", + "cpu": 4, + "gpu": 0, + "ram": 8589934592, + "arch": "x86_64" + }, + { + "name": "DEV1-XL", + "cpu": 4, + "gpu": 0, + "ram": 12884901888, + "arch": "x86_64" + }, + { + "name": "ENT1-XXS", + "cpu": 2, + "gpu": 0, + "ram": 8589934592, + "arch": "x86_64" + }, + { + "name": "ENT1-XS", + "cpu": 4, + "gpu": 0, + "ram": 17179869184, + "arch": "x86_64" + }, + { + "name": "ENT1-S", + "cpu": 8, + "gpu": 0, + "ram": 34359738368, + "arch": "x86_64" + }, + { + "name": "ENT1-M", + "cpu": 16, + "gpu": 0, + "ram": 68719476736, + "arch": "x86_64" + }, + { + "name": "ENT1-L", + "cpu": 32, + "gpu": 0, + "ram": 137438953472, + "arch": "x86_64" + }, + { + "name": "ENT1-XL", + "cpu": 64, + "gpu": 0, + "ram": 274877906944, + "arch": "x86_64" + }, + { + "name": "ENT1-2XL", + "cpu": 96, + "gpu": 0, + "ram": 412316860416, + "arch": "x86_64" + }, + { + "name": "GP1-XS", + "cpu": 4, + "gpu": 0, + "ram": 17179869184, + "arch": "x86_64" + }, + { + "name": "GP1-S", + "cpu": 8, + "gpu": 0, + "ram": 34359738368, + "arch": "x86_64" + }, + { + "name": "GP1-M", + "cpu": 16, + "gpu": 0, + "ram": 68719476736, + "arch": "x86_64" + }, + { + "name": "GP1-L", + "cpu": 32, + "gpu": 0, + "ram": 137438953472, + "arch": "x86_64" + }, + { + "name": "GP1-XL", + "cpu": 48, + "gpu": 0, + "ram": 274877906944, + "arch": "x86_64" + }, + { + "name": "L4-1-24G", + "cpu": 8, + "gpu": 1, + "ram": 51539607552, + "arch": "x86_64" + }, + { + "name": "L4-2-24G", + "cpu": 16, + "gpu": 2, + "ram": 103079215104, + "arch": "x86_64" + }, + { + "name": "L4-4-24G", + "cpu": 32, + "gpu": 4, + "ram": 206158430208, + "arch": "x86_64" + }, + { + "name": "L4-8-24G", + "cpu": 64, + "gpu": 8, + "ram": 412316860416, + "arch": "x86_64" + }, + { + "name": "PLAY2-PICO", + "cpu": 1, + "gpu": 0, + "ram": 2147483648, + "arch": "x86_64" + }, + { + "name": "PLAY2-NANO", + "cpu": 2, + "gpu": 0, + "ram": 4294967296, + "arch": "x86_64" + }, + { + "name": "PLAY2-MICRO", + "cpu": 4, + "gpu": 0, + "ram": 8589934592, + "arch": "x86_64" + }, + { + "name": "POP2-HC-2C-4G", + "cpu": 2, + "gpu": 0, + "ram": 4294967296, + "arch": "x86_64" + }, + { + "name": "POP2-2C-8G", + "cpu": 2, + "gpu": 0, + "ram": 8589934592, + "arch": "x86_64" + }, + { + "name": "POP2-HM-2C-16G", + "cpu": 2, + "gpu": 0, + "ram": 17179869184, + "arch": "x86_64" + }, + { + "name": "POP2-HC-4C-8G", + "cpu": 4, + "gpu": 0, + "ram": 8589934592, + "arch": "x86_64" + }, + { + "name": "POP2-4C-16G", + "cpu": 4, + "gpu": 0, + "ram": 17179869184, + "arch": "x86_64" + }, + { + "name": "POP2-2C-8G-WIN", + "cpu": 2, + "gpu": 0, + "ram": 8589934592, + "arch": "x86_64" + }, + { + "name": "POP2-HM-4C-32G", + "cpu": 4, + "gpu": 0, + "ram": 34359738368, + "arch": "x86_64" + }, + { + "name": "POP2-HC-8C-16G", + "cpu": 8, + "gpu": 0, + "ram": 17179869184, + "arch": "x86_64" + }, + { + "name": "POP2-HN-3", + "cpu": 2, + "gpu": 0, + "ram": 4294967296, + "arch": "x86_64" + }, + { + "name": "POP2-8C-32G", + "cpu": 8, + "gpu": 0, + "ram": 34359738368, + "arch": "x86_64" + }, + { + "name": "POP2-4C-16G-WIN", + "cpu": 4, + "gpu": 0, + "ram": 17179869184, + "arch": "x86_64" + }, + { + "name": "POP2-HM-8C-64G", + "cpu": 8, + "gpu": 0, + "ram": 68719476736, + "arch": "x86_64" + }, + { + "name": "POP2-HC-16C-32G", + "cpu": 16, + "gpu": 0, + "ram": 34359738368, + "arch": "x86_64" + }, + { + "name": "POP2-HN-5", + "cpu": 4, + "gpu": 0, + "ram": 8589934592, + "arch": "x86_64" + }, + { + "name": "POP2-16C-64G", + "cpu": 16, + "gpu": 0, + "ram": 68719476736, + "arch": "x86_64" + }, + { + "name": "POP2-8C-32G-WIN", + "cpu": 8, + "gpu": 0, + "ram": 34359738368, + "arch": "x86_64" + }, + { + "name": "POP2-HN-10", + "cpu": 4, + "gpu": 0, + "ram": 8589934592, + "arch": "x86_64" + }, + { + "name": "POP2-HM-16C-128G", + "cpu": 16, + "gpu": 0, + "ram": 137438953472, + "arch": "x86_64" + }, + { + "name": "POP2-HC-32C-64G", + "cpu": 32, + "gpu": 0, + "ram": 68719476736, + "arch": "x86_64" + }, + { + "name": "POP2-32C-128G", + "cpu": 32, + "gpu": 0, + "ram": 137438953472, + "arch": "x86_64" + }, + { + "name": "POP2-HC-48C-96G", + "cpu": 48, + "gpu": 0, + "ram": 103079215104, + "arch": "x86_64" + }, + { + "name": "POP2-16C-64G-WIN", + "cpu": 16, + "gpu": 0, + "ram": 68719476736, + "arch": "x86_64" + }, + { + "name": "POP2-HM-32C-256G", + "cpu": 32, + "gpu": 0, + "ram": 274877906944, + "arch": "x86_64" + }, + { + "name": "POP2-HC-64C-128G", + "cpu": 64, + "gpu": 0, + "ram": 137438953472, + "arch": "x86_64" + }, + { + "name": "POP2-48C-192G", + "cpu": 48, + "gpu": 0, + "ram": 206158430208, + "arch": "x86_64" + }, + { + "name": "POP2-64C-256G", + "cpu": 64, + "gpu": 0, + "ram": 274877906944, + "arch": "x86_64" + }, + { + "name": "POP2-HM-48C-384G", + "cpu": 48, + "gpu": 0, + "ram": 412316860416, + "arch": "x86_64" + }, + { + "name": "POP2-32C-128G-WIN", + "cpu": 32, + "gpu": 0, + "ram": 137438953472, + "arch": "x86_64" + }, + { + "name": "POP2-HM-64C-512G", + "cpu": 64, + "gpu": 0, + "ram": 549755813888, + "arch": "x86_64" + }, + { + "name": "PRO2-XXS", + "cpu": 2, + "gpu": 0, + "ram": 8589934592, + "arch": "x86_64" + }, + { + "name": "PRO2-XS", + "cpu": 4, + "gpu": 0, + "ram": 17179869184, + "arch": "x86_64" + }, + { + "name": "PRO2-S", + "cpu": 8, + "gpu": 0, + "ram": 34359738368, + "arch": "x86_64" + }, + { + "name": "PRO2-M", + "cpu": 16, + "gpu": 0, + "ram": 68719476736, + "arch": "x86_64" + }, + { + "name": "PRO2-L", + "cpu": 32, + "gpu": 0, + "ram": 137438953472, + "arch": "x86_64" + }, + { + "name": "RENDER-S", + "cpu": 10, + "gpu": 1, + "ram": 45097156608, + "arch": "x86_64" + }, + { + "name": "STARDUST1-S", + "cpu": 1, + "gpu": 0, + "ram": 1073741824, + "arch": "x86_64" + } +] From 87e5a49e5c75ee052beb8675b40a5844a186852f Mon Sep 17 00:00:00 2001 From: mossylion <222695950+mossylion@users.noreply.github.com> Date: Tue, 30 Sep 2025 17:15:25 +0100 Subject: [PATCH 2/3] Scaleway template - Additional QoL fixes --- .../cloud-init/userdata.sh.tftpl | 2 +- .../templates/scaleway-instance/main.tf | 61 +++++++++++++++---- 2 files changed, 51 insertions(+), 12 deletions(-) diff --git a/registry/mossylion/templates/scaleway-instance/cloud-init/userdata.sh.tftpl b/registry/mossylion/templates/scaleway-instance/cloud-init/userdata.sh.tftpl index 2070bc0a7..031628dab 100644 --- a/registry/mossylion/templates/scaleway-instance/cloud-init/userdata.sh.tftpl +++ b/registry/mossylion/templates/scaleway-instance/cloud-init/userdata.sh.tftpl @@ -1,2 +1,2 @@ #!/bin/bash -sudo -u '${linux_user}' CODER_AGENT_TOKEN=${coder_agent_token} sh -c '${init_script}' +sudo -u '${linux_user}' sh -c 'CODER_AGENT_TOKEN="${coder_agent_token}" ${init_script}' diff --git a/registry/mossylion/templates/scaleway-instance/main.tf b/registry/mossylion/templates/scaleway-instance/main.tf index 041bf123e..450d7fdb3 100644 --- a/registry/mossylion/templates/scaleway-instance/main.tf +++ b/registry/mossylion/templates/scaleway-instance/main.tf @@ -59,11 +59,22 @@ data "coder_provisioner" "me" {} data "coder_workspace" "me" {} +data "coder_workspace_owner" "me" {} + resource "coder_agent" "main" { arch = data.coder_provisioner.me.arch os = data.coder_provisioner.me.os auth = "token" + startup_script = <<-EOT + set -e + + # Install additional tools or run commands at workspace startup + # Uncomment and customize as needed: + # sudo apt-get update + # sudo apt-get install -y build-essential + EOT + metadata { display_name = "CPU Usage" key = "0_cpu_usage" @@ -82,9 +93,9 @@ resource "coder_agent" "main" { metadata { display_name = "Disk Usage" key = "1_disk_usage" - script = "coder stat disk" - interval = 10 - timeout = 1 + script = "coder stat disk --path /home/${local.linux_user}" + interval = 600 + timeout = 30 } } @@ -92,6 +103,8 @@ module "code-server" { source = "registry.coder.com/modules/code-server/coder" version = "1.3.1" agent_id = coder_agent.main.id + order = 1 + folder = "/home/${local.linux_user}" } # Runs a script at workspace start/stop or on a cron schedule @@ -104,6 +117,37 @@ module "dotfiles" { agent_id = coder_agent.main.id } +resource "coder_metadata" "workspace_info" { + count = data.coder_workspace.me.start_count + resource_id = scaleway_instance_server.workspace[0].id + + item { + key = "region" + value = data.coder_parameter.region.value + } + item { + key = "instance type" + value = scaleway_instance_server.workspace[0].type + } + item { + key = "image" + value = data.coder_parameter.base_image.value + } +} + +resource "coder_metadata" "volume_info" { + resource_id = scaleway_block_volume.persistent_storage.id + + item { + key = "size" + value = "${scaleway_block_volume.persistent_storage.size_in_gb} GiB" + } + item { + key = "iops" + value = scaleway_block_volume.persistent_storage.iops + } +} + data "coder_parameter" "region" { name = "Scaleway Region" description = "Region to deploy server into" @@ -148,7 +192,7 @@ data "coder_parameter" "base_image" { option { name = "Ubuntu 24.04 (Noble)" value = "ubuntu_noble" - icon = "/icon/fedora.svg" + icon = "/icon/ubuntu.svg" } option { @@ -219,7 +263,7 @@ data "coder_parameter" "volume_iops" { resource "scaleway_instance_server" "workspace" { count = data.coder_workspace.me.start_count - name = data.coder_workspace.me.name + name = "coder-${lower(data.coder_workspace_owner.me.name)}-${lower(data.coder_workspace.me.name)}" type = data.coder_parameter.instance_size.value image = data.coder_parameter.base_image.value ip_ids = [scaleway_instance_ip.server_ip[0].id, scaleway_instance_ip.v4_server_ip[0].id] @@ -232,7 +276,7 @@ resource "scaleway_instance_server" "workspace" { resource "scaleway_block_volume" "persistent_storage" { iops = data.coder_parameter.volume_iops.value - name = "${data.coder_workspace.me.name}-home" + name = "coder-${lower(data.coder_workspace_owner.me.name)}-${lower(data.coder_workspace.me.name)}-home" size_in_gb = data.coder_parameter.disk_size.value project_id = var.project_id } @@ -264,8 +308,3 @@ variable "secret_key" { type = string description = "Secret key to use to deploy" } - -variable "region" { - type = string - description = "Region to deploy into" -} From 008569947c4d304fcc50e7b7fa7d37caaf801d16 Mon Sep 17 00:00:00 2001 From: mossylion <222695950+mossylion@users.noreply.github.com> Date: Fri, 3 Oct 2025 10:16:27 +0100 Subject: [PATCH 3/3] fix: export CODER_AGENT_TOKEN in scaleway template The agent token was being set as a shell variable but not exported to the environment, causing the coder agent to fail with "CODER_AGENT_TOKEN must be set" error during cloud-init execution. --- .../templates/scaleway-instance/cloud-init/userdata.sh.tftpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/registry/mossylion/templates/scaleway-instance/cloud-init/userdata.sh.tftpl b/registry/mossylion/templates/scaleway-instance/cloud-init/userdata.sh.tftpl index 031628dab..72819ce99 100644 --- a/registry/mossylion/templates/scaleway-instance/cloud-init/userdata.sh.tftpl +++ b/registry/mossylion/templates/scaleway-instance/cloud-init/userdata.sh.tftpl @@ -1,2 +1,2 @@ #!/bin/bash -sudo -u '${linux_user}' sh -c 'CODER_AGENT_TOKEN="${coder_agent_token}" ${init_script}' +sudo -u '${linux_user}' sh -c 'export CODER_AGENT_TOKEN="${coder_agent_token}"; ${init_script}'