terraform { required_providers { coder = { source = "coder/coder" } aws = { source = "hashicorp/aws" } } } # Last updated 2023-03-14 # aws ec2 describe-regions | jq -r '[.Regions[].RegionName] | sort' data "coder_parameter" "region" { name = "region" display_name = "Region" description = "The region to deploy the workspace in." default = "us-east-1" mutable = false option { name = "Asia Pacific (Tokyo)" value = "ap-northeast-1" icon = "/emojis/1f1ef-1f1f5.png" } option { name = "Asia Pacific (Seoul)" value = "ap-northeast-2" icon = "/emojis/1f1f0-1f1f7.png" } option { name = "Asia Pacific (Osaka)" value = "ap-northeast-3" icon = "/emojis/1f1ef-1f1f5.png" } option { name = "Asia Pacific (Mumbai)" value = "ap-south-1" icon = "/emojis/1f1ee-1f1f3.png" } option { name = "Asia Pacific (Singapore)" value = "ap-southeast-1" icon = "/emojis/1f1f8-1f1ec.png" } option { name = "Asia Pacific (Sydney)" value = "ap-southeast-2" icon = "/emojis/1f1e6-1f1fa.png" } option { name = "Canada (Central)" value = "ca-central-1" icon = "/emojis/1f1e8-1f1e6.png" } option { name = "EU (Frankfurt)" value = "eu-central-1" icon = "/emojis/1f1ea-1f1fa.png" } option { name = "EU (Stockholm)" value = "eu-north-1" icon = "/emojis/1f1ea-1f1fa.png" } option { name = "EU (Ireland)" value = "eu-west-1" icon = "/emojis/1f1ea-1f1fa.png" } option { name = "EU (London)" value = "eu-west-2" icon = "/emojis/1f1ea-1f1fa.png" } option { name = "EU (Paris)" value = "eu-west-3" icon = "/emojis/1f1ea-1f1fa.png" } option { name = "South America (São Paulo)" value = "sa-east-1" icon = "/emojis/1f1e7-1f1f7.png" } option { name = "US East (N. Virginia)" value = "us-east-1" icon = "/emojis/1f1fa-1f1f8.png" } option { name = "US East (Ohio)" value = "us-east-2" icon = "/emojis/1f1fa-1f1f8.png" } option { name = "US West (N. California)" value = "us-west-1" icon = "/emojis/1f1fa-1f1f8.png" } option { name = "US West (Oregon)" value = "us-west-2" icon = "/emojis/1f1fa-1f1f8.png" } } data "coder_parameter" "instance_type" { name = "instance_type" display_name = "Instance type" description = "What instance type should your workspace use?" default = "t3.micro" mutable = false option { name = "2 vCPU, 1 GiB RAM" value = "t3.micro" } option { name = "2 vCPU, 2 GiB RAM" value = "t3.small" } option { name = "2 vCPU, 4 GiB RAM" value = "t3.medium" } option { name = "2 vCPU, 8 GiB RAM" value = "t3.large" } option { name = "4 vCPU, 16 GiB RAM" value = "t3.xlarge" } option { name = "8 vCPU, 32 GiB RAM" value = "t3.2xlarge" } } provider "aws" { region = data.coder_parameter.region.value } data "coder_workspace" "me" {} data "coder_workspace_owner" "me" {} data "aws_ami" "ubuntu" { most_recent = true filter { name = "name" values = ["ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*"] } filter { name = "virtualization-type" values = ["hvm"] } owners = ["099720109477"] # Canonical } resource "coder_agent" "dev" { count = data.coder_workspace.me.start_count arch = "amd64" auth = "aws-instance-identity" os = "linux" startup_script = <<-EOT set -e # Add any commands that should be executed at workspace startup (e.g install requirements, start a program, etc) here EOT metadata { key = "cpu" display_name = "CPU Usage" interval = 5 timeout = 5 script = "coder stat cpu" } metadata { key = "memory" display_name = "Memory Usage" interval = 5 timeout = 5 script = "coder stat mem" } metadata { key = "disk" display_name = "Disk Usage" interval = 600 # every 10 minutes timeout = 30 # df can take a while on large filesystems script = "coder stat disk --path $HOME" } } # See https://registry.coder.com/modules/code-server module "code-server" { count = data.coder_workspace.me.start_count source = "registry.coder.com/modules/code-server/coder" # This ensures that the latest version of the module gets downloaded, you can also pin the module version to prevent breaking changes in production. version = ">= 1.0.0" agent_id = coder_agent.dev[0].id order = 1 } # See https://registry.coder.com/modules/jetbrains-gateway module "jetbrains_gateway" { count = data.coder_workspace.me.start_count source = "registry.coder.com/modules/jetbrains-gateway/coder" # JetBrains IDEs to make available for the user to select jetbrains_ides = ["IU", "PY", "WS", "PS", "RD", "CL", "GO", "RM"] default = "IU" # Default folder to open when starting a JetBrains IDE folder = "/home/coder" # This ensures that the latest version of the module gets downloaded, you can also pin the module version to prevent breaking changes in production. version = ">= 1.0.0" agent_id = coder_agent.dev[0].id agent_name = "dev" order = 2 } 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 = try(coder_agent.dev[0].init_script, "") }) } } 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 user_data = data.cloudinit_config.user_data.rendered 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 "coder_metadata" "workspace_info" { resource_id = aws_instance.dev.id item { key = "region" value = data.coder_parameter.region.value } item { key = "instance type" value = aws_instance.dev.instance_type } item { key = "disk" value = "${aws_instance.dev.root_block_device[0].volume_size} GiB" } } resource "aws_ec2_instance_state" "dev" { instance_id = aws_instance.dev.id state = data.coder_workspace.me.transition == "start" ? "running" : "stopped" }