Compare commits

..

25 Commits

Author SHA1 Message Date
Muhammad Atif Ali
8e254a3bb9 docs: elaborate instructions for setting up hcp vault module (#163)
Co-authored-by: Mathias Fredriksson <mafredri@gmail.com>
2024-02-19 13:44:07 +04:00
Muhammad Atif Ali
1ab53139b3 ci: fix ci permissions (#166) 2024-02-18 23:45:33 +05:00
Muhammad Atif Ali
147bea9782 bump version to v1.0.4 (#160) 2024-02-16 18:50:30 +03:00
Victor Urvantsev
8d8910c52a feat(jfrog): add option to customize server id for JFrog CLI (#158)
Co-authored-by: Victor Urvantsev <victoru@jfrog.com>
2024-02-16 13:16:14 +03:00
Florian Gareis
c00b7536cb Add slug to code server (#161) 2024-02-16 12:54:05 +03:00
Muhammad Atif Ali
d66d7e994e ci: set base branch for docs update PR (#155) 2024-02-14 20:11:13 +03:00
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
57 changed files with 1053 additions and 510 deletions

View File

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

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

@@ -0,0 +1,42 @@
name: Update README on Tag
on:
workflow_dispatch:
push:
tags:
- 'v*'
jobs:
update-readme:
permissions:
contents: write
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'
base: 'main'
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'

Binary file not shown.

After

Width:  |  Height:  |  Size: 174 KiB

View File

@@ -11,10 +11,10 @@ tags: [helper]
<!-- Describes what this module does -->
```hcl
```tf
module "MODULE_NAME" {
source = "registry.coder.com/modules/MODULE_NAME/coder"
version = "1.0.0"
source = "registry.coder.com/modules/MODULE_NAME/coder"
version = "1.0.2"
}
```
@@ -26,11 +26,11 @@ module "MODULE_NAME" {
Install the Dracula theme from [OpenVSX](https://open-vsx.org/):
```hcl
```tf
module "MODULE_NAME" {
source = "registry.coder.com/modules/MODULE_NAME/coder"
version = "1.0.0"
agent_id = coder_agent.example.id
source = "registry.coder.com/modules/MODULE_NAME/coder"
version = "1.0.2"
agent_id = coder_agent.example.id
extensions = [
"dracula-theme.theme-dracula"
]
@@ -43,13 +43,13 @@ 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:
```hcl
```tf
module "MODULE_NAME" {
source = "registry.coder.com/modules/MODULE_NAME/coder"
version = "1.0.0"
agent_id = coder_agent.example.id
source = "registry.coder.com/modules/MODULE_NAME/coder"
version = "1.0.2"
agent_id = coder_agent.example.id
extensions = [ "dracula-theme.theme-dracula" ]
settings = {
settings = {
"workbench.colorTheme" = "Dracula"
}
}
@@ -59,11 +59,11 @@ module "MODULE_NAME" {
Run code-server in the background, don't fetch it from GitHub:
```hcl
```tf
module "MODULE_NAME" {
source = "registry.coder.com/modules/MODULE_NAME/coder"
version = "1.0.0"
source = "registry.coder.com/modules/MODULE_NAME/coder"
version = "1.0.2"
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:
```shell
./new.sh MOUDLE_NAME
./new.sh MODULE_NAME
```
## Testing a Module
@@ -19,7 +19,7 @@ $ bun test -t '<module>'
You can test a module locally by updating the source as follows
```hcl
```tf
module "example" {
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.
```hcl
```tf
module "code-server" {
source = "registry.coder.com/modules/code-server/coder"
version = "1.0.0"
source = "registry.coder.com/modules/code-server/coder"
version = "1.0.2"
agent_id = coder_agent.main.id
}
```

View File

@@ -14,10 +14,10 @@ the region closest to them.
Customize the preselected parameter value:
```hcl
```tf
module "aws-region" {
source = "registry.coder.com/modules/aws-region/coder"
version = "1.0.0"
source = "registry.coder.com/modules/aws-region/coder"
version = "1.0.2"
default = "us-east-1"
}
@@ -34,16 +34,18 @@ provider "aws" {
Change the display name and icon for a region using the corresponding maps:
```hcl
```tf
module "aws-region" {
source = "registry.coder.com/modules/aws-region/coder"
version = "1.0.0"
source = "registry.coder.com/modules/aws-region/coder"
version = "1.0.2"
default = "ap-south-1"
custom_names = {
"ap-south-1": "Awesome Mumbai!"
"ap-south-1" : "Awesome Mumbai!"
}
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:
```hcl
```tf
module "aws-region" {
source = "registry.coder.com/modules/aws-region/coder"
version = "1.0.0"
exclude = [ "ap-northeast-2", "ap-northeast-3" ]
source = "registry.coder.com/modules/aws-region/coder"
version = "1.0.2"
exclude = ["ap-northeast-2", "ap-northeast-3"]
}
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.
```hcl
```tf
module "azure_region" {
source = "registry.coder.com/modules/azure-region/coder"
version = "1.0.0"
source = "registry.coder.com/modules/azure-region/coder"
version = "1.0.2"
default = "eastus"
}
@@ -31,15 +31,15 @@ resource "azurem_resource_group" "example" {
Change the display name and icon for a region using the corresponding maps:
```hcl
```tf
module "azure-region" {
source = "registry.coder.com/modules/azure-region/coder"
version = "1.0.0"
source = "registry.coder.com/modules/azure-region/coder"
version = "1.0.2"
custom_names = {
"australia": "Go Australia!"
"australia" : "Go Australia!"
}
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:
```hcl
```tf
module "azure-region" {
source = "registry.coder.com/modules/azure-region/coder"
version = "1.0.0"
source = "registry.coder.com/modules/azure-region/coder"
version = "1.0.2"
exclude = [
"australia",
"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.
```hcl
```tf
module "code-server" {
source = "registry.coder.com/modules/code-server/coder"
version = "1.0.0"
source = "registry.coder.com/modules/code-server/coder"
version = "1.0.2"
agent_id = coder_agent.example.id
}
```
@@ -25,10 +25,10 @@ module "code-server" {
### Pin Versions
```hcl
```tf
module "code-server" {
source = "registry.coder.com/modules/code-server/coder"
version = "1.0.0"
version = "1.0.2"
agent_id = coder_agent.example.id
install_version = "4.8.3"
}
@@ -38,10 +38,10 @@ module "code-server" {
Install the Dracula theme from [OpenVSX](https://open-vsx.org/):
```hcl
```tf
module "code-server" {
source = "registry.coder.com/modules/code-server/coder"
version = "1.0.0"
source = "registry.coder.com/modules/code-server/coder"
version = "1.0.2"
agent_id = coder_agent.example.id
extensions = [
"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:
```hcl
module "settings" {
source = "registry.coder.com/modules/code-server/coder"
version = "1.0.0"
agent_id = coder_agent.example.id
extensions = [ "dracula-theme.theme-dracula" ]
```tf
module "code-server" {
source = "registry.coder.com/modules/code-server/coder"
version = "1.0.2"
agent_id = coder_agent.example.id
extensions = ["dracula-theme.theme-dracula"]
settings = {
"workbench.colorTheme" = "Dracula"
}
@@ -71,12 +71,12 @@ module "settings" {
Just run code-server in the background, don't fetch it from GitHub:
```hcl
module "settings" {
source = "registry.coder.com/modules/code-server/coder"
version = "1.0.0"
agent_id = coder_agent.example.id
extensions = [ "dracula-theme.theme-dracula", "ms-azuretools.vscode-docker" ]
```tf
module "code-server" {
source = "registry.coder.com/modules/code-server/coder"
version = "1.0.2"
agent_id = coder_agent.example.id
extensions = ["dracula-theme.theme-dracula", "ms-azuretools.vscode-docker"]
}
```
@@ -84,11 +84,11 @@ module "settings" {
Just run code-server in the background, don't fetch it from GitHub:
```hcl
module "settings" {
source = "registry.coder.com/modules/code-server/coder"
version = "1.0.0"
```tf
module "code-server" {
source = "registry.coder.com/modules/code-server/coder"
version = "1.0.2"
agent_id = coder_agent.example.id
offline = true
offline = true
}
```

View File

@@ -32,6 +32,12 @@ variable "display_name" {
default = "code-server"
}
variable "slug" {
type = string
description = "The slug for the code-server application."
default = "code-server"
}
variable "settings" {
type = map(string)
description = "A map of settings to apply to code-server."
@@ -89,7 +95,7 @@ resource "coder_script" "code-server" {
resource "coder_app" "code-server" {
agent_id = var.agent_id
slug = "code-server"
slug = var.slug
display_name = var.display_name
url = "http://localhost:${var.port}/${var.folder != "" ? "?folder=${urlencode(var.folder)}" : ""}"
icon = "/icon/code.svg"

View File

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

View File

@@ -10,20 +10,20 @@ tags: [helper, parameter, instances, exoscale]
# exoscale-instance-type
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:
```hcl
```tf
module "exoscale-instance-type" {
source = "registry.coder.com/modules/exoscale-instance-type/coder"
version = "1.0.0"
source = "registry.coder.com/modules/exoscale-instance-type/coder"
version = "1.0.2"
default = "standard.medium"
}
resource "exoscale_compute_instance" "instance" {
type = module.exoscale-instance-type.value
...
type = module.exoscale-instance-type.value
# ...
}
resource "coder_metadata" "workspace_info" {
@@ -42,22 +42,24 @@ resource "coder_metadata" "workspace_info" {
Change the display name a type using the corresponding maps:
```hcl
```tf
module "exoscale-instance-type" {
source = "registry.coder.com/modules/exoscale-instance-type/coder"
version = "1.0.0"
source = "registry.coder.com/modules/exoscale-instance-type/coder"
version = "1.0.2"
default = "standard.medium"
custom_names = {
"standard.medium": "Mittlere Instanz" # German translation
"standard.medium" : "Mittlere Instanz" # German translation
}
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" {
type = module.exoscale-instance-type.value
...
type = module.exoscale-instance-type.value
# ...
}
resource "coder_metadata" "workspace_info" {
@@ -70,17 +72,17 @@ resource "coder_metadata" "workspace_info" {
![Exoscale instance types Custom](../.images/exoscale-instance-custom.png)
### Use category and exlude type
### Use category and exclude type
Show only gpu1 types
```hcl
```tf
module "exoscale-instance-type" {
source = "registry.coder.com/modules/exoscale-instance-type/coder"
version = "1.0.0"
version = "1.0.2"
default = "gpu.large"
type_category = ["gpu"]
exclude = [
exclude = [
"gpu2.small",
"gpu2.medium",
"gpu2.large",
@@ -93,8 +95,8 @@ module "exoscale-instance-type" {
}
resource "exoscale_compute_instance" "instance" {
type = module.exoscale-instance-type.value
...
type = module.exoscale-instance-type.value
# ...
}
resource "coder_metadata" "workspace_info" {

View File

@@ -14,10 +14,10 @@ the zone closest to them.
Customize the preselected parameter value:
```hcl
```tf
module "exoscale-zone" {
source = "registry.coder.com/modules/exoscale-zone/coder"
version = "1.0.0"
source = "registry.coder.com/modules/exoscale-zone/coder"
version = "1.0.2"
default = "ch-dk-2"
}
@@ -28,8 +28,8 @@ data "exoscale_compute_template" "my_template" {
}
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:
```hcl
```tf
module "exoscale-zone" {
source = "registry.coder.com/modules/exoscale-zone/coder"
version = "1.0.0"
source = "registry.coder.com/modules/exoscale-zone/coder"
version = "1.0.2"
default = "at-vie-1"
custom_names = {
"at-vie-1": "Home Vienna"
"at-vie-1" : "Home Vienna"
}
custom_icons = {
"at-vie-1": "/emojis/1f3e0.png"
"at-vie-1" : "/emojis/1f3e0.png"
}
}
@@ -60,8 +62,8 @@ data "exoscale_compute_template" "my_template" {
}
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
```hcl
```tf
module "exoscale-zone" {
source = "registry.coder.com/modules/exoscale-zone/coder"
version = "1.0.0"
exclude = [ "ch-gva-2", "ch-dk-2" ]
source = "registry.coder.com/modules/exoscale-zone/coder"
version = "1.0.2"
exclude = ["ch-gva-2", "ch-dk-2"]
}
data "exoscale_compute_template" "my_template" {
@@ -84,8 +86,8 @@ data "exoscale_compute_template" "my_template" {
}
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.
```hcl
```tf
module "filebrowser" {
source = "registry.coder.com/modules/filebrowser/coder"
version = "1.0.0"
source = "registry.coder.com/modules/filebrowser/coder"
version = "1.0.3"
agent_id = coder_agent.example.id
}
```
@@ -25,22 +25,22 @@ module "filebrowser" {
### Serve a specific directory
```hcl
```tf
module "filebrowser" {
source = "registry.coder.com/modules/filebrowser/coder"
version = "1.0.0"
source = "registry.coder.com/modules/filebrowser/coder"
version = "1.0.3"
agent_id = coder_agent.example.id
folder = "/home/coder/project"
folder = "/home/coder/project"
}
```
### Specify location of `filebrowser.db`
```hcl
```tf
module "filebrowser" {
source = "registry.coder.com/modules/filebrowser/coder"
version = "1.0.0"
agent_id = coder_agent.example.id
source = "registry.coder.com/modules/filebrowser/coder"
version = "1.0.3"
agent_id = coder_agent.example.id
database_path = ".config/filebrowser.db"
}
```

View File

@@ -33,7 +33,7 @@ describe("filebrowser", async () => {
expect(output.stdout).toEqual([
"\u001b[0;1mInstalling filebrowser ",
"",
"🥳 Installation comlete! ",
"🥳 Installation complete! ",
"",
"👷 Starting filebrowser in background... ",
"",
@@ -55,7 +55,7 @@ describe("filebrowser", async () => {
expect(output.stdout).toEqual([
"\u001b[0;1mInstalling filebrowser ",
"",
"🥳 Installation comlete! ",
"🥳 Installation complete! ",
"",
"👷 Starting filebrowser in background... ",
"",
@@ -77,7 +77,7 @@ describe("filebrowser", async () => {
expect(output.stdout).toEqual([
"\u001B[0;1mInstalling filebrowser ",
"",
"🥳 Installation comlete! ",
"🥳 Installation complete! ",
"",
"👷 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
printf "🥳 Installation comlete! \n\n"
printf "🥳 Installation complete! \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.
```hcl
```tf
module "fly-region" {
source = "registry.coder.com/modules/fly-region/coder"
version = "1.0.0"
source = "registry.coder.com/modules/fly-region/coder"
version = "1.0.2"
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.
```hcl
```tf
module "fly-region" {
source = "registry.coder.com/modules/fly-region/coder"
version = "1.0.0"
source = "registry.coder.com/modules/fly-region/coder"
version = "1.0.2"
default = "ams"
regions = ["ams", "arn", "atl"]
}
@@ -44,16 +44,18 @@ module "fly-region" {
Set custom icons and names with their respective maps.
```hcl
```tf
module "fly-region" {
source = "registry.coder.com/modules/fly-region/coder"
version = "1.0.0"
source = "registry.coder.com/modules/fly-region/coder"
version = "1.0.2"
default = "ams"
custom_icons = {
"ams" = "/emojis/1f90e.png"
"ams" = "/emojis/1f90e.png"
}
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.
```hcl
```tf
module "gcp_region" {
source = "registry.coder.com/modules/gcp-region/coder"
version = "1.0.0"
version = "1.0.2"
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`.
```hcl
```tf
module "gcp_region" {
source = "registry.coder.com/modules/gcp-region/coder"
version = "1.0.0"
version = "1.0.2"
default = ["us-west1-a"]
regions = ["us-west1"]
gpu_only = false
@@ -47,10 +47,10 @@ resource "google_compute_instance" "example" {
### Add all zones in the Europe West region
```hcl
```tf
module "gcp_region" {
source = "registry.coder.com/modules/gcp-region/coder"
version = "1.0.0"
version = "1.0.2"
regions = ["europe-west"]
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" {
source = "registry.coder.com/modules/gcp-region/coder"
version = "1.0.0"
version = "1.0.2"
regions = ["us", "europe"]
gpu_only = true
single_zone_per_region = true

View File

@@ -9,35 +9,44 @@ tags: [git, helper]
# 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" {
source = "registry.coder.com/modules/git-clone/coder"
version = "1.0.0"
version = "1.0.2"
agent_id = coder_agent.example.id
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
### Custom Path
```hcl
```tf
module "git-clone" {
source = "registry.coder.com/modules/git-clone/coder"
version = "1.0.0"
version = "1.0.2"
agent_id = coder_agent.example.id
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
}
variable "path" {
variable "base_dir" {
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
}
@@ -25,10 +25,19 @@ variable "agent_id" {
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" {
agent_id = var.agent_id
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,
})
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.
```hcl
```tf
module "git-commit-signing" {
source = "registry.coder.com/modules/git-commit-signing/coder"
version = "1.0.0"
source = "registry.coder.com/modules/git-commit-signing/coder"
version = "1.0.3"
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
EOF
chmod -R 400 ~/.ssh/git-commit-signing/coder
chmod -R 400 ~/.ssh/git-commit-signing/coder.pub
chmod -R 600 ~/.ssh/git-commit-signing/coder
chmod -R 644 ~/.ssh/git-commit-signing/coder.pub
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.
```hcl
```tf
module "git-config" {
source = "registry.coder.com/modules/git-config/coder"
version = "1.0.0"
source = "registry.coder.com/modules/git-config/coder"
version = "1.0.3"
agent_id = coder_agent.example.id
}
```
@@ -25,11 +25,11 @@ TODO: Add screenshot
### Allow users to override both username and email
```hcl
```tf
module "git-config" {
source = "registry.coder.com/modules/git-config/coder"
version = "1.0.0"
agent_id = coder_agent.example.id
source = "registry.coder.com/modules/git-config/coder"
version = "1.0.3"
agent_id = coder_agent.example.id
allow_email_change = true
}
```
@@ -38,14 +38,12 @@ TODO: Add screenshot
## Disallowing users from overriding both username and email
```hcl
```tf
module "git-config" {
source = "registry.coder.com/modules/git-config/coder"
version = "1.0.0"
agent_id = coder_agent.example.id
source = "registry.coder.com/modules/git-config/coder"
version = "1.0.3"
agent_id = coder_agent.example.id
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 {
coder = {
source = "coder/coder"
version = ">= 0.12"
version = ">= 0.13"
}
}
}
@@ -34,7 +34,7 @@ data "coder_parameter" "user_email" {
name = "user_email"
type = "string"
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"
mutable = true
}
@@ -44,18 +44,31 @@ data "coder_parameter" "username" {
name = "username"
type = "string"
default = ""
description = "Git user.name to be used for commits. Leave empty to default to Coder username."
display_name = "Git config user.name"
description = "Git user.name to be used for commits. Leave empty to default to Coder user's Full Name."
display_name = "Full Name for Git config"
mutable = true
}
resource "coder_script" "git_config" {
resource "coder_env" "git_author_name" {
agent_id = var.agent_id
script = templatefile("${path.module}/run.sh", {
GIT_USERNAME = try(data.coder_parameter.username[0].value, "") == "" ? data.coder_workspace.me.owner : try(data.coder_parameter.username[0].value, "")
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"
icon = "/icon/git.svg"
run_on_start = true
name = "GIT_AUTHOR_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_commmiter_name" {
agent_id = var.agent_id
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,75 @@
---
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, follow these steps,
1. [Create secrets in HCP Vault Secrets](https://developer.hashicorp.com/vault/tutorials/hcp-vault-secrets-get-started/hcp-vault-secrets-create-secret)
2. 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.
![HCP vault secrets credentials](../.images/hcp-vault-secrets-credentials.png)
3. Set `HCP_CLIENT_ID` and `HCP_CLIENT_SECRET` variables on the coder provisioner (recommended) or supply them as input to the module.
> 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.
```hcl
```tf
module "jetbrains_gateway" {
source = "registry.coder.com/modules/jetbrains-gateway/coder"
version = "1.0.0"
version = "1.0.3"
agent_id = coder_agent.example.id
agent_name = "example"
folder = "/home/coder/example"
jetbrains_ides = ["GO", "WS", "IU", "PY", "PS", "CL", "RM"]
default = "PY"
@@ -28,14 +29,15 @@ module "jetbrains_gateway" {
### Add GoLand and WebStorm with the default set to GoLand
```hcl
```tf
module "jetbrains_gateway" {
source = "registry.coder.com/modules/jetbrains-gateway/coder"
version = "1.0.0"
agent_id = coder_agent.example.id
folder = "/home/coder/example"
jetbrains_ides = ["GO", "WS"]
default = "GO"
source = "registry.coder.com/modules/jetbrains-gateway/coder"
version = "1.0.3"
agent_id = coder_agent.example.id
agent_name = "example"
folder = "/home/coder/example"
jetbrains_ides = ["GO", "WS"]
default = "GO"
}
```

View File

@@ -30,17 +30,68 @@ variable "default" {
description = "Default IDE"
}
variable "jetbrains_ides" {
type = list(string)
description = "The list of IDE product codes."
default = ["IU", "PS", "WS", "PY", "CL", "GO", "RM"]
locals {
supported_ides = ["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 {
condition = (
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
validation {
@@ -59,37 +110,37 @@ locals {
"GO" = {
icon = "/icon/goland.svg",
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" = {
icon = "/icon/webstorm.svg",
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" = {
icon = "/icon/intellij.svg",
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" = {
icon = "/icon/pycharm.svg",
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" = {
icon = "/icon/clion.svg",
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" = {
icon = "/icon/phpstorm.svg",
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" = {
icon = "/icon/rubymine.svg",
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
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">
<img src='../.images/jfrog-oauth.png' alt="JFrog OAuth" width='600'>
</p>
![JFrog OAuth](../.images/jfrog-oauth.png)
```hcl
```tf
module "jfrog" {
source = "registry.coder.com/modules/jfrog-oauth/coder"
version = "1.0.0"
agent_id = coder_agent.example.id
jfrog_url = "https://jfrog.example.com"
source = "registry.coder.com/modules/jfrog-oauth/coder"
version = "1.0.2"
agent_id = coder_agent.example.id
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"
package_managers = {
"npm": "npm",
"go": "go",
"pypi": "pypi"
"npm" : "npm",
"go" : "go",
"pypi" : "pypi"
}
}
```
@@ -36,64 +35,22 @@ module "jfrog" {
## 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`.
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>
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.
## Examples
Configure the Python pip package manager to fetch packages from Artifactory while mapping the Coder email to the Artifactory username.
```hcl
```tf
module "jfrog" {
source = "registry.coder.com/modules/jfrog-oauth/coder"
version = "1.0.0"
agent_id = coder_agent.example.id
jfrog_url = "https://jfrog.example.com"
auth_method = "oauth"
source = "registry.coder.com/modules/jfrog-oauth/coder"
version = "1.0.2"
agent_id = coder_agent.example.id
jfrog_url = "https://example.jfrog.io"
username_field = "email"
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.
```hcl
```tf
module "jfrog" {
source = "registry.coder.com/modules/jfrog-oauth/coder"
version = "1.0.0"
agent_id = coder_agent.example.id
jfrog_url = "https://jfrog.example.com"
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
source = "registry.coder.com/modules/jfrog-oauth/coder"
version = "1.0.2"
agent_id = coder_agent.example.id
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"
configure_code_server = true # Add JFrog extension configuration for code-server
package_managers = {
"npm": "npm",
"go": "go",
"pypi": "pypi"
"npm" : "npm",
"go" : "go",
"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).
```hcl
```tf
provider "docker" {
...
# ...
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
password = module.jfrog.access_token
}
}
```
> Here `REPO_KEY` is the name of docker repository in Artifactory.

View File

@@ -19,6 +19,12 @@ variable "jfrog_url" {
}
}
variable "jfrog_server_id" {
type = string
description = "The server ID of the JFrog instance for JFrog CLI configuration"
default = "0"
}
variable "username_field" {
type = string
description = "The field to use for the artifactory username. i.e. Coder username or email."
@@ -79,6 +85,7 @@ resource "coder_script" "jfrog" {
script = templatefile("${path.module}/run.sh", {
JFROG_URL : var.jfrog_url,
JFROG_HOST : local.jfrog_host,
JFROG_SERVER_ID : var.jfrog_server_id,
ARTIFACTORY_USERNAME : local.username,
ARTIFACTORY_EMAIL : data.coder_workspace.me.owner_email,
ARTIFACTORY_ACCESS_TOKEN : data.coder_external_auth.jfrog.access_token,

View File

@@ -15,9 +15,9 @@ fi
# flows.
export CI=true
# Authenticate JFrog CLI with Artifactory.
echo "${ARTIFACTORY_ACCESS_TOKEN}" | jf c add --access-token-stdin --url "${JFROG_URL}" --overwrite 0
echo "${ARTIFACTORY_ACCESS_TOKEN}" | jf c add --access-token-stdin --url "${JFROG_URL}" --overwrite "${JFROG_SERVER_ID}"
# Set the configured server as the default.
jf c use 0
jf c use "${JFROG_SERVER_ID}"
# Configure npm to use the Artifactory "npm" repository.
if [ -z "${REPOSITORY_NPM}" ]; then

View File

@@ -12,29 +12,22 @@ tags: [integration, jfrog]
Install the JF CLI and authenticate package managers with Artifactory using Artifactory terraform provider.
```hcl
```tf
module "jfrog" {
source = "registry.coder.com/modules/jfrog-token/coder"
version = "1.0.0"
agent_id = coder_agent.example.id
jfrog_url = "https://XXXX.jfrog.io"
source = "registry.coder.com/modules/jfrog-token/coder"
version = "1.0.2"
agent_id = coder_agent.example.id
jfrog_url = "https://XXXX.jfrog.io"
artifactory_access_token = var.artifactory_access_token
package_managers = {
"npm": "npm",
"go": "go",
"pypi": "pypi"
"npm" : "npm",
"go" : "go",
"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.
```hcl
variable "artifactory_access_token" {
type = string
sensitive = true
}
```
For detailed instructions, please see this [guide](https://coder.com/docs/v2/latest/guides/artifactory-integration#jfrog-token) on the Coder documentation.
> Note
> 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
```hcl
```tf
module "jfrog" {
source = "registry.coder.com/modules/jfrog-token/coder"
version = "1.0.0"
agent_id = coder_agent.example.id
jfrog_url = "https://YYYY.jfrog.io"
source = "registry.coder.com/modules/jfrog-token/coder"
version = "1.0.2"
agent_id = coder_agent.example.id
jfrog_url = "https://YYYY.jfrog.io"
artifactory_access_token = var.artifactory_access_token # An admin access token
package_managers = {
"npm": "npm-local",
"go": "go-local",
"pypi": "pypi-local"
"npm" : "npm-local",
"go" : "go-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.
```hcl
```tf
module "jfrog" {
source = "registry.coder.com/modules/jfrog-token/coder"
version = "1.0.0"
agent_id = coder_agent.example.id
jfrog_url = "https://XXXX.jfrog.io"
source = "registry.coder.com/modules/jfrog-token/coder"
version = "1.0.2"
agent_id = coder_agent.example.id
jfrog_url = "https://XXXX.jfrog.io"
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 = {
"npm": "npm",
"go": "go",
"pypi": "pypi"
"npm" : "npm",
"go" : "go",
"pypi" : "pypi"
}
}
```
@@ -98,14 +91,16 @@ 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).
```hcl
```tf
provider "docker" {
...
# ...
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
password = module.jfrog.access_token
}
}
```
> Here `REPO_KEY` is the name of docker repository in Artifactory.

View File

@@ -23,6 +23,12 @@ variable "jfrog_url" {
}
}
variable "jfrog_server_id" {
type = string
description = "The server ID of the JFrog instance for JFrog CLI configuration"
default = "0"
}
variable "artifactory_access_token" {
type = string
description = "The admin-level access token to use for JFrog."
@@ -112,6 +118,7 @@ resource "coder_script" "jfrog" {
script = templatefile("${path.module}/run.sh", {
JFROG_URL : var.jfrog_url,
JFROG_HOST : local.jfrog_host,
JFROG_SERVER_ID : var.jfrog_server_id,
ARTIFACTORY_USERNAME : local.username,
ARTIFACTORY_EMAIL : data.coder_workspace.me.owner_email,
ARTIFACTORY_ACCESS_TOKEN : artifactory_scoped_token.me.access_token,

View File

@@ -15,9 +15,9 @@ fi
# flows.
export CI=true
# Authenticate JFrog CLI with Artifactory.
echo "${ARTIFACTORY_ACCESS_TOKEN}" | jf c add --access-token-stdin --url "${JFROG_URL}" --overwrite 0
echo "${ARTIFACTORY_ACCESS_TOKEN}" | jf c add --access-token-stdin --url "${JFROG_URL}" --overwrite "${JFROG_SERVER_ID}"
# Set the configured server as the default.
jf c use 0
jf c use "${JFROG_SERVER_ID}"
# Configure npm to use the Artifactory "npm" repository.
if [ -z "${REPOSITORY_NPM}" ]; then

View File

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

49
lint.ts
View File

@@ -13,9 +13,39 @@ let badExit = false;
// error reports an error to the console and sets badExit to true
// so that the process will exit with a non-zero exit code.
const error = (...data: any[]) => {
console.error(...data);
badExit = true;
}
console.error(...data);
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.
// Exits with 0 if all is good!
@@ -62,6 +92,7 @@ for (const dir of dirs) {
let h1 = false;
let code = false;
let paragraph = false;
let version = true;
for (const token of tokens) {
if (token.type === "heading" && token.depth === 1) {
@@ -77,6 +108,10 @@ for (const dir of dirs) {
}
if (token.type === "code") {
code = true;
if (token.lang === "tf" && !token.text.includes("version")) {
version = false;
error(dir.name, "missing version in tf code block");
}
continue;
}
}
@@ -89,6 +124,14 @@ for (const dir of dirs) {
if (!code) {
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) {

4
new.sh
View File

@@ -1,6 +1,6 @@
#!/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
MODULE_NAME=$1
@@ -11,7 +11,7 @@ if [ -z "$MODULE_NAME" ]; then
exit 1
fi
# Create module directory and exit if it alredy exists
# Create module directory and exit if it already exists
if [ -d "$MODULE_NAME" ]; then
echo "Module with name $MODULE_NAME already exists"
echo "Please choose a different name"

View File

@@ -2,17 +2,25 @@
"name": "modules",
"scripts": {
"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: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",
"lint": "bun run lint.ts"
"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 --check **/*.sh .sample/run.sh new.sh **/*.ts **/*.md *.md && terraform fmt -check **/*.tf .sample/main.tf",
"lint": "bun run lint.ts",
"update-version": "./update-version.sh"
},
"devDependencies": {
"bun-types": "^1.0.18",
"gray-matter": "^4.0.3",
"marked": "^11.1.0",
"prettier-plugin-sh": "^0.13.1"
"prettier-plugin-sh": "^0.13.1",
"prettier-plugin-terraform-formatter": "^1.2.1"
},
"peerDependencies": {
"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.
```hcl
```tf
module "personalize" {
source = "registry.coder.com/modules/personalize/coder"
version = "1.0.0"
source = "registry.coder.com/modules/personalize/coder"
version = "1.0.2"
agent_id = coder_agent.example.id
}
```

View File

@@ -54,11 +54,11 @@ 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`:
```hcl
```tf
module "slackme" {
source = "registry.coder.com/modules/slackme/coder"
version = "1.0.0"
agent_id = coder_agent.example.id
source = "registry.coder.com/modules/slackme/coder"
version = "1.0.2"
agent_id = coder_agent.example.id
auth_provider_id = "slack"
}
```
@@ -70,13 +70,13 @@ slackme npm run long-build
- `$COMMAND` is replaced with the command the user executed.
- `$DURATION` is replaced with a human-readable duration the command took to execute.
```hcl
```tf
module "slackme" {
source = "registry.coder.com/modules/slackme/coder"
version = "1.0.0"
agent_id = coder_agent.example.id
source = "registry.coder.com/modules/slackme/coder"
version = "1.0.2"
agent_id = coder_agent.example.id
auth_provider_id = "slack"
slack_message = <<EOF
slack_message = <<EOF
👋 Hey there from Coder! $COMMAND took $DURATION to execute!
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
icon: ../.icons/vault.svg
maintainer_github: coder
partner_github: hashicorp
verified: true
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.
```hcl
```tf
module "vault" {
source = "registry.coder.com/modules/vault-github/coder"
version = "1.0.0"
version = "1.0.4"
agent_id = coder_agent.example.id
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:
```shell
vault kv get -mount=secret my-secret
vault kv get -mount=coder my-secret
```
or using the Vault API:
```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)
@@ -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`)
```hcl
```tf
module "vault" {
source = "registry.coder.com/modules/vault-github/coder"
version = "1.0.0"
version = "1.0.4"
agent_id = coder_agent.example.id
vault_addr = "https://vault.example.com"
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
```hcl
```tf
module "vault" {
source = "registry.coder.com/modules/vault-github/coder"
version = "1.0.0"
version = "1.0.4"
agent_id = coder_agent.example.id
vault_addr = "https://vault.example.com"
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
```hcl
```tf
module "vault" {
source = "registry.coder.com/modules/vault-github/coder"
version = "1.0.0"
version = "1.0.4"
agent_id = coder_agent.example.id
vault_addr = "https://vault.example.com"
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)"
icon = "/icon/vault.svg"
script = templatefile("${path.module}/run.sh", {
VAULT_ADDR : var.vault_addr,
AUTH_PATH : var.vault_github_auth_path,
GITHUB_EXTERNAL_AUTH_ID : data.coder_external_auth.github.id,
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
INSTALL_VERSION=${INSTALL_VERSION}
VAULT_ADDR=${VAULT_ADDR}
GITHUB_EXTERNAL_AUTH_ID=${GITHUB_EXTERNAL_AUTH_ID}
AUTH_PATH=${AUTH_PATH}
@@ -21,7 +20,7 @@ fetch() {
fi
}
unzip() {
unzip_safe() {
if command -v unzip > /dev/null 2>&1; then
command unzip "$@"
elif command -v busybox > /dev/null 2>&1; then
@@ -32,57 +31,68 @@ unzip() {
fi
}
# 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 -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"
exit 1
fi
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}" "$${VERSION}"
fi
fetch vault.zip "https://releases.hashicorp.com/vault/$${VERSION}/vault_$${VERSION}_linux_amd64.zip"
if [ $? -ne 0 ]; then
printf "Failed to download Vault.\n"
exit 1
fi
unzip vault.zip
if [ $? -ne 0 ]; then
printf "Failed to unzip Vault.\n"
exit 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
mv vault ~/.local/bin/vault
if [ ! -f ~/.local/bin/vault ]; then
printf "Failed to move Vault to local bin.\n"
exit 1
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
printf "Please add ~/.local/bin to your PATH to use vault CLI.\n"
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"
# Authenticate with Vault
printf "🔑 Authenticating with Vault ...\n\n"
@@ -92,8 +102,6 @@ if [ $? -ne 0 ]; then
exit 1
fi
export VAULT_ADDR="$${VAULT_ADDR}"
# Login to vault using the GitHub token
printf "🔑 Logging in to Vault ...\n\n"
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.4"
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.4"
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).
```hcl
```tf
module "vscode" {
source = "registry.coder.com/modules/vscode-desktop/coder"
version = "1.0.0"
source = "registry.coder.com/modules/vscode-desktop/coder"
version = "1.0.2"
agent_id = coder_agent.example.id
}
```
@@ -25,11 +25,11 @@ module "vscode" {
### Open in a specific directory
```hcl
```tf
module "vscode" {
source = "registry.coder.com/modules/vscode-desktop/coder"
version = "1.0.0"
source = "registry.coder.com/modules/vscode-desktop/coder"
version = "1.0.2"
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.
```hcl
```tf
module "vscode-web" {
source = "registry.coder.com/modules/vscode-web/coder"
version = "1.0.0"
version = "1.0.3"
agent_id = coder_agent.example.id
accept_license = true
}
@@ -26,13 +26,13 @@ module "vscode-web" {
### Install VS Code Web to a custom folder
```hcl
```tf
module "vscode-web" {
source = "registry.coder.com/modules/vscode-web/coder"
version = "1.0.0"
agent_id = coder_agent.example.id
install_dir = "/home/coder/.vscode-web"
folder = "/home/coder"
accept_license = true
source = "registry.coder.com/modules/vscode-web/coder"
version = "1.0.3"
agent_id = coder_agent.example.id
install_dir = "/home/coder/.vscode-web"
folder = "/home/coder"
accept_license = true
}
```

View File

@@ -20,6 +20,18 @@ variable "port" {
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" {
type = string
description = "The folder to open in vscode-web."
@@ -71,8 +83,8 @@ resource "coder_script" "vscode-web" {
resource "coder_app" "vscode-web" {
agent_id = var.agent_id
slug = "vscode-web"
display_name = "VS Code Web"
slug = var.slug
display_name = var.display_name
url = var.folder == "" ? "http://localhost:${var.port}" : "http://localhost:${var.port}?folder=${var.folder}"
icon = "/icon/code.svg"
subdomain = true