Compare commits

..

19 Commits

Author SHA1 Message Date
Muhammad Atif Ali
d10ce91a64 fix: fix fetching rc versions of vault cli (#156)
Co-authored-by: Mathias Fredriksson <mafredri@gmail.com>
2024-02-14 17:04:56 +03:00
Muhammad Atif Ali
534491613f Update module versions to v1.0.3 (#159) 2024-02-14 16:37:01 +03:00
Muhammad Atif Ali
ac64af6f02 Update Hashicorp vault modules (#140)
Co-authored-by: Mathias Fredriksson <mafredri@gmail.com>
2024-02-14 01:43:33 +03:00
Muhammad Atif Ali
b299f98161 ci: automate version bumps in module README.md files (#139)
Co-authored-by: Mathias Fredriksson <mafredri@gmail.com>
2024-02-13 15:23:44 +03:00
Muhammad Atif Ali
7e897a51e6 chore(vault-github): Add partner github and tests (#142) 2024-02-13 12:18:23 +03:00
Muhammad Atif Ali
ac54966f5e feat!(git-config): use full name for git configuration (#141) 2024-02-12 17:18:13 +03:00
Andrew Svoboda
aef9b3b116 Add build numbers and versions to jetbrains gateway module (#150) 2024-02-12 17:16:31 +03:00
Phorcys
a5c4d00a01 fix(git-commit-signing): fix SSH key permissions (#152) 2024-02-10 00:20:05 +03:00
Muhammad Atif Ali
3227a47044 fix(jetbrains-gateway): fix readme to include agent_name (#151) 2024-02-09 21:19:29 +03:00
Florian Gareis
cf1807dd5c Allow custom display name and slug for VS Code Web (#146) 2024-02-09 21:18:20 +03:00
Florian Gareis
4c993d342d Fix code-server docu (#147) 2024-02-09 21:17:32 +03:00
Muhammad Atif Ali
5a7e3f6ca4 Add Hashicorp Vault Secrets Integration module (#144) 2024-02-09 21:16:41 +03:00
Muhammad Atif Ali
acab6437bc chore: bump version to 1.0.2 and add script to update them automatically. (#128)
Co-authored-by: Mathias Fredriksson <mafredri@gmail.com>
2024-01-30 17:51:31 +03:00
Muhammad Atif Ali
f16d7ca3f5 docs(jfrog-oauth): fix documentation link 2024-01-30 12:41:09 +03:00
Mathias Fredriksson
a9a58bff32 chore: lint for tf/hcl blocks (#135)
Co-authored-by: Muhammad Atif Ali <atif@coder.com>
2024-01-28 00:48:49 +03:00
Muhammad Atif Ali
6b842004e6 ci: check for typos (#131) 2024-01-27 16:50:47 +03:00
Mathias Fredriksson
376c0cae31 chore: add prettier terraform formatting in markdown files (#134) 2024-01-27 15:02:40 +02:00
Muhammad Atif Ali
7d31865c94 feat!(git-clone): change path input to base_dir and return repo_dir as output (#132) 2024-01-26 16:13:03 +03:00
Muhammad Atif Ali
d3fc2d2212 docs(jfrog-oauth): improve docs (#129)
* docs(jfrog-oauth): improve docs

Adds additional step and screenshot to show creating an OAuth app in JFrog platform

* Update README.md

* Add files via upload

* fmt

* move JFrog Artifactory integration setup instructions

* Update JFrog token documentation
2024-01-26 09:20:21 +03:00
51 changed files with 1020 additions and 505 deletions

View File

@@ -34,5 +34,7 @@ jobs:
run: bun install run: bun install
- name: Format - name: Format
run: bun fmt:ci run: bun fmt:ci
- name: typos-action
uses: crate-ci/typos@v1.17.2
- name: Lint - name: Lint
run: bun lint run: bun lint

41
.github/workflows/update-readme.yaml vendored Normal file
View File

@@ -0,0 +1,41 @@
name: Update README on Tag
on:
workflow_dispatch:
push:
tags:
- 'v*'
jobs:
update-readme:
permissions:
contents: read
pull-requests: write
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Get the latest tag
id: get-latest-tag
run: echo "TAG=$(git describe --tags --abbrev=0 | sed 's/^v//')" >> $GITHUB_OUTPUT
- name: Run update script
run: ./update-version.sh
- name: Create Pull Request
id: create-pr
uses: peter-evans/create-pull-request@v5
with:
commit-message: 'chore: bump version to ${{ env.TAG }} in README.md files'
title: 'chore: bump version to ${{ env.TAG }} in README.md files'
body: 'This is an auto-generated PR to update README.md files of all modules with the new tag ${{ env.TAG }}'
branch: 'update-readme-branch'
env:
TAG: ${{ steps.get-latest-tag.outputs.TAG }}
- name: Auto-approve
uses: hmarr/auto-approve-action@v4
if: github.ref == 'refs/heads/update-readme-branch'

View File

@@ -11,10 +11,10 @@ tags: [helper]
<!-- Describes what this module does --> <!-- Describes what this module does -->
```hcl ```tf
module "MODULE_NAME" { module "MODULE_NAME" {
source = "registry.coder.com/modules/MODULE_NAME/coder" source = "registry.coder.com/modules/MODULE_NAME/coder"
version = "1.0.0" version = "1.0.2"
} }
``` ```
@@ -26,10 +26,10 @@ module "MODULE_NAME" {
Install the Dracula theme from [OpenVSX](https://open-vsx.org/): Install the Dracula theme from [OpenVSX](https://open-vsx.org/):
```hcl ```tf
module "MODULE_NAME" { module "MODULE_NAME" {
source = "registry.coder.com/modules/MODULE_NAME/coder" source = "registry.coder.com/modules/MODULE_NAME/coder"
version = "1.0.0" version = "1.0.2"
agent_id = coder_agent.example.id agent_id = coder_agent.example.id
extensions = [ extensions = [
"dracula-theme.theme-dracula" "dracula-theme.theme-dracula"
@@ -43,10 +43,10 @@ Enter the `<author>.<name>` into the extensions array and code-server will autom
Configure VS Code's [settings.json](https://code.visualstudio.com/docs/getstarted/settings#_settingsjson) file: Configure VS Code's [settings.json](https://code.visualstudio.com/docs/getstarted/settings#_settingsjson) file:
```hcl ```tf
module "MODULE_NAME" { module "MODULE_NAME" {
source = "registry.coder.com/modules/MODULE_NAME/coder" source = "registry.coder.com/modules/MODULE_NAME/coder"
version = "1.0.0" version = "1.0.2"
agent_id = coder_agent.example.id agent_id = coder_agent.example.id
extensions = [ "dracula-theme.theme-dracula" ] extensions = [ "dracula-theme.theme-dracula" ]
settings = { settings = {
@@ -59,10 +59,10 @@ module "MODULE_NAME" {
Run code-server in the background, don't fetch it from GitHub: Run code-server in the background, don't fetch it from GitHub:
```hcl ```tf
module "MODULE_NAME" { module "MODULE_NAME" {
source = "registry.coder.com/modules/MODULE_NAME/coder" source = "registry.coder.com/modules/MODULE_NAME/coder"
version = "1.0.0" version = "1.0.2"
agent_id = coder_agent.example.id agent_id = coder_agent.example.id
offline = true offline = true
} }

View File

@@ -3,7 +3,7 @@
To create a new module, clone this repository and run: To create a new module, clone this repository and run:
```shell ```shell
./new.sh MOUDLE_NAME ./new.sh MODULE_NAME
``` ```
## Testing a Module ## Testing a Module
@@ -19,7 +19,7 @@ $ bun test -t '<module>'
You can test a module locally by updating the source as follows You can test a module locally by updating the source as follows
```hcl ```tf
module "example" { module "example" {
source = "git::https://github.com/<USERNAME>/<REPO>.git//<MODULE-NAME>?ref=<BRANCH-NAME>" source = "git::https://github.com/<USERNAME>/<REPO>.git//<MODULE-NAME>?ref=<BRANCH-NAME>"
} }

View File

@@ -14,10 +14,10 @@ Modules extend Templates to create reusable components for your development envi
e.g. e.g.
```hcl ```tf
module "code-server" { module "code-server" {
source = "registry.coder.com/modules/code-server/coder" source = "registry.coder.com/modules/code-server/coder"
version = "1.0.0" version = "1.0.2"
agent_id = coder_agent.main.id agent_id = coder_agent.main.id
} }
``` ```

View File

@@ -14,10 +14,10 @@ the region closest to them.
Customize the preselected parameter value: Customize the preselected parameter value:
```hcl ```tf
module "aws-region" { module "aws-region" {
source = "registry.coder.com/modules/aws-region/coder" source = "registry.coder.com/modules/aws-region/coder"
version = "1.0.0" version = "1.0.2"
default = "us-east-1" default = "us-east-1"
} }
@@ -34,16 +34,18 @@ provider "aws" {
Change the display name and icon for a region using the corresponding maps: Change the display name and icon for a region using the corresponding maps:
```hcl ```tf
module "aws-region" { module "aws-region" {
source = "registry.coder.com/modules/aws-region/coder" source = "registry.coder.com/modules/aws-region/coder"
version = "1.0.0" version = "1.0.2"
default = "ap-south-1" default = "ap-south-1"
custom_names = { custom_names = {
"ap-south-1": "Awesome Mumbai!" "ap-south-1" : "Awesome Mumbai!"
} }
custom_icons = { custom_icons = {
"ap-south-1": "/emojis/1f33a.png" "ap-south-1" : "/emojis/1f33a.png"
} }
} }
@@ -58,11 +60,11 @@ provider "aws" {
Hide the Asia Pacific regions Seoul and Osaka: Hide the Asia Pacific regions Seoul and Osaka:
```hcl ```tf
module "aws-region" { module "aws-region" {
source = "registry.coder.com/modules/aws-region/coder" source = "registry.coder.com/modules/aws-region/coder"
version = "1.0.0" version = "1.0.2"
exclude = [ "ap-northeast-2", "ap-northeast-3" ] exclude = ["ap-northeast-2", "ap-northeast-3"]
} }
provider "aws" { provider "aws" {

View File

@@ -11,10 +11,10 @@ tags: [helper, parameter, azure, regions]
This module adds a parameter with all Azure regions, allowing developers to select the region closest to them. This module adds a parameter with all Azure regions, allowing developers to select the region closest to them.
```hcl ```tf
module "azure_region" { module "azure_region" {
source = "registry.coder.com/modules/azure-region/coder" source = "registry.coder.com/modules/azure-region/coder"
version = "1.0.0" version = "1.0.2"
default = "eastus" default = "eastus"
} }
@@ -31,15 +31,15 @@ resource "azurem_resource_group" "example" {
Change the display name and icon for a region using the corresponding maps: Change the display name and icon for a region using the corresponding maps:
```hcl ```tf
module "azure-region" { module "azure-region" {
source = "registry.coder.com/modules/azure-region/coder" source = "registry.coder.com/modules/azure-region/coder"
version = "1.0.0" version = "1.0.2"
custom_names = { custom_names = {
"australia": "Go Australia!" "australia" : "Go Australia!"
} }
custom_icons = { custom_icons = {
"australia": "/icons/smiley.svg" "australia" : "/icons/smiley.svg"
} }
} }
@@ -54,10 +54,10 @@ resource "azurerm_resource_group" "example" {
Hide all regions in Australia except australiacentral: Hide all regions in Australia except australiacentral:
```hcl ```tf
module "azure-region" { module "azure-region" {
source = "registry.coder.com/modules/azure-region/coder" source = "registry.coder.com/modules/azure-region/coder"
version = "1.0.0" version = "1.0.2"
exclude = [ exclude = [
"australia", "australia",
"australiacentral2", "australiacentral2",

BIN
bun.lockb

Binary file not shown.

View File

@@ -11,10 +11,10 @@ tags: [helper, ide, web]
Automatically install [code-server](https://github.com/coder/code-server) in a workspace, create an app to access it via the dashboard, install extensions, and pre-configure editor settings. Automatically install [code-server](https://github.com/coder/code-server) in a workspace, create an app to access it via the dashboard, install extensions, and pre-configure editor settings.
```hcl ```tf
module "code-server" { module "code-server" {
source = "registry.coder.com/modules/code-server/coder" source = "registry.coder.com/modules/code-server/coder"
version = "1.0.0" version = "1.0.2"
agent_id = coder_agent.example.id agent_id = coder_agent.example.id
} }
``` ```
@@ -25,10 +25,10 @@ module "code-server" {
### Pin Versions ### Pin Versions
```hcl ```tf
module "code-server" { module "code-server" {
source = "registry.coder.com/modules/code-server/coder" source = "registry.coder.com/modules/code-server/coder"
version = "1.0.0" version = "1.0.2"
agent_id = coder_agent.example.id agent_id = coder_agent.example.id
install_version = "4.8.3" install_version = "4.8.3"
} }
@@ -38,10 +38,10 @@ module "code-server" {
Install the Dracula theme from [OpenVSX](https://open-vsx.org/): Install the Dracula theme from [OpenVSX](https://open-vsx.org/):
```hcl ```tf
module "code-server" { module "code-server" {
source = "registry.coder.com/modules/code-server/coder" source = "registry.coder.com/modules/code-server/coder"
version = "1.0.0" version = "1.0.2"
agent_id = coder_agent.example.id agent_id = coder_agent.example.id
extensions = [ extensions = [
"dracula-theme.theme-dracula" "dracula-theme.theme-dracula"
@@ -55,12 +55,12 @@ Enter the `<author>.<name>` into the extensions array and code-server will autom
Configure VS Code's [settings.json](https://code.visualstudio.com/docs/getstarted/settings#_settingsjson) file: Configure VS Code's [settings.json](https://code.visualstudio.com/docs/getstarted/settings#_settingsjson) file:
```hcl ```tf
module "settings" { module "code-server" {
source = "registry.coder.com/modules/code-server/coder" source = "registry.coder.com/modules/code-server/coder"
version = "1.0.0" version = "1.0.2"
agent_id = coder_agent.example.id agent_id = coder_agent.example.id
extensions = [ "dracula-theme.theme-dracula" ] extensions = ["dracula-theme.theme-dracula"]
settings = { settings = {
"workbench.colorTheme" = "Dracula" "workbench.colorTheme" = "Dracula"
} }
@@ -71,12 +71,12 @@ module "settings" {
Just run code-server in the background, don't fetch it from GitHub: Just run code-server in the background, don't fetch it from GitHub:
```hcl ```tf
module "settings" { module "code-server" {
source = "registry.coder.com/modules/code-server/coder" source = "registry.coder.com/modules/code-server/coder"
version = "1.0.0" version = "1.0.2"
agent_id = coder_agent.example.id agent_id = coder_agent.example.id
extensions = [ "dracula-theme.theme-dracula", "ms-azuretools.vscode-docker" ] extensions = ["dracula-theme.theme-dracula", "ms-azuretools.vscode-docker"]
} }
``` ```
@@ -84,10 +84,10 @@ module "settings" {
Just run code-server in the background, don't fetch it from GitHub: Just run code-server in the background, don't fetch it from GitHub:
```hcl ```tf
module "settings" { module "code-server" {
source = "registry.coder.com/modules/code-server/coder" source = "registry.coder.com/modules/code-server/coder"
version = "1.0.0" version = "1.0.2"
agent_id = coder_agent.example.id agent_id = coder_agent.example.id
offline = true offline = true
} }

View File

@@ -11,10 +11,10 @@ tags: [helper]
Automatically logs the user into Coder when creating their workspace. Automatically logs the user into Coder when creating their workspace.
```hcl ```tf
module "coder-login" { module "coder-login" {
source = "registry.coder.com/modules/coder-login/coder" source = "registry.coder.com/modules/coder-login/coder"
version = "1.0.0" version = "1.0.2"
agent_id = coder_agent.example.id agent_id = coder_agent.example.id
} }
``` ```

View File

@@ -11,10 +11,10 @@ tags: [helper]
Allow developers to optionally bring their own [dotfiles repository](https://dotfiles.github.io)! Under the hood, this module uses the [coder dotfiles](https://coder.com/docs/v2/latest/dotfiles) command. Allow developers to optionally bring their own [dotfiles repository](https://dotfiles.github.io)! Under the hood, this module uses the [coder dotfiles](https://coder.com/docs/v2/latest/dotfiles) command.
```hcl ```tf
module "dotfiles" { module "dotfiles" {
source = "registry.coder.com/modules/dotfiles/coder" source = "registry.coder.com/modules/dotfiles/coder"
version = "1.0.0" version = "1.0.2"
agent_id = coder_agent.example.id agent_id = coder_agent.example.id
} }
``` ```

View File

@@ -10,20 +10,20 @@ tags: [helper, parameter, instances, exoscale]
# exoscale-instance-type # exoscale-instance-type
A parameter with all Exoscale instance types. This allows developers to select A parameter with all Exoscale instance types. This allows developers to select
their desired virtuell machine for the workspace. their desired virtual machine for the workspace.
Customize the preselected parameter value: Customize the preselected parameter value:
```hcl ```tf
module "exoscale-instance-type" { module "exoscale-instance-type" {
source = "registry.coder.com/modules/exoscale-instance-type/coder" source = "registry.coder.com/modules/exoscale-instance-type/coder"
version = "1.0.0" version = "1.0.2"
default = "standard.medium" default = "standard.medium"
} }
resource "exoscale_compute_instance" "instance" { resource "exoscale_compute_instance" "instance" {
type = module.exoscale-instance-type.value type = module.exoscale-instance-type.value
... # ...
} }
resource "coder_metadata" "workspace_info" { resource "coder_metadata" "workspace_info" {
@@ -42,22 +42,24 @@ resource "coder_metadata" "workspace_info" {
Change the display name a type using the corresponding maps: Change the display name a type using the corresponding maps:
```hcl ```tf
module "exoscale-instance-type" { module "exoscale-instance-type" {
source = "registry.coder.com/modules/exoscale-instance-type/coder" source = "registry.coder.com/modules/exoscale-instance-type/coder"
version = "1.0.0" version = "1.0.2"
default = "standard.medium" default = "standard.medium"
custom_names = { custom_names = {
"standard.medium": "Mittlere Instanz" # German translation "standard.medium" : "Mittlere Instanz" # German translation
} }
custom_descriptions = { custom_descriptions = {
"standard.medium": "4 GB Arbeitsspeicher, 2 Kerne, 10 - 400 GB Festplatte" # German translation "standard.medium" : "4 GB Arbeitsspeicher, 2 Kerne, 10 - 400 GB Festplatte" # German translation
} }
} }
resource "exoscale_compute_instance" "instance" { resource "exoscale_compute_instance" "instance" {
type = module.exoscale-instance-type.value type = module.exoscale-instance-type.value
... # ...
} }
resource "coder_metadata" "workspace_info" { resource "coder_metadata" "workspace_info" {
@@ -70,14 +72,14 @@ resource "coder_metadata" "workspace_info" {
![Exoscale instance types Custom](../.images/exoscale-instance-custom.png) ![Exoscale instance types Custom](../.images/exoscale-instance-custom.png)
### Use category and exlude type ### Use category and exclude type
Show only gpu1 types Show only gpu1 types
```hcl ```tf
module "exoscale-instance-type" { module "exoscale-instance-type" {
source = "registry.coder.com/modules/exoscale-instance-type/coder" source = "registry.coder.com/modules/exoscale-instance-type/coder"
version = "1.0.0" version = "1.0.2"
default = "gpu.large" default = "gpu.large"
type_category = ["gpu"] type_category = ["gpu"]
exclude = [ exclude = [
@@ -94,7 +96,7 @@ module "exoscale-instance-type" {
resource "exoscale_compute_instance" "instance" { resource "exoscale_compute_instance" "instance" {
type = module.exoscale-instance-type.value type = module.exoscale-instance-type.value
... # ...
} }
resource "coder_metadata" "workspace_info" { resource "coder_metadata" "workspace_info" {

View File

@@ -14,10 +14,10 @@ the zone closest to them.
Customize the preselected parameter value: Customize the preselected parameter value:
```hcl ```tf
module "exoscale-zone" { module "exoscale-zone" {
source = "registry.coder.com/modules/exoscale-zone/coder" source = "registry.coder.com/modules/exoscale-zone/coder"
version = "1.0.0" version = "1.0.2"
default = "ch-dk-2" default = "ch-dk-2"
} }
@@ -29,7 +29,7 @@ data "exoscale_compute_template" "my_template" {
resource "exoscale_compute_instance" "instance" { resource "exoscale_compute_instance" "instance" {
zone = module.exoscale-zone.value zone = module.exoscale-zone.value
.... # ...
} }
``` ```
@@ -41,16 +41,18 @@ resource "exoscale_compute_instance" "instance" {
Change the display name and icon for a zone using the corresponding maps: Change the display name and icon for a zone using the corresponding maps:
```hcl ```tf
module "exoscale-zone" { module "exoscale-zone" {
source = "registry.coder.com/modules/exoscale-zone/coder" source = "registry.coder.com/modules/exoscale-zone/coder"
version = "1.0.0" version = "1.0.2"
default = "at-vie-1" default = "at-vie-1"
custom_names = { custom_names = {
"at-vie-1": "Home Vienna" "at-vie-1" : "Home Vienna"
} }
custom_icons = { custom_icons = {
"at-vie-1": "/emojis/1f3e0.png" "at-vie-1" : "/emojis/1f3e0.png"
} }
} }
@@ -61,7 +63,7 @@ data "exoscale_compute_template" "my_template" {
resource "exoscale_compute_instance" "instance" { resource "exoscale_compute_instance" "instance" {
zone = module.exoscale-zone.value zone = module.exoscale-zone.value
.... # ...
} }
``` ```
@@ -71,11 +73,11 @@ resource "exoscale_compute_instance" "instance" {
Hide the Switzerland zones Geneva and Zurich Hide the Switzerland zones Geneva and Zurich
```hcl ```tf
module "exoscale-zone" { module "exoscale-zone" {
source = "registry.coder.com/modules/exoscale-zone/coder" source = "registry.coder.com/modules/exoscale-zone/coder"
version = "1.0.0" version = "1.0.2"
exclude = [ "ch-gva-2", "ch-dk-2" ] exclude = ["ch-gva-2", "ch-dk-2"]
} }
data "exoscale_compute_template" "my_template" { data "exoscale_compute_template" "my_template" {
@@ -85,7 +87,7 @@ data "exoscale_compute_template" "my_template" {
resource "exoscale_compute_instance" "instance" { resource "exoscale_compute_instance" "instance" {
zone = module.exoscale-zone.value zone = module.exoscale-zone.value
.... # ...
} }
``` ```

View File

@@ -11,10 +11,10 @@ tags: [helper, filebrowser]
A file browser for your workspace. A file browser for your workspace.
```hcl ```tf
module "filebrowser" { module "filebrowser" {
source = "registry.coder.com/modules/filebrowser/coder" source = "registry.coder.com/modules/filebrowser/coder"
version = "1.0.0" version = "1.0.3"
agent_id = coder_agent.example.id agent_id = coder_agent.example.id
} }
``` ```
@@ -25,10 +25,10 @@ module "filebrowser" {
### Serve a specific directory ### Serve a specific directory
```hcl ```tf
module "filebrowser" { module "filebrowser" {
source = "registry.coder.com/modules/filebrowser/coder" source = "registry.coder.com/modules/filebrowser/coder"
version = "1.0.0" version = "1.0.3"
agent_id = coder_agent.example.id agent_id = coder_agent.example.id
folder = "/home/coder/project" folder = "/home/coder/project"
} }
@@ -36,10 +36,10 @@ module "filebrowser" {
### Specify location of `filebrowser.db` ### Specify location of `filebrowser.db`
```hcl ```tf
module "filebrowser" { module "filebrowser" {
source = "registry.coder.com/modules/filebrowser/coder" source = "registry.coder.com/modules/filebrowser/coder"
version = "1.0.0" version = "1.0.3"
agent_id = coder_agent.example.id agent_id = coder_agent.example.id
database_path = ".config/filebrowser.db" database_path = ".config/filebrowser.db"
} }

View File

@@ -33,7 +33,7 @@ describe("filebrowser", async () => {
expect(output.stdout).toEqual([ expect(output.stdout).toEqual([
"\u001b[0;1mInstalling filebrowser ", "\u001b[0;1mInstalling filebrowser ",
"", "",
"🥳 Installation comlete! ", "🥳 Installation complete! ",
"", "",
"👷 Starting filebrowser in background... ", "👷 Starting filebrowser in background... ",
"", "",
@@ -55,7 +55,7 @@ describe("filebrowser", async () => {
expect(output.stdout).toEqual([ expect(output.stdout).toEqual([
"\u001b[0;1mInstalling filebrowser ", "\u001b[0;1mInstalling filebrowser ",
"", "",
"🥳 Installation comlete! ", "🥳 Installation complete! ",
"", "",
"👷 Starting filebrowser in background... ", "👷 Starting filebrowser in background... ",
"", "",
@@ -77,7 +77,7 @@ describe("filebrowser", async () => {
expect(output.stdout).toEqual([ expect(output.stdout).toEqual([
"\u001B[0;1mInstalling filebrowser ", "\u001B[0;1mInstalling filebrowser ",
"", "",
"🥳 Installation comlete! ", "🥳 Installation complete! ",
"", "",
"👷 Starting filebrowser in background... ", "👷 Starting filebrowser in background... ",
"", "",

View File

@@ -5,7 +5,7 @@ printf "$${BOLD}Installing filebrowser \n\n"
curl -fsSL https://raw.githubusercontent.com/filebrowser/get/master/get.sh | bash curl -fsSL https://raw.githubusercontent.com/filebrowser/get/master/get.sh | bash
printf "🥳 Installation comlete! \n\n" printf "🥳 Installation complete! \n\n"
printf "👷 Starting filebrowser in background... \n\n" printf "👷 Starting filebrowser in background... \n\n"

View File

@@ -13,10 +13,10 @@ This module adds Fly.io regions to your Coder template. Regions can be whitelist
We can use the simplest format here, only adding a default selection as the `atl` region. We can use the simplest format here, only adding a default selection as the `atl` region.
```hcl ```tf
module "fly-region" { module "fly-region" {
source = "registry.coder.com/modules/fly-region/coder" source = "registry.coder.com/modules/fly-region/coder"
version = "1.0.0" version = "1.0.2"
default = "atl" default = "atl"
} }
``` ```
@@ -29,10 +29,10 @@ module "fly-region" {
The regions argument can be used to display only the desired regions in the Coder parameter. The regions argument can be used to display only the desired regions in the Coder parameter.
```hcl ```tf
module "fly-region" { module "fly-region" {
source = "registry.coder.com/modules/fly-region/coder" source = "registry.coder.com/modules/fly-region/coder"
version = "1.0.0" version = "1.0.2"
default = "ams" default = "ams"
regions = ["ams", "arn", "atl"] regions = ["ams", "arn", "atl"]
} }
@@ -44,14 +44,16 @@ module "fly-region" {
Set custom icons and names with their respective maps. Set custom icons and names with their respective maps.
```hcl ```tf
module "fly-region" { module "fly-region" {
source = "registry.coder.com/modules/fly-region/coder" source = "registry.coder.com/modules/fly-region/coder"
version = "1.0.0" version = "1.0.2"
default = "ams" default = "ams"
custom_icons = { custom_icons = {
"ams" = "/emojis/1f90e.png" "ams" = "/emojis/1f90e.png"
} }
custom_names = { custom_names = {
"ams" = "We love the Netherlands!" "ams" = "We love the Netherlands!"
} }

View File

@@ -11,10 +11,10 @@ tags: [gcp, regions, parameter, helper]
This module adds Google Cloud Platform regions to your Coder template. This module adds Google Cloud Platform regions to your Coder template.
```hcl ```tf
module "gcp_region" { module "gcp_region" {
source = "registry.coder.com/modules/gcp-region/coder" source = "registry.coder.com/modules/gcp-region/coder"
version = "1.0.0" version = "1.0.2"
regions = ["us", "europe"] regions = ["us", "europe"]
} }
@@ -31,10 +31,10 @@ resource "google_compute_instance" "example" {
Note: setting `gpu_only = true` and using a default region without GPU support, the default will be set to `null`. Note: setting `gpu_only = true` and using a default region without GPU support, the default will be set to `null`.
```hcl ```tf
module "gcp_region" { module "gcp_region" {
source = "registry.coder.com/modules/gcp-region/coder" source = "registry.coder.com/modules/gcp-region/coder"
version = "1.0.0" version = "1.0.2"
default = ["us-west1-a"] default = ["us-west1-a"]
regions = ["us-west1"] regions = ["us-west1"]
gpu_only = false gpu_only = false
@@ -47,10 +47,10 @@ resource "google_compute_instance" "example" {
### Add all zones in the Europe West region ### Add all zones in the Europe West region
```hcl ```tf
module "gcp_region" { module "gcp_region" {
source = "registry.coder.com/modules/gcp-region/coder" source = "registry.coder.com/modules/gcp-region/coder"
version = "1.0.0" version = "1.0.2"
regions = ["europe-west"] regions = ["europe-west"]
single_zone_per_region = false single_zone_per_region = false
} }
@@ -60,12 +60,12 @@ resource "google_compute_instance" "example" {
} }
``` ```
### Add a single zone from each region in US and Europe that laos has GPUs ### Add a single zone from each region in US and Europe that has GPUs
```hcl ```tf
module "gcp_region" { module "gcp_region" {
source = "registry.coder.com/modules/gcp-region/coder" source = "registry.coder.com/modules/gcp-region/coder"
version = "1.0.0" version = "1.0.2"
regions = ["us", "europe"] regions = ["us", "europe"]
gpu_only = true gpu_only = true
single_zone_per_region = true single_zone_per_region = true

View File

@@ -9,35 +9,44 @@ tags: [git, helper]
# Git Clone # Git Clone
This module allows you to automatically clone a repository by URL and skip if it exists in the path provided. This module allows you to automatically clone a repository by URL and skip if it exists in the base directory provided.
```hcl ```tf
module "git-clone" { module "git-clone" {
source = "registry.coder.com/modules/git-clone/coder" source = "registry.coder.com/modules/git-clone/coder"
version = "1.0.0" version = "1.0.2"
agent_id = coder_agent.example.id agent_id = coder_agent.example.id
url = "https://github.com/coder/coder" url = "https://github.com/coder/coder"
} }
``` ```
To use with [Git Authentication](https://coder.com/docs/v2/latest/admin/git-providers), add the provider by ID to your template:
```hcl
data "coder_git_auth" "github" {
id = "github"
}
```
## Examples ## Examples
### Custom Path ### Custom Path
```hcl ```tf
module "git-clone" { module "git-clone" {
source = "registry.coder.com/modules/git-clone/coder" source = "registry.coder.com/modules/git-clone/coder"
version = "1.0.0" version = "1.0.2"
agent_id = coder_agent.example.id agent_id = coder_agent.example.id
url = "https://github.com/coder/coder" url = "https://github.com/coder/coder"
path = "~/projects/coder/coder" base_dir = "~/projects/coder"
}
```
### Git Authentication
To use with [Git Authentication](https://coder.com/docs/v2/latest/admin/git-providers), add the provider by ID to your template:
```tf
module "git-clone" {
source = "registry.coder.com/modules/git-clone/coder"
version = "1.0.2"
agent_id = coder_agent.example.id
url = "https://github.com/coder/coder"
}
data "coder_git_auth" "github" {
id = "github"
} }
``` ```

View File

@@ -14,9 +14,9 @@ variable "url" {
type = string type = string
} }
variable "path" { variable "base_dir" {
default = "" default = ""
description = "The path to clone the repository. Defaults to \"$HOME/<basename of url>\"." description = "The base directory to clone the repository. Defaults to \"$HOME\"."
type = string type = string
} }
@@ -25,10 +25,19 @@ variable "agent_id" {
type = string type = string
} }
locals {
clone_path = var.base_dir != "" ? join("/", [var.base_dir, replace(basename(var.url), ".git", "")]) : join("/", ["~", replace(basename(var.url), ".git", "")])
}
output "repo_dir" {
value = local.clone_path
description = "Full path of cloned repo directory"
}
resource "coder_script" "git_clone" { resource "coder_script" "git_clone" {
agent_id = var.agent_id agent_id = var.agent_id
script = templatefile("${path.module}/run.sh", { script = templatefile("${path.module}/run.sh", {
CLONE_PATH = var.path != "" ? join("/", [var.path, replace(basename(var.url), ".git", "")]) : join("/", ["~", replace(basename(var.url), ".git", "")]) CLONE_PATH = local.clone_path
REPO_URL : var.url, REPO_URL : var.url,
}) })
display_name = "Git Clone" display_name = "Git Clone"

View File

@@ -16,10 +16,10 @@ Please observe that using the SSH key that's part of your Coder account for comm
This module has a chance of conflicting with the user's dotfiles / the personalize module if one of those has configuration directives that overwrite this module's / each other's git configuration. This module has a chance of conflicting with the user's dotfiles / the personalize module if one of those has configuration directives that overwrite this module's / each other's git configuration.
```hcl ```tf
module "git-commit-signing" { module "git-commit-signing" {
source = "registry.coder.com/modules/git-commit-signing/coder" source = "registry.coder.com/modules/git-commit-signing/coder"
version = "1.0.0" version = "1.0.3"
agent_id = coder_agent.example.id agent_id = coder_agent.example.id
} }
``` ```

View File

@@ -31,8 +31,8 @@ jq --raw-output ".private_key" > ~/.ssh/git-commit-signing/coder << EOF
$ssh_key $ssh_key
EOF EOF
chmod -R 400 ~/.ssh/git-commit-signing/coder chmod -R 600 ~/.ssh/git-commit-signing/coder
chmod -R 400 ~/.ssh/git-commit-signing/coder.pub chmod -R 644 ~/.ssh/git-commit-signing/coder.pub
echo "Configuring git to use the SSH key" echo "Configuring git to use the SSH key"

View File

@@ -11,10 +11,10 @@ tags: [helper, git]
Runs a script that updates git credentials in the workspace to match the user's Coder credentials, optionally allowing to the developer to override the defaults. Runs a script that updates git credentials in the workspace to match the user's Coder credentials, optionally allowing to the developer to override the defaults.
```hcl ```tf
module "git-config" { module "git-config" {
source = "registry.coder.com/modules/git-config/coder" source = "registry.coder.com/modules/git-config/coder"
version = "1.0.0" version = "1.0.3"
agent_id = coder_agent.example.id agent_id = coder_agent.example.id
} }
``` ```
@@ -25,10 +25,10 @@ TODO: Add screenshot
### Allow users to override both username and email ### Allow users to override both username and email
```hcl ```tf
module "git-config" { module "git-config" {
source = "registry.coder.com/modules/git-config/coder" source = "registry.coder.com/modules/git-config/coder"
version = "1.0.0" version = "1.0.3"
agent_id = coder_agent.example.id agent_id = coder_agent.example.id
allow_email_change = true allow_email_change = true
} }
@@ -38,14 +38,12 @@ TODO: Add screenshot
## Disallowing users from overriding both username and email ## Disallowing users from overriding both username and email
```hcl ```tf
module "git-config" { module "git-config" {
source = "registry.coder.com/modules/git-config/coder" source = "registry.coder.com/modules/git-config/coder"
version = "1.0.0" version = "1.0.3"
agent_id = coder_agent.example.id agent_id = coder_agent.example.id
allow_username_change = false allow_username_change = false
allow_email_change = false allow_email_change = false
} }
``` ```
TODO: Add screenshot

View File

@@ -1,43 +0,0 @@
import { describe, expect, it } from "bun:test";
import {
executeScriptInContainer,
runTerraformApply,
runTerraformInit,
testRequiredVariables,
} from "../test";
describe("git-config", async () => {
await runTerraformInit(import.meta.dir);
testRequiredVariables(import.meta.dir, {
agent_id: "foo",
});
it("fails without git", async () => {
const state = await runTerraformApply(import.meta.dir, {
agent_id: "foo",
});
const output = await executeScriptInContainer(state, "alpine");
expect(output.exitCode).toBe(1);
expect(output.stdout).toEqual([
"\u001B[0;1mChecking git-config!",
"Git is not installed!",
]);
});
it("runs with git", async () => {
const state = await runTerraformApply(import.meta.dir, {
agent_id: "foo",
});
const output = await executeScriptInContainer(state, "alpine/git");
expect(output.exitCode).toBe(0);
expect(output.stdout).toEqual([
"\u001B[0;1mChecking git-config!",
"git-config: No user.email found, setting to ",
"git-config: No user.name found, setting to default",
"",
"\u001B[0;1mgit-config: using email: ",
"\u001B[0;1mgit-config: using username: default",
]);
});
});

View File

@@ -4,7 +4,7 @@ terraform {
required_providers { required_providers {
coder = { coder = {
source = "coder/coder" source = "coder/coder"
version = ">= 0.12" version = ">= 0.13"
} }
} }
} }
@@ -34,7 +34,7 @@ data "coder_parameter" "user_email" {
name = "user_email" name = "user_email"
type = "string" type = "string"
default = "" default = ""
description = "Git user.email to be used for commits. Leave empty to default to Coder username." description = "Git user.email to be used for commits. Leave empty to default to Coder user's email."
display_name = "Git config user.email" display_name = "Git config user.email"
mutable = true mutable = true
} }
@@ -44,18 +44,31 @@ data "coder_parameter" "username" {
name = "username" name = "username"
type = "string" type = "string"
default = "" default = ""
description = "Git user.name to be used for commits. Leave empty to default to Coder username." description = "Git user.name to be used for commits. Leave empty to default to Coder user's Full Name."
display_name = "Git config user.name" display_name = "Full Name for Git config"
mutable = true mutable = true
} }
resource "coder_script" "git_config" { resource "coder_env" "git_author_name" {
agent_id = var.agent_id agent_id = var.agent_id
script = templatefile("${path.module}/run.sh", { name = "GIT_AUTHOR_NAME"
GIT_USERNAME = try(data.coder_parameter.username[0].value, "") == "" ? data.coder_workspace.me.owner : try(data.coder_parameter.username[0].value, "") value = coalesce(try(data.coder_parameter.username[0].value, ""), data.coder_workspace.me.owner_name, data.coder_workspace.me.owner)
GIT_EMAIL = try(data.coder_parameter.user_email[0].value, "") == "" ? data.coder_workspace.me.owner_email : try(data.coder_parameter.user_email[0].value, "") }
})
display_name = "Git Config" resource "coder_env" "git_commmiter_name" {
icon = "/icon/git.svg" agent_id = var.agent_id
run_on_start = true name = "GIT_COMMITTER_NAME"
value = coalesce(try(data.coder_parameter.username[0].value, ""), data.coder_workspace.me.owner_name, data.coder_workspace.me.owner)
}
resource "coder_env" "git_author_email" {
agent_id = var.agent_id
name = "GIT_AUTHOR_EMAIL"
value = coalesce(try(data.coder_parameter.user_email[0].value, ""), data.coder_workspace.me.owner_email)
}
resource "coder_env" "git_commmiter_email" {
agent_id = var.agent_id
name = "GIT_COMMITTER_EMAIL"
value = coalesce(try(data.coder_parameter.user_email[0].value, ""), data.coder_workspace.me.owner_email)
} }

View File

@@ -1,24 +0,0 @@
#!/usr/bin/env sh
BOLD='\033[0;1m'
printf "$${BOLD}Checking git-config!\n"
# Check if git is installed
command -v git > /dev/null 2>&1 || {
echo "Git is not installed!"
exit 1
}
# Set git username and email if missing
if [ -z $(git config --get user.email) ]; then
printf "git-config: No user.email found, setting to ${GIT_EMAIL}\n"
git config --global user.email "${GIT_EMAIL}"
fi
if [ -z $(git config --get user.name) ]; then
printf "git-config: No user.name found, setting to ${GIT_USERNAME}\n"
git config --global user.name "${GIT_USERNAME}"
fi
printf "\n$${BOLD}git-config: using email: $(git config --get user.email)\n"
printf "$${BOLD}git-config: using username: $(git config --get user.name)\n\n"

View File

@@ -0,0 +1,68 @@
---
display_name: "HCP Vault Secrets"
description: "Fetch secrets from HCP Vault"
icon: ../.icons/vault.svg
maintainer_github: coder
partner_github: hashicorp
verified: true
tags: [helper, integration, vault, hashicorp, hvs]
---
# HCP Vault Secrets
This module lets you fetch all or selective secrets from a [HCP Vault Secrets](https://developer.hashicorp.com/hcp/docs/vault-secrets) app into your [Coder](https://coder.com) workspaces. It makes use of the [`hcp_vault_secrets_app`](https://registry.terraform.io/providers/hashicorp/hcp/latest/docs/data-sources/vault_secrets_app) data source from the [HCP provider](https://registry.terraform.io/providers/hashicorp/hcp/latest).
```tf
module "vault" {
source = "registry.coder.com/modules/hcp-vault-secrets/coder"
version = "1.0.3"
agent_id = coder_agent.example.id
app_name = "demo-app"
}
```
## Configuration
To configure the HCP Vault Secrets module, you must create an HCP Service Principal from the HCP Vault Secrets app in the HCP console. This will give you the `HCP_CLIENT_ID` and `HCP_CLIENT_SECRET` that you need to authenticate with HCP Vault Secrets. See the [HCP Vault Secrets documentation](https://developer.hashicorp.com/hcp/docs/vault-secrets) for more information.
## Fetch All Secrets
To fetch all secrets from the HCP Vault Secrets app, skip the `secrets` input.
```tf
module "vault" {
source = "registry.coder.com/modules/hcp-vault-secrets/coder"
version = "1.0.3"
agent_id = coder_agent.example.id
app_name = "demo-app"
}
```
## Fetch Selective Secrets
To fetch selective secrets from the HCP Vault Secrets app, set the `secrets` input.
```tf
module "vault" {
source = "registry.coder.com/modules/hcp-vault-secrets/coder"
version = "1.0.3"
agent_id = coder_agent.example.id
app_name = "demo-app"
secrets = ["MY_SECRET_1", "MY_SECRET_2"]
}
```
## Set Client ID and Client Secret as Inputs
Set `client_id` and `client_secret` as module inputs.
```tf
module "vault" {
source = "registry.coder.com/modules/hcp-vault-secrets/coder"
version = "1.0.3"
agent_id = coder_agent.example.id
app_name = "demo-app"
client_id = "HCP_CLIENT_ID"
client_secret = "HCP_CLIENT_SECRET"
}
```

67
hcp-vault-secrets/main.tf Normal file
View File

@@ -0,0 +1,67 @@
terraform {
required_version = ">= 1.0"
required_providers {
coder = {
source = "coder/coder"
version = ">= 0.12.4"
}
hcp = {
source = "hashicorp/hcp"
version = ">= 0.82.0"
}
}
}
provider "hcp" {
client_id = var.client_id
client_secret = var.client_secret
}
provider "coder" {}
variable "agent_id" {
type = string
description = "The ID of a Coder agent."
}
variable "client_id" {
type = string
description = <<-EOF
The client ID for the HCP Vault Secrets service principal. (Optional if HCP_CLIENT_ID is set as an environment variable.)
EOF
default = null
sensitive = true
}
variable "client_secret" {
type = string
description = <<-EOF
The client secret for the HCP Vault Secrets service principal. (Optional if HCP_CLIENT_SECRET is set as an environment variable.)
EOF
default = null
sensitive = true
}
variable "app_name" {
type = string
description = "The name of the secrets app in HCP Vault Secrets"
}
variable "secrets" {
type = list(string)
description = "The names of the secrets to retrieve from HCP Vault Secrets"
default = null
}
data "hcp_vault_secrets_app" "secrets" {
app_name = var.app_name
}
resource "coder_env" "hvs_secrets" {
# https://support.hashicorp.com/hc/en-us/articles/4538432032787-Variable-has-a-sensitive-value-and-cannot-be-used-as-for-each-arguments
for_each = var.secrets != null ? toset(var.secrets) : nonsensitive(toset(keys(data.hcp_vault_secrets_app.secrets.secrets)))
agent_id = var.agent_id
name = each.key
value = data.hcp_vault_secrets_app.secrets.secrets[each.key]
}

View File

@@ -11,11 +11,12 @@ tags: [ide, jetbrains, helper, parameter]
This module adds a JetBrains Gateway Button to open any workspace with a single click. This module adds a JetBrains Gateway Button to open any workspace with a single click.
```hcl ```tf
module "jetbrains_gateway" { module "jetbrains_gateway" {
source = "registry.coder.com/modules/jetbrains-gateway/coder" source = "registry.coder.com/modules/jetbrains-gateway/coder"
version = "1.0.0" version = "1.0.3"
agent_id = coder_agent.example.id agent_id = coder_agent.example.id
agent_name = "example"
folder = "/home/coder/example" folder = "/home/coder/example"
jetbrains_ides = ["GO", "WS", "IU", "PY", "PS", "CL", "RM"] jetbrains_ides = ["GO", "WS", "IU", "PY", "PS", "CL", "RM"]
default = "PY" default = "PY"
@@ -28,11 +29,12 @@ module "jetbrains_gateway" {
### Add GoLand and WebStorm with the default set to GoLand ### Add GoLand and WebStorm with the default set to GoLand
```hcl ```tf
module "jetbrains_gateway" { module "jetbrains_gateway" {
source = "registry.coder.com/modules/jetbrains-gateway/coder" source = "registry.coder.com/modules/jetbrains-gateway/coder"
version = "1.0.0" version = "1.0.3"
agent_id = coder_agent.example.id agent_id = coder_agent.example.id
agent_name = "example"
folder = "/home/coder/example" folder = "/home/coder/example"
jetbrains_ides = ["GO", "WS"] jetbrains_ides = ["GO", "WS"]
default = "GO" default = "GO"

View File

@@ -30,17 +30,68 @@ variable "default" {
description = "Default IDE" description = "Default IDE"
} }
variable "jetbrains_ides" { locals {
type = list(string) supported_ides = ["IU", "PS", "WS", "PY", "CL", "GO", "RM"]
description = "The list of IDE product codes." }
default = ["IU", "PS", "WS", "PY", "CL", "GO", "RM"]
variable "jetbrains_ide_versions" {
type = map(object({
build_number = string
version = string
}))
description = "The set of versions for each jetbrains IDE"
default = {
"IU" = {
build_number = "232.10203.10"
version = "2023.2.4"
}
"PS" = {
build_number = "232.10072.32"
version = "2023.2.3"
}
"WS" = {
build_number = "232.10203.14"
version = "2023.2.4"
}
"PY" = {
build_number = "232.10203.26"
version = "2023.2.4"
}
"CL" = {
build_number = "232.9921.42"
version = "2023.2.2"
}
"GO" = {
build_number = "232.10203.20"
version = "2023.2.4"
}
"RM" = {
build_number = "232.10203.15"
version = "2023.2.4"
}
}
validation { validation {
condition = ( condition = (
alltrue([ alltrue([
for code in var.jetbrains_ides : contains(["IU", "PS", "WS", "PY", "CL", "GO", "RM"], code) for code in var.jetbrains_ide_versions : contains(local.supported_ides, code)
]) ])
) )
error_message = "The jetbrains_ides must be a list of valid product codes. Valid product codes are IU, PS, WS, PY, CL, GO, RM." error_message = "The jetbrains_ide_versions must contain a map of valid product codes. Valid product codes are ${join(",", local.supported_ides)}."
}
}
variable "jetbrains_ides" {
type = list(string)
description = "The list of IDE product codes."
default = local.supported_ides
validation {
condition = (
alltrue([
for code in var.jetbrains_ides : contains(local.supported_ides, code)
])
)
error_message = "The jetbrains_ides must be a list of valid product codes. Valid product codes are ${join(",", local.supported_ides)}."
} }
# check if the list is empty # check if the list is empty
validation { validation {
@@ -59,37 +110,37 @@ locals {
"GO" = { "GO" = {
icon = "/icon/goland.svg", icon = "/icon/goland.svg",
name = "GoLand", name = "GoLand",
value = jsonencode(["GO", "232.10203.20", "https://download.jetbrains.com/go/goland-2023.2.4.tar.gz"]) value = jsonencode(["GO", var.jetbrains_ide_versions["GO"].build_number, "https://download.jetbrains.com/go/goland-${var.jetbrains_ide_versions["GO"].version}.tar.gz"])
}, },
"WS" = { "WS" = {
icon = "/icon/webstorm.svg", icon = "/icon/webstorm.svg",
name = "WebStorm", name = "WebStorm",
value = jsonencode(["WS", "232.10203.14", "https://download.jetbrains.com/webstorm/WebStorm-2023.2.4.tar.gz"]) value = jsonencode(["WS", var.jetbrains_ide_versions["WS"].build_number, "https://download.jetbrains.com/webstorm/WebStorm-${var.jetbrains_ide_versions["WS"].version}.tar.gz"])
}, },
"IU" = { "IU" = {
icon = "/icon/intellij.svg", icon = "/icon/intellij.svg",
name = "IntelliJ IDEA Ultimate", name = "IntelliJ IDEA Ultimate",
value = jsonencode(["IU", "232.10203.10", "https://download.jetbrains.com/idea/ideaIU-2023.2.4.tar.gz"]) value = jsonencode(["IU", var.jetbrains_ide_versions["IU"].build_number, "https://download.jetbrains.com/idea/ideaIU-${var.jetbrains_ide_versions["IU"].version}.tar.gz"])
}, },
"PY" = { "PY" = {
icon = "/icon/pycharm.svg", icon = "/icon/pycharm.svg",
name = "PyCharm Professional", name = "PyCharm Professional",
value = jsonencode(["PY", "232.10203.26", "https://download.jetbrains.com/python/pycharm-professional-2023.2.4.tar.gz"]) value = jsonencode(["PY", var.jetbrains_ide_versions["PY"].build_number, "https://download.jetbrains.com/python/pycharm-professional-${var.jetbrains_ide_versions["PY"].version}.tar.gz"])
}, },
"CL" = { "CL" = {
icon = "/icon/clion.svg", icon = "/icon/clion.svg",
name = "CLion", name = "CLion",
value = jsonencode(["CL", "232.9921.42", "https://download.jetbrains.com/cpp/CLion-2023.2.2.tar.gz"]) value = jsonencode(["CL", var.jetbrains_ide_versions["CL"].build_number, "https://download.jetbrains.com/cpp/CLion-${var.jetbrains_ide_versions["CL"].version}.tar.gz"])
}, },
"PS" = { "PS" = {
icon = "/icon/phpstorm.svg", icon = "/icon/phpstorm.svg",
name = "PhpStorm", name = "PhpStorm",
value = jsonencode(["PS", "232.10072.32", "https://download.jetbrains.com/webide/PhpStorm-2023.2.3.tar.gz"]) value = jsonencode(["PS", var.jetbrains_ide_versions["PS"].build_number, "https://download.jetbrains.com/webide/PhpStorm-${var.jetbrains_ide_versions["PS"].version}.tar.gz"])
}, },
"RM" = { "RM" = {
icon = "/icon/rubymine.svg", icon = "/icon/rubymine.svg",
name = "RubyMine", name = "RubyMine",
value = jsonencode(["RM", "232.10203.15", "https://download.jetbrains.com/ruby/RubyMine-2023.2.4.tar.gz"]) value = jsonencode(["RM", var.jetbrains_ide_versions["RM"].build_number, "https://download.jetbrains.com/ruby/RubyMine-${var.jetbrains_ide_versions["RM"].version}.tar.gz"])
} }
} }
} }

View File

@@ -10,23 +10,22 @@ tags: [integration, jfrog]
# JFrog # JFrog
Install the JF CLI and authenticate package managers with Artifactory using OAuth configured via the Coder `external-auth` feature. Install the JF CLI and authenticate package managers with Artifactory using OAuth configured via the Coder [`external-auth`](https://coder.com/docs/v2/latest/admin/external-auth) feature.
<p align="center"> ![JFrog OAuth](../.images/jfrog-oauth.png)
<img src='../.images/jfrog-oauth.png' alt="JFrog OAuth" width='600'>
</p>
```hcl ```tf
module "jfrog" { module "jfrog" {
source = "registry.coder.com/modules/jfrog-oauth/coder" source = "registry.coder.com/modules/jfrog-oauth/coder"
version = "1.0.0" version = "1.0.2"
agent_id = coder_agent.example.id agent_id = coder_agent.example.id
jfrog_url = "https://jfrog.example.com" jfrog_url = "https://example.jfrog.io"
username_field = "username" # If you are using GitHub to login to both Coder and Artifactory, use username_field = "username" username_field = "username" # If you are using GitHub to login to both Coder and Artifactory, use username_field = "username"
package_managers = { package_managers = {
"npm": "npm", "npm" : "npm",
"go": "go", "go" : "go",
"pypi": "pypi" "pypi" : "pypi"
} }
} }
``` ```
@@ -36,64 +35,22 @@ module "jfrog" {
## Prerequisites ## Prerequisites
Coder [`external-auth`](https://coder.com/docs/v2/latest/admin/external-auth) configured with Artifactory. This requires a [custom integration](https://jfrog.com/help/r/jfrog-installation-setup-documentation/enable-new-integrations) in Artifactory with **Callback URL** set to `https://<your-coder-url>/external-auth/jfrog/callback`. This module is usable by JFrog self-hosted (on-premises) Artifactory as it requires configuring a custom integration. This integration benefits from Coder's [external-auth](https://coder.com/docs/v2/latest/admin/external-auth) feature and allows each user to authenticate with Artifactory using an OAuth flow and issues user-scoped tokens to each user. For configuration instructions, see this [guide](https://coder.com/docs/v2/latest/guides/artifactory-integration#jfrog-oauth) on the Coder documentation.
To set this up,
1. Modify your `values.yaml` for JFrog Artifactory to add,
```yaml
artifactory:
enabled: true
frontend:
extraEnvironmentVariables:
- name: JF_FRONTEND_FEATURETOGGLER_ACCESSINTEGRATION
value: "true"
access:
accessConfig:
integrations-enabled: true
integration-templates:
- id: "1"
name: "CODER"
redirect-uri: "https://CODER_URL/external-auth/jfrog/callback"
scope: "applied-permissions/user"
```
> Note
> Replace `CODER_URL` with your Coder deployment URL, e.g., <coder.example.com>
2. Add a new [external authetication](https://coder.com/docs/v2/latest/admin/external-auth) to Coder by setting these env variables,
```env
# JFrog Artifactory External Auth
CODER_EXTERNAL_AUTH_1_ID="jfrog"
CODER_EXTERNAL_AUTH_1_TYPE="jfrog"
CODER_EXTERNAL_AUTH_1_CLIENT_ID="YYYYYYYYYYYYYYY"
CODER_EXTERNAL_AUTH_1_CLIENT_SECRET="XXXXXXXXXXXXXXXXXXX"
CODER_EXTERNAL_AUTH_1_DISPLAY_NAME="JFrog Artifactory"
CODER_EXTERNAL_AUTH_1_DISPLAY_ICON="/icon/jfrog.svg"
CODER_EXTERNAL_AUTH_1_AUTH_URL="https://JFROG_URL/ui/authorization"
CODER_EXTERNAL_AUTH_1_TOKEN_URL="https://JFROG_URL/access/api/v1/integrations/YYYYYYYYYYYYYYY/token"
CODER_EXTERNAL_AUTH_1_SCOPES="applied-permissions/user"
```
> Note
> Replace `JFROG_URL` with your JFrog Artifactory base URL, e.g., <artifactory.example.com>
## Examples ## Examples
Configure the Python pip package manager to fetch packages from Artifactory while mapping the Coder email to the Artifactory username. Configure the Python pip package manager to fetch packages from Artifactory while mapping the Coder email to the Artifactory username.
```hcl ```tf
module "jfrog" { module "jfrog" {
source = "registry.coder.com/modules/jfrog-oauth/coder" source = "registry.coder.com/modules/jfrog-oauth/coder"
version = "1.0.0" version = "1.0.2"
agent_id = coder_agent.example.id agent_id = coder_agent.example.id
jfrog_url = "https://jfrog.example.com" jfrog_url = "https://example.jfrog.io"
auth_method = "oauth"
username_field = "email" username_field = "email"
package_managers = { package_managers = {
"pypi": "pypi" "pypi" : "pypi"
} }
} }
``` ```
@@ -112,18 +69,18 @@ pip install requests
The [JFrog extension](https://open-vsx.org/extension/JFrog/jfrog-vscode-extension) for VS Code allows you to interact with Artifactory from within the IDE. The [JFrog extension](https://open-vsx.org/extension/JFrog/jfrog-vscode-extension) for VS Code allows you to interact with Artifactory from within the IDE.
```hcl ```tf
module "jfrog" { module "jfrog" {
source = "registry.coder.com/modules/jfrog-oauth/coder" source = "registry.coder.com/modules/jfrog-oauth/coder"
version = "1.0.0" version = "1.0.2"
agent_id = coder_agent.example.id agent_id = coder_agent.example.id
jfrog_url = "https://jfrog.example.com" jfrog_url = "https://example.jfrog.io"
username_field = "username" # If you are using GitHub to login to both Coder and Artifactory, use username_field = "username" username_field = "username" # If you are using GitHub to login to both Coder and Artifactory, use username_field = "username"
configure_code_server = true # Add JFrog extension configuration for code-server configure_code_server = true # Add JFrog extension configuration for code-server
package_managers = { package_managers = {
"npm": "npm", "npm" : "npm",
"go": "go", "go" : "go",
"pypi": "pypi" "pypi" : "pypi"
} }
} }
``` ```
@@ -132,14 +89,15 @@ module "jfrog" {
JFrog Access token is also available as a terraform output. You can use it in other terraform resources. For example, you can use it to configure an [Artifactory docker registry](https://jfrog.com/help/r/jfrog-artifactory-documentation/docker-registry) with the [docker terraform provider](https://registry.terraform.io/providers/kreuzwerker/docker/latest/docs). JFrog Access token is also available as a terraform output. You can use it in other terraform resources. For example, you can use it to configure an [Artifactory docker registry](https://jfrog.com/help/r/jfrog-artifactory-documentation/docker-registry) with the [docker terraform provider](https://registry.terraform.io/providers/kreuzwerker/docker/latest/docs).
```hcl ```tf
provider "docker" { provider "docker" {
... # ...
registry_auth { registry_auth {
address = "https://YYYY.jfrog.io/artifactory/api/docker/REPO-KEY" address = "https://example.jfrog.io/artifactory/api/docker/REPO-KEY"
username = module.jfrog.username username = module.jfrog.username
password = module.jfrog.access_token password = module.jfrog.access_token
} }
} }
``` ```
> Here `REPO_KEY` is the name of docker repository in Artifactory.

View File

@@ -12,29 +12,22 @@ tags: [integration, jfrog]
Install the JF CLI and authenticate package managers with Artifactory using Artifactory terraform provider. Install the JF CLI and authenticate package managers with Artifactory using Artifactory terraform provider.
```hcl ```tf
module "jfrog" { module "jfrog" {
source = "registry.coder.com/modules/jfrog-token/coder" source = "registry.coder.com/modules/jfrog-token/coder"
version = "1.0.0" version = "1.0.2"
agent_id = coder_agent.example.id agent_id = coder_agent.example.id
jfrog_url = "https://XXXX.jfrog.io" jfrog_url = "https://XXXX.jfrog.io"
artifactory_access_token = var.artifactory_access_token artifactory_access_token = var.artifactory_access_token
package_managers = { package_managers = {
"npm": "npm", "npm" : "npm",
"go": "go", "go" : "go",
"pypi": "pypi" "pypi" : "pypi"
} }
} }
``` ```
Get a JFrog access token from your Artifactory instance. The token must be an [admin token](https://registry.terraform.io/providers/jfrog/artifactory/latest/docs#access-token). It is recommended to store the token in a secret terraform variable. For detailed instructions, please see this [guide](https://coder.com/docs/v2/latest/guides/artifactory-integration#jfrog-token) on the Coder documentation.
```hcl
variable "artifactory_access_token" {
type = string
sensitive = true
}
```
> Note > Note
> This module does not install `npm`, `go`, `pip`, etc but only configure them. You need to handle the installation of these tools yourself. > This module does not install `npm`, `go`, `pip`, etc but only configure them. You need to handle the installation of these tools yourself.
@@ -45,17 +38,17 @@ variable "artifactory_access_token" {
### Configure npm, go, and pypi to use Artifactory local repositories ### Configure npm, go, and pypi to use Artifactory local repositories
```hcl ```tf
module "jfrog" { module "jfrog" {
source = "registry.coder.com/modules/jfrog-token/coder" source = "registry.coder.com/modules/jfrog-token/coder"
version = "1.0.0" version = "1.0.2"
agent_id = coder_agent.example.id agent_id = coder_agent.example.id
jfrog_url = "https://YYYY.jfrog.io" jfrog_url = "https://YYYY.jfrog.io"
artifactory_access_token = var.artifactory_access_token # An admin access token artifactory_access_token = var.artifactory_access_token # An admin access token
package_managers = { package_managers = {
"npm": "npm-local", "npm" : "npm-local",
"go": "go-local", "go" : "go-local",
"pypi": "pypi-local" "pypi" : "pypi-local"
} }
} }
``` ```
@@ -78,18 +71,18 @@ pip install requests
The [JFrog extension](https://open-vsx.org/extension/JFrog/jfrog-vscode-extension) for VS Code allows you to interact with Artifactory from within the IDE. The [JFrog extension](https://open-vsx.org/extension/JFrog/jfrog-vscode-extension) for VS Code allows you to interact with Artifactory from within the IDE.
```hcl ```tf
module "jfrog" { module "jfrog" {
source = "registry.coder.com/modules/jfrog-token/coder" source = "registry.coder.com/modules/jfrog-token/coder"
version = "1.0.0" version = "1.0.2"
agent_id = coder_agent.example.id agent_id = coder_agent.example.id
jfrog_url = "https://XXXX.jfrog.io" jfrog_url = "https://XXXX.jfrog.io"
artifactory_access_token = var.artifactory_access_token artifactory_access_token = var.artifactory_access_token
configure_code_server = true # Add JFrog extension configuration for code-server configure_code_server = true # Add JFrog extension configuration for code-server
package_managers = { package_managers = {
"npm": "npm", "npm" : "npm",
"go": "go", "go" : "go",
"pypi": "pypi" "pypi" : "pypi"
} }
} }
``` ```
@@ -98,10 +91,10 @@ module "jfrog" {
JFrog Access token is also available as a terraform output. You can use it in other terraform resources. For example, you can use it to configure an [Artifactory docker registry](https://jfrog.com/help/r/jfrog-artifactory-documentation/docker-registry) with the [docker terraform provider](https://registry.terraform.io/providers/kreuzwerker/docker/latest/docs). JFrog Access token is also available as a terraform output. You can use it in other terraform resources. For example, you can use it to configure an [Artifactory docker registry](https://jfrog.com/help/r/jfrog-artifactory-documentation/docker-registry) with the [docker terraform provider](https://registry.terraform.io/providers/kreuzwerker/docker/latest/docs).
```hcl ```tf
provider "docker" { provider "docker" {
... # ...
registry_auth { registry_auth {
address = "https://YYYY.jfrog.io/artifactory/api/docker/REPO-KEY" address = "https://YYYY.jfrog.io/artifactory/api/docker/REPO-KEY"
username = module.jfrog.username username = module.jfrog.username
@@ -109,3 +102,5 @@ provider "docker" {
} }
} }
``` ```
> Here `REPO_KEY` is the name of docker repository in Artifactory.

View File

@@ -13,10 +13,10 @@ A module that adds Jupyter Notebook in your Coder template.
![Jupyter Notebook](../.images/jupyter-notebook.png) ![Jupyter Notebook](../.images/jupyter-notebook.png)
```hcl ```tf
module "jupyter-notebook" { module "jupyter-notebook" {
source = "registry.coder.com/modules/jupyter-notebook/coder" source = "registry.coder.com/modules/jupyter-notebook/coder"
version = "1.0.0" version = "1.0.2"
agent_id = coder_agent.example.id agent_id = coder_agent.example.id
} }
``` ```

View File

@@ -13,10 +13,10 @@ A module that adds JupyterLab in your Coder template.
![JupyterLab](../.images/jupyterlab.png) ![JupyterLab](../.images/jupyterlab.png)
```hcl ```tf
module "jupyterlab" { module "jupyterlab" {
source = "registry.coder.com/modules/jupyterlab/coder" source = "registry.coder.com/modules/jupyterlab/coder"
version = "1.0.0" version = "1.0.2"
agent_id = coder_agent.example.id agent_id = coder_agent.example.id
} }
``` ```

45
lint.ts
View File

@@ -15,7 +15,37 @@ let badExit = false;
const error = (...data: any[]) => { const error = (...data: any[]) => {
console.error(...data); console.error(...data);
badExit = true; badExit = true;
} };
const verifyCodeBlocks = (
tokens: marked.Token[],
res = {
codeIsTF: false,
codeIsHCL: false,
}
) => {
for (const token of tokens) {
// Check in-depth.
if (token.type === "list") {
verifyCodeBlocks(token.items, res);
continue;
}
if (token.type === "list_item") {
verifyCodeBlocks(token.tokens, res);
continue;
}
if (token.type === "code") {
if (token.lang === "tf") {
res.codeIsTF = true;
}
if (token.lang === "hcl") {
res.codeIsHCL = true;
}
}
}
return res;
};
// Ensures that each README has the proper format. // Ensures that each README has the proper format.
// Exits with 0 if all is good! // Exits with 0 if all is good!
@@ -62,6 +92,7 @@ for (const dir of dirs) {
let h1 = false; let h1 = false;
let code = false; let code = false;
let paragraph = false; let paragraph = false;
let version = true;
for (const token of tokens) { for (const token of tokens) {
if (token.type === "heading" && token.depth === 1) { if (token.type === "heading" && token.depth === 1) {
@@ -77,6 +108,10 @@ for (const dir of dirs) {
} }
if (token.type === "code") { if (token.type === "code") {
code = true; code = true;
if (token.lang === "tf" && !token.text.includes("version")) {
version = false;
error(dir.name, "missing version in tf code block");
}
continue; continue;
} }
} }
@@ -89,6 +124,14 @@ for (const dir of dirs) {
if (!code) { if (!code) {
error(dir.name, "missing example code block after paragraph"); error(dir.name, "missing example code block after paragraph");
} }
const { codeIsTF, codeIsHCL } = verifyCodeBlocks(tokens);
if (!codeIsTF) {
error(dir.name, "missing example tf code block");
}
if (codeIsHCL) {
error(dir.name, "hcl code block should be tf");
}
} }
if (badExit) { if (badExit) {

4
new.sh
View File

@@ -1,6 +1,6 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# This scripts creates a new sample moduledir with requried files # This scripts creates a new sample moduledir with required files
# Run it like : ./new.sh my-module # Run it like : ./new.sh my-module
MODULE_NAME=$1 MODULE_NAME=$1
@@ -11,7 +11,7 @@ if [ -z "$MODULE_NAME" ]; then
exit 1 exit 1
fi fi
# Create module directory and exit if it alredy exists # Create module directory and exit if it already exists
if [ -d "$MODULE_NAME" ]; then if [ -d "$MODULE_NAME" ]; then
echo "Module with name $MODULE_NAME already exists" echo "Module with name $MODULE_NAME already exists"
echo "Please choose a different name" echo "Please choose a different name"

View File

@@ -2,17 +2,25 @@
"name": "modules", "name": "modules",
"scripts": { "scripts": {
"test": "bun test", "test": "bun test",
"fmt": "bun x prettier --plugin prettier-plugin-sh -w **/*.sh .sample/run.sh new.sh **/*.ts **/*.md *.md && terraform fmt **/*.tf .sample/main.tf", "fmt": "bun x prettier -w **/*.sh .sample/run.sh new.sh **/*.ts **/*.md *.md && terraform fmt **/*.tf .sample/main.tf",
"fmt:ci": "bun x prettier --plugin prettier-plugin-sh --check **/*.sh .sample/run.sh new.sh **/*.ts **/*.md *.md && terraform fmt -check **/*.tf .sample/main.tf", "fmt:ci": "bun x prettier --check **/*.sh .sample/run.sh new.sh **/*.ts **/*.md *.md && terraform fmt -check **/*.tf .sample/main.tf",
"lint": "bun run lint.ts" "lint": "bun run lint.ts",
"update-version": "./update-version.sh"
}, },
"devDependencies": { "devDependencies": {
"bun-types": "^1.0.18", "bun-types": "^1.0.18",
"gray-matter": "^4.0.3", "gray-matter": "^4.0.3",
"marked": "^11.1.0", "marked": "^11.1.0",
"prettier-plugin-sh": "^0.13.1" "prettier-plugin-sh": "^0.13.1",
"prettier-plugin-terraform-formatter": "^1.2.1"
}, },
"peerDependencies": { "peerDependencies": {
"typescript": "^5.3.3" "typescript": "^5.3.3"
},
"prettier": {
"plugins": [
"prettier-plugin-sh",
"prettier-plugin-terraform-formatter"
]
} }
} }

View File

@@ -11,10 +11,10 @@ tags: [helper]
Run a script on workspace start that allows developers to run custom commands to personalize their workspace. Run a script on workspace start that allows developers to run custom commands to personalize their workspace.
```hcl ```tf
module "personalize" { module "personalize" {
source = "registry.coder.com/modules/personalize/coder" source = "registry.coder.com/modules/personalize/coder"
version = "1.0.0" version = "1.0.2"
agent_id = coder_agent.example.id agent_id = coder_agent.example.id
} }
``` ```

View File

@@ -54,10 +54,10 @@ slackme npm run long-build
3. Restart your Coder deployment. Any Template can now import the Slack Me module, and `slackme` will be available on the `$PATH`: 3. Restart your Coder deployment. Any Template can now import the Slack Me module, and `slackme` will be available on the `$PATH`:
```hcl ```tf
module "slackme" { module "slackme" {
source = "registry.coder.com/modules/slackme/coder" source = "registry.coder.com/modules/slackme/coder"
version = "1.0.0" version = "1.0.2"
agent_id = coder_agent.example.id agent_id = coder_agent.example.id
auth_provider_id = "slack" auth_provider_id = "slack"
} }
@@ -70,10 +70,10 @@ slackme npm run long-build
- `$COMMAND` is replaced with the command the user executed. - `$COMMAND` is replaced with the command the user executed.
- `$DURATION` is replaced with a human-readable duration the command took to execute. - `$DURATION` is replaced with a human-readable duration the command took to execute.
```hcl ```tf
module "slackme" { module "slackme" {
source = "registry.coder.com/modules/slackme/coder" source = "registry.coder.com/modules/slackme/coder"
version = "1.0.0" version = "1.0.2"
agent_id = coder_agent.example.id agent_id = coder_agent.example.id
auth_provider_id = "slack" auth_provider_id = "slack"
slack_message = <<EOF slack_message = <<EOF

29
update-version.sh Executable file
View File

@@ -0,0 +1,29 @@
#!/usr/bin/env bash
# This script updates the version number in the README.md files of all modules
# to the latest tag in the repository. It is intended to be run from the root
# of the repository or by using the `bun update-version` command.
set -euo pipefail
current_tag=$(git describe --tags --abbrev=0)
previous_tag=$(git describe --tags --abbrev=0 $current_tag^)
mapfile -t changed_dirs < <(git diff --name-only "$previous_tag"..."$current_tag" -- ':!**/README.md' ':!**/*.test.ts' | xargs dirname | grep -v '^\.' | sort -u)
LATEST_TAG=$(git describe --abbrev=0 --tags | sed 's/^v//') || exit $?
for dir in "${changed_dirs[@]}"; do
if [[ -f "$dir/README.md" ]]; then
echo "Bumping version in $dir/README.md"
file="$dir/README.md"
tmpfile=$(mktemp /tmp/tempfile.XXXXXX)
awk -v tag="$LATEST_TAG" '{
if ($1 == "version" && $2 == "=") {
sub(/"[^"]*"/, "\"" tag "\"")
print
} else {
print
}
}' "$file" > "$tmpfile" && mv "$tmpfile" "$file"
fi
done

View File

@@ -3,6 +3,7 @@ display_name: Hashicorp Vault Integration (GitHub)
description: Authenticates with Vault using GitHub description: Authenticates with Vault using GitHub
icon: ../.icons/vault.svg icon: ../.icons/vault.svg
maintainer_github: coder maintainer_github: coder
partner_github: hashicorp
verified: true verified: true
tags: [helper, integration, vault, github] tags: [helper, integration, vault, github]
--- ---
@@ -11,10 +12,10 @@ tags: [helper, integration, vault, github]
This module lets you authenticate with [Hashicorp Vault](https://www.vaultproject.io/) in your Coder workspaces using [external auth](https://coder.com/docs/v2/latest/admin/external-auth) for GitHub. This module lets you authenticate with [Hashicorp Vault](https://www.vaultproject.io/) in your Coder workspaces using [external auth](https://coder.com/docs/v2/latest/admin/external-auth) for GitHub.
```hcl ```tf
module "vault" { module "vault" {
source = "registry.coder.com/modules/vault-github/coder" source = "registry.coder.com/modules/vault-github/coder"
version = "1.0.0" version = "1.0.3"
agent_id = coder_agent.example.id agent_id = coder_agent.example.id
vault_addr = "https://vault.example.com" vault_addr = "https://vault.example.com"
} }
@@ -23,13 +24,13 @@ module "vault" {
Then you can use the Vault CLI in your workspaces to fetch secrets from Vault: Then you can use the Vault CLI in your workspaces to fetch secrets from Vault:
```shell ```shell
vault kv get -mount=secret my-secret vault kv get -mount=coder my-secret
``` ```
or using the Vault API: or using the Vault API:
```shell ```shell
curl -H "X-Vault-Token: ${VAULT_TOKEN}" -X GET "${VAULT_ADDR}/v1/secret/data/my-secret" curl -H "X-Vault-Token: ${VAULT_TOKEN}" -X GET "${VAULT_ADDR}/v1/coder/data/my-secret"
``` ```
![Vault login](../.images/vault-login.png) ![Vault login](../.images/vault-login.png)
@@ -42,10 +43,10 @@ To configure the Vault module, you must set up a Vault GitHub auth method. See t
### Configure Vault integration with a different Coder GitHub external auth ID (i.e., not the default `github`) ### Configure Vault integration with a different Coder GitHub external auth ID (i.e., not the default `github`)
```hcl ```tf
module "vault" { module "vault" {
source = "registry.coder.com/modules/vault-github/coder" source = "registry.coder.com/modules/vault-github/coder"
version = "1.0.0" version = "1.0.3"
agent_id = coder_agent.example.id agent_id = coder_agent.example.id
vault_addr = "https://vault.example.com" vault_addr = "https://vault.example.com"
coder_github_auth_id = "my-github-auth-id" coder_github_auth_id = "my-github-auth-id"
@@ -54,10 +55,10 @@ module "vault" {
### Configure Vault integration with a different Coder GitHub external auth ID and a different Vault GitHub auth path ### Configure Vault integration with a different Coder GitHub external auth ID and a different Vault GitHub auth path
```hcl ```tf
module "vault" { module "vault" {
source = "registry.coder.com/modules/vault-github/coder" source = "registry.coder.com/modules/vault-github/coder"
version = "1.0.0" version = "1.0.3"
agent_id = coder_agent.example.id agent_id = coder_agent.example.id
vault_addr = "https://vault.example.com" vault_addr = "https://vault.example.com"
coder_github_auth_id = "my-github-auth-id" coder_github_auth_id = "my-github-auth-id"
@@ -67,10 +68,10 @@ module "vault" {
### Configure Vault integration and install a specific version of the Vault CLI ### Configure Vault integration and install a specific version of the Vault CLI
```hcl ```tf
module "vault" { module "vault" {
source = "registry.coder.com/modules/vault-github/coder" source = "registry.coder.com/modules/vault-github/coder"
version = "1.0.0" version = "1.0.3"
agent_id = coder_agent.example.id agent_id = coder_agent.example.id
vault_addr = "https://vault.example.com" vault_addr = "https://vault.example.com"
vault_cli_version = "1.15.0" vault_cli_version = "1.15.0"

11
vault-github/main.test.ts Normal file
View File

@@ -0,0 +1,11 @@
import { describe } from "bun:test";
import { runTerraformInit, testRequiredVariables } from "../test";
describe("vault-token", async () => {
await runTerraformInit(import.meta.dir);
testRequiredVariables(import.meta.dir, {
agent_id: "foo",
vault_addr: "foo",
});
});

View File

@@ -49,7 +49,6 @@ resource "coder_script" "vault" {
display_name = "Vault (GitHub)" display_name = "Vault (GitHub)"
icon = "/icon/vault.svg" icon = "/icon/vault.svg"
script = templatefile("${path.module}/run.sh", { script = templatefile("${path.module}/run.sh", {
VAULT_ADDR : var.vault_addr,
AUTH_PATH : var.vault_github_auth_path, AUTH_PATH : var.vault_github_auth_path,
GITHUB_EXTERNAL_AUTH_ID : data.coder_external_auth.github.id, GITHUB_EXTERNAL_AUTH_ID : data.coder_external_auth.github.id,
INSTALL_VERSION : var.vault_cli_version, INSTALL_VERSION : var.vault_cli_version,

View File

@@ -1,8 +1,7 @@
#!/usr/bin/env sh #!/usr/bin/env bash
# Convert all templated variables to shell variables # Convert all templated variables to shell variables
INSTALL_VERSION=${INSTALL_VERSION} INSTALL_VERSION=${INSTALL_VERSION}
VAULT_ADDR=${VAULT_ADDR}
GITHUB_EXTERNAL_AUTH_ID=${GITHUB_EXTERNAL_AUTH_ID} GITHUB_EXTERNAL_AUTH_ID=${GITHUB_EXTERNAL_AUTH_ID}
AUTH_PATH=${AUTH_PATH} AUTH_PATH=${AUTH_PATH}
@@ -21,7 +20,7 @@ fetch() {
fi fi
} }
unzip() { unzip_safe() {
if command -v unzip > /dev/null 2>&1; then if command -v unzip > /dev/null 2>&1; then
command unzip "$@" command unzip "$@"
elif command -v busybox > /dev/null 2>&1; then elif command -v busybox > /dev/null 2>&1; then
@@ -32,57 +31,68 @@ unzip() {
fi fi
} }
# Fetch the latest version of Vault if INSTALL_VERSION is 'latest' install() {
if [ "$${INSTALL_VERSION}" = "latest" ]; then # Fetch the latest version of Vault if INSTALL_VERSION is 'latest'
LATEST_VERSION=$(curl -s https://releases.hashicorp.com/vault/ | grep -oP 'vault/\K[0-9]+\.[0-9]+\.[0-9]+' | sort -V | tail -n 1) if [ "$${INSTALL_VERSION}" = "latest" ]; then
LATEST_VERSION=$(curl -s https://releases.hashicorp.com/vault/ | grep -v '-rc' | grep -oP 'vault/\K[0-9]+\.[0-9]+\.[0-9]+' | sort -V | tail -n 1)
printf "Latest version of Vault is %s.\n\n" "$${LATEST_VERSION}" printf "Latest version of Vault is %s.\n\n" "$${LATEST_VERSION}"
if [ -z "$${LATEST_VERSION}" ]; then if [ -z "$${LATEST_VERSION}" ]; then
printf "Failed to determine the latest Vault version.\n" printf "Failed to determine the latest Vault version.\n"
exit 1 return 1
fi
INSTALL_VERSION=$${LATEST_VERSION}
fi fi
VERSION=$${LATEST_VERSION}
fi
# Check if the vault CLI is installed and has the correct version # Check if the vault CLI is installed and has the correct version
installation_needed=1 installation_needed=1
if command -v vault > /dev/null 2>&1; then if command -v vault > /dev/null 2>&1; then
CURRENT_VERSION=$(vault version | grep -oE '[0-9]+\.[0-9]+\.[0-9]+') CURRENT_VERSION=$(vault version | grep -oE '[0-9]+\.[0-9]+\.[0-9]+')
if [ "$${CURRENT_VERSION}" = "$${INSTALL_VERSION}" ]; then if [ "$${CURRENT_VERSION}" = "$${INSTALL_VERSION}" ]; then
printf "Vault version %s is already installed and up-to-date.\n\n" "$${CURRENT_VERSION}" printf "Vault version %s is already installed and up-to-date.\n\n" "$${CURRENT_VERSION}"
installation_needed=0 installation_needed=0
fi fi
fi fi
if [ $${installation_needed} -eq 1 ]; then if [ $${installation_needed} -eq 1 ]; then
# Download and install Vault # Download and install Vault
if [ -z "$${CURRENT_VERSION}" ]; then if [ -z "$${CURRENT_VERSION}" ]; then
printf "Installing Vault CLI ...\n\n" printf "Installing Vault CLI ...\n\n"
else else
printf "Upgrading Vault CLI from version %s to %s ...\n\n" "$${CURRENT_VERSION}" "$${VERSION}" printf "Upgrading Vault CLI from version %s to %s ...\n\n" "$${CURRENT_VERSION}" "${INSTALL_VERSION}"
fi fi
fetch vault.zip "https://releases.hashicorp.com/vault/$${VERSION}/vault_$${VERSION}_linux_amd64.zip" fetch vault.zip "https://releases.hashicorp.com/vault/$${INSTALL_VERSION}/vault_$${INSTALL_VERSION}_linux_amd64.zip"
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
printf "Failed to download Vault.\n" printf "Failed to download Vault.\n"
exit 1 return 1
fi fi
unzip vault.zip if ! unzip_safe vault.zip; then
if [ $? -ne 0 ]; then
printf "Failed to unzip Vault.\n" printf "Failed to unzip Vault.\n"
exit 1 return 1
fi fi
rm vault.zip rm vault.zip
if sudo mv vault /usr/local/bin/vault 2> /dev/null; then if sudo mv vault /usr/local/bin/vault 2> /dev/null; then
printf "Vault installed successfully!\n\n" printf "Vault installed successfully!\n\n"
else else
mkdir -p ~/.local/bin mkdir -p ~/.local/bin
mv vault ~/.local/bin/vault if ! mv vault ~/.local/bin/vault; then
if [ ! -f ~/.local/bin/vault ]; then
printf "Failed to move Vault to local bin.\n" printf "Failed to move Vault to local bin.\n"
exit 1 return 1
fi fi
printf "Please add ~/.local/bin to your PATH to use vault CLI.\n" printf "Please add ~/.local/bin to your PATH to use vault CLI.\n"
fi fi
fi
return 0
}
TMP=$(mktemp -d)
if ! (
cd "$TMP"
install
); then
echo "Failed to install Vault CLI."
exit 1
fi fi
rm -rf "$TMP"
# Authenticate with Vault # Authenticate with Vault
printf "🔑 Authenticating with Vault ...\n\n" printf "🔑 Authenticating with Vault ...\n\n"
@@ -92,8 +102,6 @@ if [ $? -ne 0 ]; then
exit 1 exit 1
fi fi
export VAULT_ADDR="$${VAULT_ADDR}"
# Login to vault using the GitHub token # Login to vault using the GitHub token
printf "🔑 Logging in to Vault ...\n\n" printf "🔑 Logging in to Vault ...\n\n"
vault login -no-print -method=github -path=/$${AUTH_PATH} token="$${GITHUB_TOKEN}" vault login -no-print -method=github -path=/$${AUTH_PATH} token="$${GITHUB_TOKEN}"

83
vault-token/README.md Normal file
View File

@@ -0,0 +1,83 @@
---
display_name: Hashicorp Vault Integration (Token)
description: Authenticates with Vault using Token
icon: ../.icons/vault.svg
maintainer_github: coder
partner_github: hashicorp
verified: true
tags: [helper, integration, vault, token]
---
# Hashicorp Vault Integration (Token)
This module lets you authenticate with [Hashicorp Vault](https://www.vaultproject.io/) in your Coder workspaces using a [Vault token](https://developer.hashicorp.com/vault/docs/auth/token).
```tf
variable "vault_token" {
type = string
description = "The Vault token to use for authentication."
sensitive = true
}
module "vault" {
source = "registry.coder.com/modules/vault-token/coder"
version = "1.0.3"
agent_id = coder_agent.example.id
vault_token = var.token
vault_addr = "https://vault.example.com"
}
```
Then you can use the Vault CLI in your workspaces to fetch secrets from Vault:
```shell
vault kv get -namespace=coder -mount=secrets coder
```
or using the Vault API:
```shell
curl -H "X-Vault-Token: ${VAULT_TOKEN}" -X GET "${VAULT_ADDR}/v1/coder/secrets/data/coder"
```
## Configuration
To configure the Vault module, you must create a Vault token with the the required permissions and configure the module with the token and Vault address.
1. Create a vault policy with read access to the secret mount you need your developers to access.
```shell
vault policy write read-coder-secrets - <<EOF
path "coder/data/*" {
capabilities = ["read"]
}
path "coder/metadata/*" {
capabilities = ["read"]
}
EOF
```
2. Create a token using this policy.
```shell
vault token create -policy="read-coder-secrets"
```
3. Copy the generated token and use in your template.
## Examples
### Configure Vault integration and install a specific version of the Vault CLI
```tf
variable "vault_token" {
type = string
description = "The Vault token to use for authentication."
sensitive = true
}
module "vault" {
source = "registry.coder.com/modules/vault-token/coder"
version = "1.0.3"
agent_id = coder_agent.example.id
vault_addr = "https://vault.example.com"
vault_token = var.token
vault_cli_version = "1.15.0"
}
```

12
vault-token/main.test.ts Normal file
View File

@@ -0,0 +1,12 @@
import { describe } from "bun:test";
import { runTerraformInit, testRequiredVariables } from "../test";
describe("vault-token", async () => {
await runTerraformInit(import.meta.dir);
testRequiredVariables(import.meta.dir, {
agent_id: "foo",
vault_addr: "foo",
vault_token: "foo",
});
});

62
vault-token/main.tf Normal file
View File

@@ -0,0 +1,62 @@
terraform {
required_version = ">= 1.0"
required_providers {
coder = {
source = "coder/coder"
version = ">= 0.12.4"
}
}
}
# Add required variables for your modules and remove any unneeded variables
variable "agent_id" {
type = string
description = "The ID of a Coder agent."
}
variable "vault_addr" {
type = string
description = "The address of the Vault server."
}
variable "vault_token" {
type = string
description = "The Vault token to use for authentication."
sensitive = true
}
variable "vault_cli_version" {
type = string
description = "The version of Vault to install."
default = "latest"
validation {
condition = can(regex("^(latest|[0-9]+\\.[0-9]+\\.[0-9]+)$", var.vault_cli_version))
error_message = "Vault version must be in the format 0.0.0 or latest"
}
}
data "coder_workspace" "me" {}
resource "coder_script" "vault" {
agent_id = var.agent_id
display_name = "Vault (Token)"
icon = "/icon/vault.svg"
script = templatefile("${path.module}/run.sh", {
INSTALL_VERSION : var.vault_cli_version,
})
run_on_start = true
start_blocks_login = true
}
resource "coder_env" "vault_addr" {
agent_id = var.agent_id
name = "VAULT_ADDR"
value = var.vault_addr
}
resource "coder_env" "vault_token" {
agent_id = var.agent_id
name = "VAULT_TOKEN"
value = var.vault_token
}

93
vault-token/run.sh Normal file
View File

@@ -0,0 +1,93 @@
#!/usr/bin/env bash
# Convert all templated variables to shell variables
INSTALL_VERSION=${INSTALL_VERSION}
fetch() {
dest="$1"
url="$2"
if command -v curl > /dev/null 2>&1; then
curl -sSL --fail "$${url}" -o "$${dest}"
elif command -v wget > /dev/null 2>&1; then
wget -O "$${dest}" "$${url}"
elif command -v busybox > /dev/null 2>&1; then
busybox wget -O "$${dest}" "$${url}"
else
printf "curl, wget, or busybox is not installed. Please install curl or wget in your image.\n"
return 1
fi
}
unzip_safe() {
if command -v unzip > /dev/null 2>&1; then
command unzip "$@"
elif command -v busybox > /dev/null 2>&1; then
busybox unzip "$@"
else
printf "unzip or busybox is not installed. Please install unzip in your image.\n"
return 1
fi
}
install() {
# Fetch the latest version of Vault if INSTALL_VERSION is 'latest'
if [ "$${INSTALL_VERSION}" = "latest" ]; then
LATEST_VERSION=$(curl -s https://releases.hashicorp.com/vault/ | grep -v '-rc' | grep -oP 'vault/\K[0-9]+\.[0-9]+\.[0-9]+' | sort -V | tail -n 1)
printf "Latest version of Vault is %s.\n\n" "$${LATEST_VERSION}"
if [ -z "$${LATEST_VERSION}" ]; then
printf "Failed to determine the latest Vault version.\n"
return 1
fi
INSTALL_VERSION=$${LATEST_VERSION}
fi
# Check if the vault CLI is installed and has the correct version
installation_needed=1
if command -v vault > /dev/null 2>&1; then
CURRENT_VERSION=$(vault version | grep -oE '[0-9]+\.[0-9]+\.[0-9]+')
if [ "$${CURRENT_VERSION}" = "$${INSTALL_VERSION}" ]; then
printf "Vault version %s is already installed and up-to-date.\n\n" "$${CURRENT_VERSION}"
installation_needed=0
fi
fi
if [ $${installation_needed} -eq 1 ]; then
# Download and install Vault
if [ -z "$${CURRENT_VERSION}" ]; then
printf "Installing Vault CLI ...\n\n"
else
printf "Upgrading Vault CLI from version %s to %s ...\n\n" "$${CURRENT_VERSION}" "${INSTALL_VERSION}"
fi
fetch vault.zip "https://releases.hashicorp.com/vault/$${INSTALL_VERSION}/vault_$${INSTALL_VERSION}_linux_amd64.zip"
if [ $? -ne 0 ]; then
printf "Failed to download Vault.\n"
return 1
fi
if ! unzip_safe vault.zip; then
printf "Failed to unzip Vault.\n"
return 1
fi
rm vault.zip
if sudo mv vault /usr/local/bin/vault 2> /dev/null; then
printf "Vault installed successfully!\n\n"
else
mkdir -p ~/.local/bin
if ! mv vault ~/.local/bin/vault; then
printf "Failed to move Vault to local bin.\n"
return 1
fi
printf "Please add ~/.local/bin to your PATH to use vault CLI.\n"
fi
fi
return 0
}
TMP=$(mktemp -d)
if ! (
cd "$TMP"
install
); then
echo "Failed to install Vault CLI."
exit 1
fi
rm -rf "$TMP"

View File

@@ -13,10 +13,10 @@ Add a button to open any workspace with a single click.
Uses the [Coder Remote VS Code Extension](https://github.com/coder/vscode-coder). Uses the [Coder Remote VS Code Extension](https://github.com/coder/vscode-coder).
```hcl ```tf
module "vscode" { module "vscode" {
source = "registry.coder.com/modules/vscode-desktop/coder" source = "registry.coder.com/modules/vscode-desktop/coder"
version = "1.0.0" version = "1.0.2"
agent_id = coder_agent.example.id agent_id = coder_agent.example.id
} }
``` ```
@@ -25,10 +25,10 @@ module "vscode" {
### Open in a specific directory ### Open in a specific directory
```hcl ```tf
module "vscode" { module "vscode" {
source = "registry.coder.com/modules/vscode-desktop/coder" source = "registry.coder.com/modules/vscode-desktop/coder"
version = "1.0.0" version = "1.0.2"
agent_id = coder_agent.example.id agent_id = coder_agent.example.id
folder = "/home/coder/project" folder = "/home/coder/project"
} }

View File

@@ -11,10 +11,10 @@ tags: [helper, ide, vscode, web]
Automatically install [Visual Studio Code Server](https://code.visualstudio.com/docs/remote/vscode-server) in a workspace using the [VS Code CLI](https://code.visualstudio.com/docs/editor/command-line) and create an app to access it via the dashboard. Automatically install [Visual Studio Code Server](https://code.visualstudio.com/docs/remote/vscode-server) in a workspace using the [VS Code CLI](https://code.visualstudio.com/docs/editor/command-line) and create an app to access it via the dashboard.
```hcl ```tf
module "vscode-web" { module "vscode-web" {
source = "registry.coder.com/modules/vscode-web/coder" source = "registry.coder.com/modules/vscode-web/coder"
version = "1.0.0" version = "1.0.3"
agent_id = coder_agent.example.id agent_id = coder_agent.example.id
accept_license = true accept_license = true
} }
@@ -26,10 +26,10 @@ module "vscode-web" {
### Install VS Code Web to a custom folder ### Install VS Code Web to a custom folder
```hcl ```tf
module "vscode-web" { module "vscode-web" {
source = "registry.coder.com/modules/vscode-web/coder" source = "registry.coder.com/modules/vscode-web/coder"
version = "1.0.0" version = "1.0.3"
agent_id = coder_agent.example.id agent_id = coder_agent.example.id
install_dir = "/home/coder/.vscode-web" install_dir = "/home/coder/.vscode-web"
folder = "/home/coder" folder = "/home/coder"

View File

@@ -20,6 +20,18 @@ variable "port" {
default = 13338 default = 13338
} }
variable "display_name" {
type = string
description = "The display name for the VS Code Web application."
default = "VS Code Web"
}
variable "slug" {
type = string
description = "The slug for the VS Code Web application."
default = "vscode-web"
}
variable "folder" { variable "folder" {
type = string type = string
description = "The folder to open in vscode-web." description = "The folder to open in vscode-web."
@@ -71,8 +83,8 @@ resource "coder_script" "vscode-web" {
resource "coder_app" "vscode-web" { resource "coder_app" "vscode-web" {
agent_id = var.agent_id agent_id = var.agent_id
slug = "vscode-web" slug = var.slug
display_name = "VS Code Web" display_name = var.display_name
url = var.folder == "" ? "http://localhost:${var.port}" : "http://localhost:${var.port}?folder=${var.folder}" url = var.folder == "" ? "http://localhost:${var.port}" : "http://localhost:${var.port}?folder=${var.folder}"
icon = "/icon/code.svg" icon = "/icon/code.svg"
subdomain = true subdomain = true