From 25aabae6bd8e4f0bff6b3fa8807fab135d3acc19 Mon Sep 17 00:00:00 2001 From: Ammar Bandukwala Date: Mon, 24 Jul 2023 17:30:30 +0000 Subject: [PATCH 1/2] =?UTF-8?q?docs:=20explain=20JFrog=20integration=20?= =?UTF-8?q?=F0=9F=90=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/manifest.json | 25 +++-- docs/platforms/jfrog.md | 18 ++++ examples/templates/jfrog-docker/README.md | 26 +++++ .../templates/jfrog-docker/build/Dockerfile | 18 ++++ examples/templates/jfrog-docker/main.tf | 95 +++++++++++++++++++ site/static/icon/jfrog.svg | 1 + 6 files changed, 173 insertions(+), 10 deletions(-) create mode 100644 docs/platforms/jfrog.md create mode 100644 examples/templates/jfrog-docker/README.md create mode 100644 examples/templates/jfrog-docker/build/Dockerfile create mode 100644 examples/templates/jfrog-docker/main.tf create mode 100644 site/static/icon/jfrog.svg diff --git a/docs/manifest.json b/docs/manifest.json index 423bb33353a70..96b5e9048cccb 100644 --- a/docs/manifest.json +++ b/docs/manifest.json @@ -85,6 +85,18 @@ "path": "./platforms/aws.md", "icon_path": "./images/aws.svg" }, + { + "title": "Azure", + "description": "Set up Coder on an Azure VM", + "path": "./platforms/azure.md", + "icon_path": "./images/azure.svg" + }, + { + "title": "Docker", + "description": "Set up Coder with Docker", + "path": "./platforms/docker.md", + "icon_path": "./images/icons/docker.svg" + }, { "title": "GCP", "description": "Set up Coder on a GCP Compute Engine VM", @@ -92,10 +104,9 @@ "icon_path": "./images/google-cloud.svg" }, { - "title": "Azure", - "description": "Set up Coder on an Azure VM", - "path": "./platforms/azure.md", - "icon_path": "./images/azure.svg" + "title": "JFrog", + "description": "Integrate Coder with JFrog", + "path": "./platforms/jfrog.md" }, { "title": "Kubernetes", @@ -109,12 +120,6 @@ } ] }, - { - "title": "Docker", - "description": "Set up Coder with Docker", - "path": "./platforms/docker.md", - "icon_path": "./images/icons/docker.svg" - }, { "title": "Other platforms", "description": "Set up Coder on an another provider", diff --git a/docs/platforms/jfrog.md b/docs/platforms/jfrog.md new file mode 100644 index 0000000000000..96a06484be8d2 --- /dev/null +++ b/docs/platforms/jfrog.md @@ -0,0 +1,18 @@ +# JFrog + +Coder and JFrog work together to provide seamless security and compliance for +your development environments. With Coder, you can automatically authenticate +every workspace to use a central Artifactory. + +In this page we will give examples in terms of a Docker template for simplicity, +but the same concepts apply to any compute platform. + +## Installing jf + +The easiest way to install the JFrog CLI is to run the following command: + +```sh +curl -fL https://install-cli.jfrog.io | sh +``` + +Other methods are listed [here](https://jfrog.com/help/r/jfrog-cli/download-and-installation). diff --git a/examples/templates/jfrog-docker/README.md b/examples/templates/jfrog-docker/README.md new file mode 100644 index 0000000000000..ac1a3a128643f --- /dev/null +++ b/examples/templates/jfrog-docker/README.md @@ -0,0 +1,26 @@ +--- +name: JFrog and Docker +description: Develop inside Docker containers using your local daemon +tags: [local, docker, jfrog] +icon: /icon/docker.png +--- + +# jfrog-docker + +To get started, run `coder templates init`. When prompted, select this template. +Follow the on-screen instructions to proceed. + +## Editing the image + +Edit the `Dockerfile` and run `coder templates push` to update workspaces. + +## code-server + +`code-server` is installed via the `startup_script` argument in the `coder_agent` +resource block. The `coder_app` resource is defined to access `code-server` through +the dashboard UI over `localhost:13337`. + +# Next steps + +Check out our [Docker](../docker/) template for a more fully featured Docker +example. diff --git a/examples/templates/jfrog-docker/build/Dockerfile b/examples/templates/jfrog-docker/build/Dockerfile new file mode 100644 index 0000000000000..a443b5d07100e --- /dev/null +++ b/examples/templates/jfrog-docker/build/Dockerfile @@ -0,0 +1,18 @@ +FROM ubuntu + +RUN apt-get update \ + && apt-get install -y \ + curl \ + git \ + golang \ + sudo \ + vim \ + wget \ + && rm -rf /var/lib/apt/lists/* + +ARG USER=coder +RUN useradd --groups sudo --no-create-home --shell /bin/bash ${USER} \ + && echo "${USER} ALL=(ALL) NOPASSWD:ALL" >/etc/sudoers.d/${USER} \ + && chmod 0440 /etc/sudoers.d/${USER} +USER ${USER} +WORKDIR /home/${USER} diff --git a/examples/templates/jfrog-docker/main.tf b/examples/templates/jfrog-docker/main.tf new file mode 100644 index 0000000000000..36fbab2497c5f --- /dev/null +++ b/examples/templates/jfrog-docker/main.tf @@ -0,0 +1,95 @@ +terraform { + required_providers { + coder = { + source = "coder/coder" + version = "~> 0.8.3" + } + docker = { + source = "kreuzwerker/docker" + version = "~> 3.0.1" + } + } +} + +locals { + username = data.coder_workspace.me.owner +} + +data "coder_provisioner" "me" { +} + +provider "docker" { +} + +data "coder_workspace" "me" { +} + +resource "coder_agent" "main" { + arch = data.coder_provisioner.me.arch + os = "linux" + startup_script_timeout = 180 + startup_script = <<-EOT + set -e + + # install and start code-server + curl -fsSL https://code-server.dev/install.sh | sh -s -- --method=standalone --prefix=/tmp/code-server --version 4.11.0 + /tmp/code-server/bin/code-server --auth none --port 13337 >/tmp/code-server.log 2>&1 & + EOT +} + +resource "coder_app" "code-server" { + agent_id = coder_agent.main.id + slug = "code-server" + display_name = "code-server" + url = "http://localhost:13337/?folder=/home/${local.username}" + icon = "/icon/code.svg" + subdomain = false + share = "owner" + + healthcheck { + url = "http://localhost:13337/healthz" + interval = 5 + threshold = 6 + } +} + +resource "docker_volume" "home_volume" { + name = "coder-${data.coder_workspace.me.id}-home" + # Protect the volume from being deleted due to changes in attributes. + lifecycle { + ignore_changes = all + } +} + +resource "docker_image" "main" { + name = "coder-${data.coder_workspace.me.id}" + build { + context = "./build" + build_args = { + USER = local.username + } + } + triggers = { + dir_sha1 = sha1(join("", [for f in fileset(path.module, "build/*") : filesha1(f)])) + } +} + +resource "docker_container" "workspace" { + count = data.coder_workspace.me.start_count + image = docker_image.main.name + # Uses lower() to avoid Docker restriction on container names. + name = "coder-${data.coder_workspace.me.owner}-${lower(data.coder_workspace.me.name)}" + # Hostname makes the shell more user friendly: coder@my-workspace:~$ + hostname = data.coder_workspace.me.name + entrypoint = ["sh", "-c", coder_agent.main.init_script] + env = ["CODER_AGENT_TOKEN=${coder_agent.main.token}"] + host { + host = "host.docker.internal" + ip = "host-gateway" + } + volumes { + container_path = "/home/${local.username}" + volume_name = docker_volume.home_volume.name + read_only = false + } +} diff --git a/site/static/icon/jfrog.svg b/site/static/icon/jfrog.svg new file mode 100644 index 0000000000000..5e0c6337f3bb8 --- /dev/null +++ b/site/static/icon/jfrog.svg @@ -0,0 +1 @@ + \ No newline at end of file From eb58e01833a8b511a80a20cebcb1c210f714fecc Mon Sep 17 00:00:00 2001 From: Ammar Bandukwala Date: Mon, 24 Jul 2023 20:42:57 +0000 Subject: [PATCH 2/2] Build out most of the basic example --- docs/platforms/jfrog.md | 142 +++++++++++++++++- .../templates/jfrog-docker/build/Dockerfile | 3 + examples/templates/jfrog-docker/main.tf | 45 +++++- 3 files changed, 185 insertions(+), 5 deletions(-) diff --git a/docs/platforms/jfrog.md b/docs/platforms/jfrog.md index 96a06484be8d2..42499d4ded0fe 100644 --- a/docs/platforms/jfrog.md +++ b/docs/platforms/jfrog.md @@ -2,17 +2,151 @@ Coder and JFrog work together to provide seamless security and compliance for your development environments. With Coder, you can automatically authenticate -every workspace to use a central Artifactory. +every workspace to use Artifactory as a package registry. -In this page we will give examples in terms of a Docker template for simplicity, -but the same concepts apply to any compute platform. +In this page, we'll show you how to integrate both products using a Docker template +as an example. But, these concepts apply to any compute platform. The full example template can be found [here](https://github.com/coder/coder/tree/main/examples/jfrog-docker). + +## Requirements + +- A JFrog Artifactory instance +- 1:1 mapping of users in Coder to users in Artifactory, with the same email + +## Provisioner Authentication + +The most straight-forward way to authenticate your template with artifactory is +by using +[Terraform-managed variables](https://coder.com/docs/v2/latest/templates/parameters#terraform-template-wide-variables). + +See the following example: + +```hcl +terraform { + required_providers { + coder = { + source = "coder/coder" + version = "~> 0.11.1" + } + docker = { + source = "kreuzwerker/docker" + version = "~> 3.0.1" + } + artifactory = { + source = "registry.terraform.io/jfrog/artifactory" + version = "6.22.3" + } + } +} + +variable "jfrog_url" { + type = string + description = "The URL of the JFrog instance." +} + +variable "artifactory_access_token" { + type = string + description = "The access token to use for JFrog." +} + + +# Configure the Artifactory provider +provider "artifactory" { + url = "${var.jfrog_url}/artifactory" + access_token = "${var.artifactory_access_token}" +} +``` + +When pushing the template, you can pass in the variables using the `--variable` flag: + +```sh +coder templates push --variable 'jfrog_url=https://YYY.jfrog.io' --variable 'artifactory_access_token=XXX' +``` ## Installing jf -The easiest way to install the JFrog CLI is to run the following command: +`jf` is the JFrog CLI. Every workspace must have `jf` installed to use +Artifactory. + +The generic method of installing the JFrog CLI is the following command: ```sh curl -fL https://install-cli.jfrog.io | sh ``` Other methods are listed [here](https://jfrog.com/help/r/jfrog-cli/download-and-installation). + +In our Docker-based example, we install `jf` by adding these lines to our `Dockerfile`: + +```Dockerfile +RUN curl -fL https://install-cli.jfrog.io | sh +RUN chmod 755 $(which jf) +``` + +and use this `coder_agent` block: + +```hcl +resource "coder_agent" "main" { + arch = data.coder_provisioner.me.arch + os = "linux" + startup_script_timeout = 180 + startup_script = <<-EOT + set -e + + # install and start code-server + curl -fsSL https://code-server.dev/install.sh | sh -s -- --method=standalone --prefix=/tmp/code-server --version 4.11.0 + /tmp/code-server/bin/code-server --auth none --port 13337 >/tmp/code-server.log 2>&1 & + + # The jf CLI checks $CI when determining whether to use interactive + # flows. + export CI=true + + jf c rm 0 || true + echo ${artifactory_access_token.me.access_token} | \ + jf c add --access-token-stdin --url ${var.jfrog_url} 0 + EOT +} +``` + +You can verify that `jf` is configured correctly in your workspace by +running `jf c show`. It should present output like: + +```text +coder@jf:~$ jf c show +Server ID: 0 +JFrog Platform URL: https://cdr.jfrog.io/ +Artifactory URL: https://cdr.jfrog.io/artifactory/ +Distribution URL: https://cdr.jfrog.io/distribution/ +Xray URL: https://cdr.jfrog.io/xray/ +Mission Control URL: https://cdr.jfrog.io/mc/ +Pipelines URL: https://cdr.jfrog.io/pipelines/ +User: ammar@....com +Access token: ... +Default: true +``` + +## Configuring npm + +Add the following line to your `startup_script` to configure `npm` to use +Artifactory: + +```sh + # Configure the `npm` CLI to use the Artifactory "npm" registry. + cat << EOF > ~/.npmrc + _auth = ${artifactory_access_token.me.access_token} + email = ${data.coder_workspace.me.owner_email} + always-auth = true + registry=${var.jfrog_url}/artifactory/api/npm/npm/ + EOF +``` + +Now, your developers can run `npm install`, `npm audit`, etc. and transparently +use Artifactory as the package registry. + +You can apply the same concepts to Docker, Go, Maven, and other package managers +supported by Artifactory. + +## Next steps + +* If you'd like to serve extensions from your own VS Code Marketplace, check out +[`code-marketplace`](https://github.com/coder/code-marketplace#artifactory-storage). +* See the full example template [here](https://github.com/coder/coder/tree/main/examples/jfrog-docker). diff --git a/examples/templates/jfrog-docker/build/Dockerfile b/examples/templates/jfrog-docker/build/Dockerfile index a443b5d07100e..1dfaa77015f32 100644 --- a/examples/templates/jfrog-docker/build/Dockerfile +++ b/examples/templates/jfrog-docker/build/Dockerfile @@ -8,11 +8,14 @@ RUN apt-get update \ sudo \ vim \ wget \ + npm \ && rm -rf /var/lib/apt/lists/* ARG USER=coder RUN useradd --groups sudo --no-create-home --shell /bin/bash ${USER} \ && echo "${USER} ALL=(ALL) NOPASSWD:ALL" >/etc/sudoers.d/${USER} \ && chmod 0440 /etc/sudoers.d/${USER} +RUN curl -fL https://install-cli.jfrog.io | sh +RUN chmod 755 $(which jf) USER ${USER} WORKDIR /home/${USER} diff --git a/examples/templates/jfrog-docker/main.tf b/examples/templates/jfrog-docker/main.tf index 36fbab2497c5f..ee0cc7dccd36d 100644 --- a/examples/templates/jfrog-docker/main.tf +++ b/examples/templates/jfrog-docker/main.tf @@ -2,12 +2,16 @@ terraform { required_providers { coder = { source = "coder/coder" - version = "~> 0.8.3" + version = "~> 0.11.1" } docker = { source = "kreuzwerker/docker" version = "~> 3.0.1" } + artifactory = { + source = "registry.terraform.io/jfrog/artifactory" + version = "6.22.3" + } } } @@ -24,6 +28,29 @@ provider "docker" { data "coder_workspace" "me" { } +variable "jfrog_url" { + type = string + description = "The URL of the JFrog instance." +} + +variable "artifactory_access_token" { + type = string + description = "The access token to use for JFrog." +} + + +# Configure the Artifactory provider +provider "artifactory" { + url = "${var.jfrog_url}/artifactory" + access_token = "${var.artifactory_access_token}" +} + +resource "artifactory_access_token" "me" { + username = "${data.coder_workspace.me.owner_email}" + # The token should live for the duration of the workspace. + end_date_relative = "0s" +} + resource "coder_agent" "main" { arch = data.coder_provisioner.me.arch os = "linux" @@ -34,6 +61,22 @@ resource "coder_agent" "main" { # install and start code-server curl -fsSL https://code-server.dev/install.sh | sh -s -- --method=standalone --prefix=/tmp/code-server --version 4.11.0 /tmp/code-server/bin/code-server --auth none --port 13337 >/tmp/code-server.log 2>&1 & + + # The jf CLI checks $CI when determining whether to use interactive + # flows. + export CI=true + + jf c rm 0 || true + echo ${artifactory_access_token.me.access_token} | \ + jf c add --access-token-stdin --url ${var.jfrog_url} 0 + + # Configure the `npm` CLI to use the Artifactory "npm" registry. + cat << EOF > ~/.npmrc + _auth = ${artifactory_access_token.me.access_token} + email = ${data.coder_workspace.me.owner_email} + always-auth = true + registry=${var.jfrog_url}/artifactory/api/npm/npm/ + EOF EOT }