Chris2pi
Chris2pi
CCoder.com
Created by Chris2pi on 2/12/2025 in #help
newgrp not working in startup script
This might just be a Linux 101 issue but still can't work out why. We have a custom built AMI with Docker installed and want to grant the Coder user access to use Docker. Since the Coder user doesn't exist on the AMI yet I added the commands to the startup_script in resource "coder_agent" The script runs
newgrp docker
newgrp docker
and it doesn't appear to work. We run the same command in the terminal and it works. So maybe something strange is happening with the session?
resource "coder_agent" "dev" {
count = data.coder_workspace.me.start_count
arch = "amd64"
auth = "aws-instance-identity"
os = "linux"
startup_script_behavior = "blocking"
startup_script = <<-EOT
set -e

# Add any commands that should be executed at workspace startup (e.g install requirements, start a program, etc) here
# docker group already exists
sudo usermod -aG docker coder
newgrp docker
resource "coder_agent" "dev" {
count = data.coder_workspace.me.start_count
arch = "amd64"
auth = "aws-instance-identity"
os = "linux"
startup_script_behavior = "blocking"
startup_script = <<-EOT
set -e

# Add any commands that should be executed at workspace startup (e.g install requirements, start a program, etc) here
# docker group already exists
sudo usermod -aG docker coder
newgrp docker
9 replies
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