Skip to content
This repository was archived by the owner on May 15, 2025. It is now read-only.

Commit c1800b7

Browse files
matifalimafredri
andauthored
Add Hashicorp Vault Integration (GitHub) (#105)
Co-authored-by: Mathias Fredriksson <mafredri@gmail.com>
1 parent 98bb94c commit c1800b7

File tree

5 files changed

+249
-0
lines changed

5 files changed

+249
-0
lines changed

.icons/vault.svg

Lines changed: 2 additions & 0 deletions
Loading

.images/vault-login.png

202 KB
Loading

vault-github/README.md

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
---
2+
display_name: Hashicorp Vault Integration (GitHub)
3+
description: Authenticates with Vault using GitHub
4+
icon: ../.icons/vault.svg
5+
maintainer_github: coder
6+
verified: true
7+
tags: [helper, integration, vault, github]
8+
---
9+
10+
# Hashicorp Vault Integration (GitHub)
11+
12+
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.
13+
14+
```hcl
15+
module "vault" {
16+
source = "https://registry.coder.com/modules/vault-github"
17+
agent_id = coder_agent.example.id
18+
vault_addr = "https://vault.example.com"
19+
}
20+
21+
# A workaround until we have https://github.com/coder/terraform-provider-coder/issues/170
22+
resource "coder_agent" "example" {
23+
...
24+
env = {
25+
VAULT_ADDR = "https://vault.example.com"
26+
}
27+
...
28+
}
29+
30+
```
31+
32+
Then you can use the Vault CLI in your workspaces to fetch secrets from Vault:
33+
34+
```shell
35+
vault kv get -mount=secret my-secret
36+
```
37+
38+
or using the Vault API:
39+
40+
```shell
41+
curl -H "X-Vault-Token: ${VAULT_TOKEN}" -X GET "${VAULT_ADDR}/v1/secret/data/my-secret"
42+
```
43+
44+
![Vault login](../.images/vault-login.png)
45+
46+
## Configuration
47+
48+
To configure the Vault module, you must set up a Vault GitHub auth method. See the [Vault documentation](https://www.vaultproject.io/docs/auth/github) for more information.
49+
50+
## Examples
51+
52+
### Configure Vault integration with a different Coder GitHub external auth ID (i.e., not the default `github`)
53+
54+
```hcl
55+
module "vault" {
56+
source = "https://registry.coder.com/modules/vault"
57+
agent_id = coder_agent.example.id
58+
vault_addr = "https://vault.example.com"
59+
coder_github_auth_id = "my-github-auth-id"
60+
}
61+
```
62+
63+
### Configure Vault integration with a different Coder GitHub external auth ID and a different Vault GitHub auth path
64+
65+
```hcl
66+
module "vault" {
67+
source = "https://registry.coder.com/modules/vault"
68+
agent_id = coder_agent.example.id
69+
vault_addr = "https://vault.example.com"
70+
coder_github_auth_id = "my-github-auth-id"
71+
vault_github_auth_path = "my-github-auth-path"
72+
}
73+
```
74+
75+
### Configure Vault integration and install a specific version of the Vault CLI
76+
77+
```hcl
78+
module "vault" {
79+
source = "https://registry.coder.com/modules/vault"
80+
agent_id = coder_agent.example.id
81+
vault_addr = "https://vault.example.com"
82+
vault_cli_version = "1.15.0"
83+
}
84+
```

vault-github/main.tf

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
terraform {
2+
required_version = ">= 1.0"
3+
4+
required_providers {
5+
coder = {
6+
source = "coder/coder"
7+
version = ">= 0.12"
8+
}
9+
}
10+
}
11+
12+
# Add required variables for your modules and remove any unneeded variables
13+
variable "agent_id" {
14+
type = string
15+
description = "The ID of a Coder agent."
16+
}
17+
18+
variable "vault_addr" {
19+
type = string
20+
description = "The address of the Vault server."
21+
}
22+
23+
variable "coder_github_auth_id" {
24+
type = string
25+
description = "The ID of the GitHub external auth."
26+
default = "github"
27+
}
28+
29+
variable "vault_github_auth_path" {
30+
type = string
31+
description = "The path to the GitHub auth method."
32+
default = "github"
33+
}
34+
35+
variable "vault_cli_version" {
36+
type = string
37+
description = "The version of Vault to install."
38+
default = "latest"
39+
validation {
40+
condition = can(regex("^(latest|[0-9]+\\.[0-9]+\\.[0-9]+)$", var.vault_cli_version))
41+
error_message = "Vault version must be in the format 0.0.0 or latest"
42+
}
43+
}
44+
45+
data "coder_workspace" "me" {}
46+
resource "coder_script" "vault" {
47+
agent_id = var.agent_id
48+
display_name = "Vault (GitHub)"
49+
icon = "/icon/vault.svg"
50+
script = templatefile("${path.module}/run.sh", {
51+
VAULT_ADDR : var.vault_addr,
52+
AUTH_PATH : var.vault_github_auth_path,
53+
GITHUB_EXTERNAL_AUTH_ID : data.coder_external_auth.github.id,
54+
INSTALL_VERSION : var.vault_cli_version,
55+
})
56+
run_on_start = true
57+
start_blocks_login = true
58+
}
59+
60+
data "coder_external_auth" "github" {
61+
id = var.coder_github_auth_id
62+
}

vault-github/run.sh

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
#!/usr/bin/env sh
2+
3+
# Convert all templated variables to shell variables
4+
INSTALL_VERSION=${INSTALL_VERSION}
5+
VAULT_ADDR=${VAULT_ADDR}
6+
GITHUB_EXTERNAL_AUTH_ID=${GITHUB_EXTERNAL_AUTH_ID}
7+
AUTH_PATH=${AUTH_PATH}
8+
9+
fetch() {
10+
dest="$1"
11+
url="$2"
12+
if command -v curl > /dev/null 2>&1; then
13+
curl -sSL --fail "$${url}" -o "$${dest}"
14+
elif command -v wget > /dev/null 2>&1; then
15+
wget -O "$${dest}" "$${url}"
16+
elif command -v busybox > /dev/null 2>&1; then
17+
busybox wget -O "$${dest}" "$${url}"
18+
else
19+
printf "curl, wget, or busybox is not installed. Please install curl or wget in your image.\n"
20+
exit 1
21+
fi
22+
}
23+
24+
unzip() {
25+
if command -v unzip > /dev/null 2>&1; then
26+
command unzip "$@"
27+
elif command -v busybox > /dev/null 2>&1; then
28+
busybox unzip "$@"
29+
else
30+
printf "unzip or busybox is not installed. Please install unzip in your image.\n"
31+
exit 1
32+
fi
33+
}
34+
35+
# Fetch the latest version of Vault if INSTALL_VERSION is 'latest'
36+
if [ "$${INSTALL_VERSION}" = "latest" ]; then
37+
LATEST_VERSION=$(curl -s https://releases.hashicorp.com/vault/ | grep -oP 'vault/\K[0-9]+\.[0-9]+\.[0-9]+' | sort -V | tail -n 1)
38+
printf "Latest version of Vault is %s.\n\n" "$${LATEST_VERSION}"
39+
if [ -z "$${LATEST_VERSION}" ]; then
40+
printf "Failed to determine the latest Vault version.\n"
41+
exit 1
42+
fi
43+
VERSION=$${LATEST_VERSION}
44+
fi
45+
46+
# Check if the vault CLI is installed and has the correct version
47+
installation_needed=1
48+
if command -v vault > /dev/null 2>&1; then
49+
CURRENT_VERSION=$(vault version | grep -oE '[0-9]+\.[0-9]+\.[0-9]+')
50+
if [ "$${CURRENT_VERSION}" = "$${INSTALL_VERSION}" ]; then
51+
printf "Vault version %s is already installed and up-to-date.\n\n" "$${CURRENT_VERSION}"
52+
installation_needed=0
53+
fi
54+
fi
55+
56+
if [ $${installation_needed} -eq 1 ]; then
57+
# Download and install Vault
58+
if [ -z "$${CURRENT_VERSION}" ]; then
59+
printf "Installing Vault CLI ...\n\n"
60+
else
61+
printf "Upgrading Vault CLI from version %s to %s ...\n\n" "$${CURRENT_VERSION}" "$${VERSION}"
62+
fi
63+
fetch vault.zip "https://releases.hashicorp.com/vault/$${VERSION}/vault_$${VERSION}_linux_amd64.zip"
64+
if [ $? -ne 0 ]; then
65+
printf "Failed to download Vault.\n"
66+
exit 1
67+
fi
68+
unzip vault.zip
69+
if [ $? -ne 0 ]; then
70+
printf "Failed to unzip Vault.\n"
71+
exit 1
72+
fi
73+
rm vault.zip
74+
if sudo mv vault /usr/local/bin/vault 2> /dev/null; then
75+
printf "Vault installed successfully!\n\n"
76+
else
77+
mkdir -p ~/.local/bin
78+
mv vault ~/.local/bin/vault
79+
if [ ! -f ~/.local/bin/vault ]; then
80+
printf "Failed to move Vault to local bin.\n"
81+
exit 1
82+
fi
83+
printf "Please add ~/.local/bin to your PATH to use vault CLI.\n"
84+
fi
85+
fi
86+
87+
# Authenticate with Vault
88+
printf "🔑 Authenticating with Vault ...\n\n"
89+
GITHUB_TOKEN=$(coder external-auth access-token "$${GITHUB_EXTERNAL_AUTH_ID}")
90+
if [ $? -ne 0 ]; then
91+
printf "Authentication with Vault failed. Please check your credentials.\n"
92+
exit 1
93+
fi
94+
95+
export VAULT_ADDR="$${VAULT_ADDR}"
96+
97+
# Login to vault using the GitHub token
98+
printf "🔑 Logging in to Vault ...\n\n"
99+
vault login -no-print -method=github -path=/$${AUTH_PATH} token="$${GITHUB_TOKEN}"
100+
printf "🥳 Vault authentication complete!\n\n"
101+
printf "You can now use Vault CLI to access secrets.\n"

0 commit comments

Comments
 (0)