Add Hashicorp Vault Integration (GitHub) (#105)
Co-authored-by: Mathias Fredriksson <mafredri@gmail.com>pull/109/head
parent
98bb94c5f0
commit
c1800b7a85
@ -0,0 +1,2 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
||||||
|
<svg width="800px" height="800px" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" fill="none"><path fill="#FFD814" d="M0 0l7.971 15.516L16 0H0zm6.732 6.16h-1.27V4.89h1.27v1.27zm0-1.906h-1.27V2.985h1.27v1.269zm1.904 3.81h-1.27v-1.27h1.27v1.27zm0-1.905h-1.27V4.89h1.27v1.27zm0-1.905h-1.27V2.985h1.27v1.269zm1.894 1.905H9.26V4.89h1.27v1.27zM9.26 4.254V2.985h1.27v1.269H9.26z"/></svg>
|
After Width: | Height: | Size: 506 B |
Binary file not shown.
After Width: | Height: | Size: 202 KiB |
@ -0,0 +1,84 @@
|
|||||||
|
---
|
||||||
|
display_name: Hashicorp Vault Integration (GitHub)
|
||||||
|
description: Authenticates with Vault using GitHub
|
||||||
|
icon: ../.icons/vault.svg
|
||||||
|
maintainer_github: coder
|
||||||
|
verified: true
|
||||||
|
tags: [helper, integration, vault, github]
|
||||||
|
---
|
||||||
|
|
||||||
|
# Hashicorp Vault Integration (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
|
||||||
|
module "vault" {
|
||||||
|
source = "https://registry.coder.com/modules/vault-github"
|
||||||
|
agent_id = coder_agent.example.id
|
||||||
|
vault_addr = "https://vault.example.com"
|
||||||
|
}
|
||||||
|
|
||||||
|
# A workaround until we have https://github.com/coder/terraform-provider-coder/issues/170
|
||||||
|
resource "coder_agent" "example" {
|
||||||
|
...
|
||||||
|
env = {
|
||||||
|
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 -mount=secret my-secret
|
||||||
|
```
|
||||||
|
|
||||||
|
or using the Vault API:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
curl -H "X-Vault-Token: ${VAULT_TOKEN}" -X GET "${VAULT_ADDR}/v1/secret/data/my-secret"
|
||||||
|
```
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
### Configure Vault integration with a different Coder GitHub external auth ID (i.e., not the default `github`)
|
||||||
|
|
||||||
|
```hcl
|
||||||
|
module "vault" {
|
||||||
|
source = "https://registry.coder.com/modules/vault"
|
||||||
|
agent_id = coder_agent.example.id
|
||||||
|
vault_addr = "https://vault.example.com"
|
||||||
|
coder_github_auth_id = "my-github-auth-id"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Configure Vault integration with a different Coder GitHub external auth ID and a different Vault GitHub auth path
|
||||||
|
|
||||||
|
```hcl
|
||||||
|
module "vault" {
|
||||||
|
source = "https://registry.coder.com/modules/vault"
|
||||||
|
agent_id = coder_agent.example.id
|
||||||
|
vault_addr = "https://vault.example.com"
|
||||||
|
coder_github_auth_id = "my-github-auth-id"
|
||||||
|
vault_github_auth_path = "my-github-auth-path"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Configure Vault integration and install a specific version of the Vault CLI
|
||||||
|
|
||||||
|
```hcl
|
||||||
|
module "vault" {
|
||||||
|
source = "https://registry.coder.com/modules/vault"
|
||||||
|
agent_id = coder_agent.example.id
|
||||||
|
vault_addr = "https://vault.example.com"
|
||||||
|
vault_cli_version = "1.15.0"
|
||||||
|
}
|
||||||
|
```
|
@ -0,0 +1,62 @@
|
|||||||
|
terraform {
|
||||||
|
required_version = ">= 1.0"
|
||||||
|
|
||||||
|
required_providers {
|
||||||
|
coder = {
|
||||||
|
source = "coder/coder"
|
||||||
|
version = ">= 0.12"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# 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 "coder_github_auth_id" {
|
||||||
|
type = string
|
||||||
|
description = "The ID of the GitHub external auth."
|
||||||
|
default = "github"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "vault_github_auth_path" {
|
||||||
|
type = string
|
||||||
|
description = "The path to the GitHub auth method."
|
||||||
|
default = "github"
|
||||||
|
}
|
||||||
|
|
||||||
|
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 (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,
|
||||||
|
})
|
||||||
|
run_on_start = true
|
||||||
|
start_blocks_login = true
|
||||||
|
}
|
||||||
|
|
||||||
|
data "coder_external_auth" "github" {
|
||||||
|
id = var.coder_github_auth_id
|
||||||
|
}
|
@ -0,0 +1,101 @@
|
|||||||
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
# 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}
|
||||||
|
|
||||||
|
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"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
unzip() {
|
||||||
|
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"
|
||||||
|
exit 1
|
||||||
|
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
|
||||||
|
fi
|
||||||
|
printf "Please add ~/.local/bin to your PATH to use vault CLI.\n"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Authenticate with Vault
|
||||||
|
printf "🔑 Authenticating with Vault ...\n\n"
|
||||||
|
GITHUB_TOKEN=$(coder external-auth access-token "$${GITHUB_EXTERNAL_AUTH_ID}")
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
printf "Authentication with Vault failed. Please check your credentials.\n"
|
||||||
|
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}"
|
||||||
|
printf "🥳 Vault authentication complete!\n\n"
|
||||||
|
printf "You can now use Vault CLI to access secrets.\n"
|
Loading…
Reference in New Issue