Chris2pi
Chris2pi
CCoder.com
Created by Chris2pi on 1/8/2025 in #help
Persistent AWS EBS/EC2 home directory
Problem—When I click restart in the coder web GUI, it recreates my workspace and causes the EBS volume to be recreated, causing me to lose all of the data. I understand why that is as a terraform recreate is happening. So, before I go down the rabbit hole of making custom scripts, etc., I just wanted to see if there was an out-of-the-box method from the coder. I found this doco - https://coder.com/docs/admin/templates/extending-templates/resource-persistence But it doesn't seem right for what I want. Napkin-style plan for what I think should happen - The user hits restart. Recreation happens, but the EBS is detached from the instance. A new instance spins up and attaches the EBS again. Source code based on this template - https://github.com/coder/coder/blob/main/examples/templates/aws-linux/main.tf
resource "aws_instance" "dev" {
ami = data.aws_ami.ubuntu.id
availability_zone = "${data.coder_parameter.region.value}a"
instance_type = data.coder_parameter.instance_type.value
subnet_id = "subnet-xxxxxxxxxxxxxxxx"
associate_public_ip_address = true

user_data = data.cloudinit_config.user_data.rendered

# Define the root volume storage
root_block_device {
volume_type = "gp3" # You can choose gp2, gp3, io1, etc.
volume_size = data.coder_parameter.disk_space.value # Specify the volume size in GB
encrypted = true # Encrypt the volume
delete_on_termination = true
}

tags = {
Name = "coder-${data.coder_workspace_owner.me.name}-${data.coder_workspace.me.name}"
# Required if you are using our example policy, see template README
Coder_Provisioned = "true"
}
lifecycle {
ignore_changes = [ami]
}
}
resource "aws_instance" "dev" {
ami = data.aws_ami.ubuntu.id
availability_zone = "${data.coder_parameter.region.value}a"
instance_type = data.coder_parameter.instance_type.value
subnet_id = "subnet-xxxxxxxxxxxxxxxx"
associate_public_ip_address = true

user_data = data.cloudinit_config.user_data.rendered

# Define the root volume storage
root_block_device {
volume_type = "gp3" # You can choose gp2, gp3, io1, etc.
volume_size = data.coder_parameter.disk_space.value # Specify the volume size in GB
encrypted = true # Encrypt the volume
delete_on_termination = true
}

tags = {
Name = "coder-${data.coder_workspace_owner.me.name}-${data.coder_workspace.me.name}"
# Required if you are using our example policy, see template README
Coder_Provisioned = "true"
}
lifecycle {
ignore_changes = [ami]
}
}
7 replies
CCoder.com
Created by Chris2pi on 11/24/2024 in #help
Creating a JupyterLab instance
It might be simple, but I can't get a JupyterLab instance going. The goal is to spin up an AWS EC2 instance. I can do that with VSCode without issue. I add the module from here but get a few errors on launch - https://registry.coder.com/modules/jupyterlab Then I see this doco and it seems to be what the module is meant to do? https://coder.com/docs/admin/templates/extending-templates/web-ides#jupyterlab Can't get that working either. I suspect I am confusing the above doco and just using the module incorrectly and mixing it with the vscode out of the box template. Code below
resource "coder_agent" "main" {
os = "linux"
arch = "amd64"
dir = "/home/coder"

startup_script = <<-EOT
set -e

pip3 install jupyterlab

# install and start JupyterLab
~/.local/bin/jupyter lab --ServerApp.base_url=/@${data.coder_workspace_owner.me.name}/${data.coder_workspace.me.name}/apps/jupyter --ServerApp.token='' --ip='*'
EOT
}

module "jupyterlab" {
source = "registry.coder.com/modules/jupyterlab/coder"
version = "1.0.23"
agent_id = coder_agent.main.id
}

locals {
linux_user = "coder"
user_data = <<-EOT
Content-Type: multipart/mixed; boundary="//"
MIME-Version: 1.0

--//
Content-Type: text/cloud-config; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="cloud-config.txt"

#cloud-config
cloud_final_modules:
- [scripts-user, always]
hostname: ${lower(data.coder_workspace.me.name)}
users:
- name: ${local.linux_user}
sudo: ALL=(ALL) NOPASSWD:ALL
shell: /bin/bash

--//
Content-Type: text/x-shellscript; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="userdata.txt"

#!/bin/bash
sudo -u ${local.linux_user} sh -c '${try(coder_agent.main.init_script, "")}'
--//--
EOT
}
resource "coder_agent" "main" {
os = "linux"
arch = "amd64"
dir = "/home/coder"

startup_script = <<-EOT
set -e

pip3 install jupyterlab

# install and start JupyterLab
~/.local/bin/jupyter lab --ServerApp.base_url=/@${data.coder_workspace_owner.me.name}/${data.coder_workspace.me.name}/apps/jupyter --ServerApp.token='' --ip='*'
EOT
}

module "jupyterlab" {
source = "registry.coder.com/modules/jupyterlab/coder"
version = "1.0.23"
agent_id = coder_agent.main.id
}

locals {
linux_user = "coder"
user_data = <<-EOT
Content-Type: multipart/mixed; boundary="//"
MIME-Version: 1.0

--//
Content-Type: text/cloud-config; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="cloud-config.txt"

#cloud-config
cloud_final_modules:
- [scripts-user, always]
hostname: ${lower(data.coder_workspace.me.name)}
users:
- name: ${local.linux_user}
sudo: ALL=(ALL) NOPASSWD:ALL
shell: /bin/bash

--//
Content-Type: text/x-shellscript; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="userdata.txt"

#!/bin/bash
sudo -u ${local.linux_user} sh -c '${try(coder_agent.main.init_script, "")}'
--//--
EOT
}
Overall a end to end template would be nice. Happy to put one together once I understand it better.
7 replies