From 7e9b7fbf1439bce49f9de2e4e2b63e47530067e7 Mon Sep 17 00:00:00 2001 From: Muhammad Atif Ali Date: Thu, 9 Mar 2023 14:53:31 +0300 Subject: [PATCH 01/12] add fly.io example --- examples/templates/fly-docker-image/README.md | 37 +++ examples/templates/fly-docker-image/main.tf | 239 ++++++++++++++++++ 2 files changed, 276 insertions(+) create mode 100644 examples/templates/fly-docker-image/README.md create mode 100644 examples/templates/fly-docker-image/main.tf diff --git a/examples/templates/fly-docker-image/README.md b/examples/templates/fly-docker-image/README.md new file mode 100644 index 0000000000000..aef1ee1fea143 --- /dev/null +++ b/examples/templates/fly-docker-image/README.md @@ -0,0 +1,37 @@ +# Coder Docker Image fly.io Template + +This template provisions a [code-server](https://github.com/coder/code-server) instance on [fly.io](https://fly.io) using the [codercom/code-server](https://hub.docker.com/r/codercom/code-server) image. + +## Prerequisites + +- [flyctl](https://fly.io/docs/getting-started/installing-flyctl/) installed. +- [Coder](https://coder.com/) already setup and running with coder-cli installed locally. + +## Deploy + +1. Clone this repo and cd into `fly-docker-image` directory. +2. Add a secret or environment variable to your Coder deployment with the name `FLY_API_TOKEN` and the value of your fly.io API token. + > This is needed to deploy the workspace to fly.io. + +```shell +flyctl auth login +export FLY_API_TOKEN=$(flyctl auth token) +``` + +Add this to your Coder deployment's environment variables. (e.g. `/etc/coder.d/coder.env`) + +Or, If Coder is running as a fly.io app, you can set the secret directly: + +```shell +flyctl secrets set FLY_API_TOKEN=$(flyctl auth token) -a +# where is the name of the Coder app on fly.io +``` + +> Read our blog [post](coder.com/blog/deploying-coder-on-fly-io) to learn more about how to deploy Coder on fly.io. + +3. Run `coder templates create fly-docker-image` to create a template in Coder. +4. Create a new workspace from the template. + +This is all. You should now have a code-server instance running on fly.io. + +> Note: Change the image and the startup command to suit your needs. diff --git a/examples/templates/fly-docker-image/main.tf b/examples/templates/fly-docker-image/main.tf new file mode 100644 index 0000000000000..bbe765c7ee0a2 --- /dev/null +++ b/examples/templates/fly-docker-image/main.tf @@ -0,0 +1,239 @@ +resource "fly_app" "workspace" { + name = "coder-${data.coder_workspace.me.owner}-${lower(data.coder_workspace.me.name)}" + org = var.fly_org +} + +resource "fly_ip" "workspace-ip4" { + app = fly_app.workspace.name + type = "v4" +} + +resource "fly_ip" "workspace-ip6" { + app = fly_app.workspace.name + type = "v6" +} + +resource "fly_volume" "home-volume" { + app = fly_app.workspace.name + name = "coder_${data.coder_workspace.me.owner}_${lower(data.coder_workspace.me.name)}_home" + size = data.coder_parameter.volume-size.value + region = data.coder_parameter.region.value +} + +resource "fly_machine" "workspace" { + count = data.coder_workspace.me.start_count + app = fly_app.workspace.name + region = data.coder_parameter.region.value + name = data.coder_workspace.me.name + image = data.coder_parameter.docker-image.value + cpus = data.coder_parameter.cpu.value + memorymb = data.coder_parameter.memory.value * 1024 + env = { + CODER_AGENT_TOKEN = "${coder_agent.main.token}" + } + entrypoint = ["sh", "-c", replace(coder_agent.main.init_script, "/localhost|127\\.0\\.0\\.1/", "${fly_ip.workspace-ip4.address}")] # replace localhost with the IP of the workspace + services = [ + { + ports = [ + { + port = 443 + handlers = ["tls", "http"] + }, + { + port = 80 + handlers = ["http"] + } + + ] + protocol = "tcp", + "internal_port" = 80 + }, + { + ports = [ + { + port = 8080 + handlers = ["tls", "http"] + } + ] + protocol = "tcp", + "internal_port" = 8080 + } + ] + mounts = [ + { + volume = fly_volume.home-volume.id + path = "/home/coder" + } + ] +} + +variable "fly_org" { + type = string + default = "coder-409" + description = "The Fly.io organization to deploy the workspace in" +} + +data "coder_parameter" "docker-image" { + name = "Docker Image" + description = "The docker image to use for the workspace" + default = "codercom/code-server:latest" + icon = "https://raw.githubusercontent.com/matifali/logos/main/docker.svg" +} + +data "coder_parameter" "cpu" { + 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 (GB)" + description = "The amount of memory to allocate to the workspace in GB (1-8)" + type = "number" + default = "1" + icon = "/icon/memory.svg" + mutable = true + validation { + min = 1 + max = 8 + } +} + +data "coder_parameter" "volume-size" { + name = "Volume Size" + description = "The size of the volume to create for the workspace in GB (1-20)" + type = "number" + default = "3" + icon = "https://raw.githubusercontent.com/matifali/logos/main/database.svg" + validation { + min = 1 + max = 20 + } +} + +# You can see all available regions here: https://fly.io/docs/reference/regions/ +data "coder_parameter" "region" { + name = "Region" + description = "The region to deploy the workspace in" + default = "ams" + icon = "/emojis/1f30e.png" + option { + name = "Amsterdam, Netherlands" + value = "ams" + icon = "/emojis/1f1f3-1f1f1.png" + } + option { + name = "Frankfurt, Germany" + value = "fra" + icon = "/emojis/1f1e9-1f1ea.png" + } + option { + name = "Paris, France" + value = "cdg" + icon = "/emojis/1f1eb-1f1f7.png" + } + option { + name = "Denver, Colorado (US)" + value = "den" + icon = "/emojis/1f1fa-1f1f8.png" + } + option { + name = "Dallas, Texas (US)" + value = "dal" + icon = "/emojis/1f1fa-1f1f8.png" + } + option { + name = "Hong Kong" + value = "hkg" + icon = "/emojis/1f1ed-1f1f0.png" + } + option { + name = "Los Angeles, California (US)" + value = "lax" + icon = "/emojis/1f1fa-1f1f8.png" + } + option { + name = "London, United Kingdom" + value = "lhr" + icon = "/emojis/1f1ec-1f1e7.png" + } + option { + name = "Chennai, India" + value = "maa" + icon = "/emojis/1f1ee-1f1f3.png" + } + option { + name = "Tokyo, Japan" + value = "nrt" + icon = "/emojis/1f1ef-1f1f5.png" + } + option { + name = "Chicago, Illinois (US)" + value = "ord" + icon = "/emojis/1f1fa-1f1f8.png" + } + option { + name = "Seattle, Washington (US)" + value = "sea" + icon = "/emojis/1f1fa-1f1f8.png" + } + option { + name = "Singapore" + value = "sin" + icon = "/emojis/1f1f8-1f1ec.png" + } + option { + name = "Sydney, Australia" + value = "syd" + icon = "/emojis/1f1e6-1f1fa.png" + } + option { + name = "Toronto, Canada" + value = "yyz" + icon = "/emojis/1f1e8-1f1e6.png" + } +} + +resource "coder_app" "code-server" { + count = 1 + agent_id = coder_agent.main.id + display_name = "Code Server" + slug = "code-server" + url = "http://localhost:8080?folder=/home/coder/" + icon = "/icon/code.svg" + subdomain = false + share = "owner" + + healthcheck { + url = "http://localhost:8080/healthz" + interval = 3 + threshold = 10 + } +} + +resource "coder_agent" "main" { + arch = data.coder_provisioner.me.arch + os = "linux" + login_before_ready = false + startup_script_timeout = 180 + startup_script = <<-EOT + set -e + # Start code-server + code-server --auth none >/tmp/code-server.log 2>&1 & + # Set the hostname to the workspace name + sudo hostname -b "${data.coder_workspace.me.name}-fly" + EOT +} + +data "coder_provisioner" "me" { +} + +data "coder_workspace" "me" { +} From e151d7760825ef5357a38e78e8673f1bf6ac7894 Mon Sep 17 00:00:00 2001 From: Muhammad Atif Ali Date: Sun, 12 Mar 2023 12:43:10 +0300 Subject: [PATCH 02/12] fix: `fly_volume` does not allow using - in name. fix: `fly_volume` does not allow using - in the name. --- examples/templates/fly-docker-image/main.tf | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/examples/templates/fly-docker-image/main.tf b/examples/templates/fly-docker-image/main.tf index bbe765c7ee0a2..66d9e8dfa232a 100644 --- a/examples/templates/fly-docker-image/main.tf +++ b/examples/templates/fly-docker-image/main.tf @@ -15,7 +15,9 @@ resource "fly_ip" "workspace-ip6" { resource "fly_volume" "home-volume" { app = fly_app.workspace.name - name = "coder_${data.coder_workspace.me.owner}_${lower(data.coder_workspace.me.name)}_home" + name = "coder_${data.coder_workspace.me.owner}_${lower(replace(data.coder_workspace.me.name, "-", "_"))}_home" + # or use workspace id + # name = "coder_${data.coder_workspace.me.owner}_${data.coder_workspace.me.id}_home" size = data.coder_parameter.volume-size.value region = data.coder_parameter.region.value } From e6b5489d5462c64f1f8b79cbf0cf162620c2d501 Mon Sep 17 00:00:00 2001 From: Muhammad Atif Ali Date: Sun, 12 Mar 2023 16:34:40 +0300 Subject: [PATCH 03/12] fix: provider versions and settings --- examples/templates/fly-docker-image/main.tf | 25 +++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/examples/templates/fly-docker-image/main.tf b/examples/templates/fly-docker-image/main.tf index 66d9e8dfa232a..b80439dbce54b 100644 --- a/examples/templates/fly-docker-image/main.tf +++ b/examples/templates/fly-docker-image/main.tf @@ -1,3 +1,26 @@ +terraform { + required_providers { + fly = { + source = "fly-apps/fly" + version = "~>0.0.21" + } + coder = { + source = "coder/coder" + version = "~>0.6.17" + } + } +} + +provider "fly" { + useinternaltunnel = true + internaltunnelorg = var.fly_org + internaltunnelregion = data.coder_parameter.region.value +} + +provider "coder" { + feature_use_managed_variables = true +} + resource "fly_app" "workspace" { name = "coder-${data.coder_workspace.me.owner}-${lower(data.coder_workspace.me.name)}" org = var.fly_org @@ -16,8 +39,6 @@ resource "fly_ip" "workspace-ip6" { resource "fly_volume" "home-volume" { app = fly_app.workspace.name name = "coder_${data.coder_workspace.me.owner}_${lower(replace(data.coder_workspace.me.name, "-", "_"))}_home" - # or use workspace id - # name = "coder_${data.coder_workspace.me.owner}_${data.coder_workspace.me.id}_home" size = data.coder_parameter.volume-size.value region = data.coder_parameter.region.value } From fe925aa6d542d06b8c23146a64ed0ebf84cb460c Mon Sep 17 00:00:00 2001 From: Muhammad Atif Ali Date: Sun, 12 Mar 2023 16:35:58 +0300 Subject: [PATCH 04/12] fix: valid `fly_app` name --- examples/templates/fly-docker-image/main.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/templates/fly-docker-image/main.tf b/examples/templates/fly-docker-image/main.tf index b80439dbce54b..172d255de4196 100644 --- a/examples/templates/fly-docker-image/main.tf +++ b/examples/templates/fly-docker-image/main.tf @@ -22,7 +22,7 @@ provider "coder" { } resource "fly_app" "workspace" { - name = "coder-${data.coder_workspace.me.owner}-${lower(data.coder_workspace.me.name)}" + name = "coder-${data.coder_workspace.me.owner}-${lower(replace(data.coder_workspace.me.name, "-", "_"))}" org = var.fly_org } From a35e75af3a77fc556b9c9417eed4a8328b8e845c Mon Sep 17 00:00:00 2001 From: Muhammad Atif Ali Date: Sun, 12 Mar 2023 16:36:59 +0300 Subject: [PATCH 05/12] chore: ipv6 is not used --- examples/templates/fly-docker-image/main.tf | 5 ----- 1 file changed, 5 deletions(-) diff --git a/examples/templates/fly-docker-image/main.tf b/examples/templates/fly-docker-image/main.tf index 172d255de4196..d5834bc02880d 100644 --- a/examples/templates/fly-docker-image/main.tf +++ b/examples/templates/fly-docker-image/main.tf @@ -31,11 +31,6 @@ resource "fly_ip" "workspace-ip4" { type = "v4" } -resource "fly_ip" "workspace-ip6" { - app = fly_app.workspace.name - type = "v6" -} - resource "fly_volume" "home-volume" { app = fly_app.workspace.name name = "coder_${data.coder_workspace.me.owner}_${lower(replace(data.coder_workspace.me.name, "-", "_"))}_home" From d44aa2d8657e1f08acefe8e89508ccd2a750dd2a Mon Sep 17 00:00:00 2001 From: Muhammad Atif Ali Date: Sun, 12 Mar 2023 16:51:31 +0300 Subject: [PATCH 06/12] fix: names strangely `fly_volume` does not allow `-` and `fly_app` does not allow `_`. --- examples/templates/fly-docker-image/main.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/templates/fly-docker-image/main.tf b/examples/templates/fly-docker-image/main.tf index d5834bc02880d..bfac0a2ee0ff0 100644 --- a/examples/templates/fly-docker-image/main.tf +++ b/examples/templates/fly-docker-image/main.tf @@ -22,7 +22,7 @@ provider "coder" { } resource "fly_app" "workspace" { - name = "coder-${data.coder_workspace.me.owner}-${lower(replace(data.coder_workspace.me.name, "-", "_"))}" + name = "coder-${data.coder_workspace.me.owner}-${lower(data.coder_workspace.me.name)}" org = var.fly_org } From eb1caa3f59cd1d38dafe602eac75f8cfbfee443d Mon Sep 17 00:00:00 2001 From: Muhammad Atif Ali Date: Sun, 12 Mar 2023 17:31:32 +0300 Subject: [PATCH 07/12] chore: update max RAM --- examples/templates/fly-docker-image/main.tf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/templates/fly-docker-image/main.tf b/examples/templates/fly-docker-image/main.tf index bfac0a2ee0ff0..a598ddb6fbbee 100644 --- a/examples/templates/fly-docker-image/main.tf +++ b/examples/templates/fly-docker-image/main.tf @@ -113,14 +113,14 @@ data "coder_parameter" "cpu" { data "coder_parameter" "memory" { name = "Memory (GB)" - description = "The amount of memory to allocate to the workspace in GB (1-8)" + description = "The amount of memory to allocate to the workspace in GB (1-16)" type = "number" default = "1" icon = "/icon/memory.svg" mutable = true validation { min = 1 - max = 8 + max = 16 } } From d8cf4373043b51da1b61f2dee129df1f0e85d92c Mon Sep 17 00:00:00 2001 From: Muhammad Atif Ali Date: Tue, 14 Mar 2023 18:48:15 +0300 Subject: [PATCH 08/12] add fly-auth-api managed variables --- examples/templates/fly-docker-image/main.tf | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/examples/templates/fly-docker-image/main.tf b/examples/templates/fly-docker-image/main.tf index a598ddb6fbbee..18387bfd213bc 100644 --- a/examples/templates/fly-docker-image/main.tf +++ b/examples/templates/fly-docker-image/main.tf @@ -15,6 +15,7 @@ provider "fly" { useinternaltunnel = true internaltunnelorg = var.fly_org internaltunnelregion = data.coder_parameter.region.value + fly_api_token = var.fly_api_token == "" ? null : var.fly_api_token } provider "coder" { @@ -85,6 +86,17 @@ resource "fly_machine" "workspace" { ] } +variable "fly_api_token" { + type = string + description = <<-EOF +The Fly.io API token to use for deploying the workspace. You can generate one by running: + +$ flyctl auth token +EOF + sensitive = true + default = "" +} + variable "fly_org" { type = string default = "coder-409" From 03a28b22952156ec8fc0737f9870d9096f475dba Mon Sep 17 00:00:00 2001 From: Muhammad Atif Ali Date: Wed, 15 Mar 2023 00:55:44 +0300 Subject: [PATCH 09/12] Update README.md --- examples/templates/fly-docker-image/README.md | 31 +++++++------------ 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/examples/templates/fly-docker-image/README.md b/examples/templates/fly-docker-image/README.md index aef1ee1fea143..d5a401f32e85a 100644 --- a/examples/templates/fly-docker-image/README.md +++ b/examples/templates/fly-docker-image/README.md @@ -7,31 +7,24 @@ This template provisions a [code-server](https://github.com/coder/code-server) i - [flyctl](https://fly.io/docs/getting-started/installing-flyctl/) installed. - [Coder](https://coder.com/) already setup and running with coder-cli installed locally. -## Deploy +## Getting started -1. Clone this repo and cd into `fly-docker-image` directory. -2. Add a secret or environment variable to your Coder deployment with the name `FLY_API_TOKEN` and the value of your fly.io API token. - > This is needed to deploy the workspace to fly.io. +1. Run `coder templates init` and select this template. Follow the instructions that appear. +2. cd into the directory that was created. (e.g. `cd fly-docker-image`) +3. Create the new template by running the following command from the `fly-docker-image` directory: -```shell -flyctl auth login -export FLY_API_TOKEN=$(flyctl auth token) +```bash +coder templates create fly-docker-image --variable fly_api_token=$(flyctl auth token) ``` -Add this to your Coder deployment's environment variables. (e.g. `/etc/coder.d/coder.env`) - -Or, If Coder is running as a fly.io app, you can set the secret directly: - -```shell -flyctl secrets set FLY_API_TOKEN=$(flyctl auth token) -a -# where is the name of the Coder app on fly.io -``` +> If your Coder is also running as a fly.io app, then instead of setting variable `fly_api_token` you can also set a fly.io secret with the name `FLY_API_TOKEN` +> +> ```bash +> flyctl secrets set FLY_API_TOKEN=$(flyctl auth token) --app +> ``` > Read our blog [post](coder.com/blog/deploying-coder-on-fly-io) to learn more about how to deploy Coder on fly.io. -3. Run `coder templates create fly-docker-image` to create a template in Coder. -4. Create a new workspace from the template. +4. Navigate to the Coder dashboard and create a new workspace using the template. This is all. You should now have a code-server instance running on fly.io. - -> Note: Change the image and the startup command to suit your needs. From ba99899e1454886fb17aa4c78455dde0771651b2 Mon Sep 17 00:00:00 2001 From: Ben Date: Wed, 15 Mar 2023 18:28:06 +0000 Subject: [PATCH 10/12] improve setup flow - user is not prompted in UI for default values - org slug is best fetched via CLI --- examples/templates/fly-docker-image/main.tf | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/examples/templates/fly-docker-image/main.tf b/examples/templates/fly-docker-image/main.tf index 18387bfd213bc..22ff0ceb8d9c0 100644 --- a/examples/templates/fly-docker-image/main.tf +++ b/examples/templates/fly-docker-image/main.tf @@ -94,13 +94,15 @@ The Fly.io API token to use for deploying the workspace. You can generate one by $ flyctl auth token EOF sensitive = true - default = "" } variable "fly_org" { type = string - default = "coder-409" - description = "The Fly.io organization to deploy the workspace in" + description = <<-EOF +The Fly.io organization slug to deploy the workspace in. List organizations by running: + +$ flyctl orgs list +EOF } data "coder_parameter" "docker-image" { From 26ce35ff8c34d084b3297825047c3c7c00619c02 Mon Sep 17 00:00:00 2001 From: Ben Date: Fri, 17 Mar 2023 15:09:27 +0000 Subject: [PATCH 11/12] add metadata --- examples/templates/fly-docker-image/README.md | 15 ++++++++++++--- site/static/icon/fly.io.svg | 1 + 2 files changed, 13 insertions(+), 3 deletions(-) create mode 100644 site/static/icon/fly.io.svg diff --git a/examples/templates/fly-docker-image/README.md b/examples/templates/fly-docker-image/README.md index d5a401f32e85a..e0c26b79582ed 100644 --- a/examples/templates/fly-docker-image/README.md +++ b/examples/templates/fly-docker-image/README.md @@ -1,4 +1,11 @@ -# Coder Docker Image fly.io Template +--- +name: Develop on a Fly.io container +description: Run workspaces as Firecracker VMs on Fly.io +tags: [docker, fly.io] +icon: /icon/fly.io.svg +--- + +# Coder Fly.io Template This template provisions a [code-server](https://github.com/coder/code-server) instance on [fly.io](https://fly.io) using the [codercom/code-server](https://hub.docker.com/r/codercom/code-server) image. @@ -14,10 +21,12 @@ This template provisions a [code-server](https://github.com/coder/code-server) i 3. Create the new template by running the following command from the `fly-docker-image` directory: ```bash -coder templates create fly-docker-image --variable fly_api_token=$(flyctl auth token) +coder templates create fly-docker-image \ + --variable fly_api_token=$(flyctl auth token) \ + --variable fly_org=personal ``` -> If your Coder is also running as a fly.io app, then instead of setting variable `fly_api_token` you can also set a fly.io secret with the name `FLY_API_TOKEN` +> If the Coder server is also running as a fly.io app, then instead of setting variable `fly_api_token` you can also set a fly.io secret with the name `FLY_API_TOKEN` > > ```bash > flyctl secrets set FLY_API_TOKEN=$(flyctl auth token) --app diff --git a/site/static/icon/fly.io.svg b/site/static/icon/fly.io.svg new file mode 100644 index 0000000000000..0d0086b7eff5d --- /dev/null +++ b/site/static/icon/fly.io.svg @@ -0,0 +1 @@ + \ No newline at end of file From 834acc9d832763612eec3d403297cff403a0119b Mon Sep 17 00:00:00 2001 From: Ben Date: Fri, 17 Mar 2023 15:11:37 +0000 Subject: [PATCH 12/12] add to starter templates --- examples/examples.go | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/examples.go b/examples/examples.go index 28036f8e7a3a7..e9631c2b2de5a 100644 --- a/examples/examples.go +++ b/examples/examples.go @@ -32,6 +32,7 @@ var ( //go:embed templates/gcp-vm-container //go:embed templates/gcp-windows //go:embed templates/kubernetes + //go:embed templates/fly-docker-image files embed.FS exampleBasePath = "https://github.com/coder/coder/tree/main/examples/templates/"