Skip to content

Instantly share code, notes, and snippets.

@hkwi
Last active January 6, 2026 00:28
Show Gist options
  • Select an option

  • Save hkwi/2a33c7045d5620e093968b765d2611eb to your computer and use it in GitHub Desktop.

Select an option

Save hkwi/2a33c7045d5620e093968b765d2611eb to your computer and use it in GitHub Desktop.
nomad vault integration確認用

Nomad + Vault Integration Sample (最小サンプル)

このワーキングスペースは、Nomad と HashiCorp Vault の連携を手早く動作確認するための最小サンプルです。

目的:

  • Nomad が Vault からシークレットを取得できることを確認する最小構成を提供します。

構成ファイル:

  • docker-compose.yml - 必要なサービス(Vault, Nomad など)をローカルで立ち上げるための構成。
  • Dockerfile.bootstrap - ブートストラップ用のイメージ作成に使う Dockerfile。
  • bootstrap.sh - Vault の初期化やトークン発行、Nomad の設定などブートストラップ処理を行うスクリプト。
  • nomad.hcl - Nomad の最小構成ファイル(クライアント/サーバ設定や Vault の統合設定を含む)。

クイックスタート (ローカル開発用)

前提:

  • Docker と Docker Compose がインストールされていること。
  1. コンテナ群を起動する:
docker compose up -d
  1. ブートストラップ処理を実行する:
./bootstrap.sh
  1. Nomad のジョブを submit して、ジョブ内で Vault シークレットが取得できることを確認します。
# 例: nomad job run example.nomad

注意:

  • このリポジトリは学習/検証用の最小構成を目的としています。本番利用のセキュリティ要件(TLS 設定、強力なトークン管理、監査ログなど)は満たしていません。

追加情報:

  • 手順やコマンドの詳細は DIRECTIONS.md を参照してください。
#!/bin/sh
set -eu
VAULT_ADDR="http://vault:8200"
VAULT_TOKEN="root"
NOMAD_ADDR="http://nomad:4646"
# Wait for Vault
echo "Waiting for Vault..."
until curl -sSf "$VAULT_ADDR/v1/sys/health" >/dev/null 2>&1; do
sleep 1
done
echo "Vault is up"
# Wait for Nomad
echo "Waiting for Nomad..."
until curl -sSf "$NOMAD_ADDR/v1/status/leader" >/dev/null 2>&1; do
sleep 1
done
echo "Nomad is up"
# enable vault audit logging to file
jo type=file options=$(jo file_path="/tmp/vault_audit.log") | tee /tmp/audit-backend.json | jq .
curl -sSf -H "X-Vault-Token: $VAULT_TOKEN" "$VAULT_ADDR/v1/sys/audit/file" -d @/tmp/audit-backend.json
# Ensure KV v2 is mounted at "secret/"
if ! curl -sSf -H "X-Vault-Token: $VAULT_TOKEN" "$VAULT_ADDR/v1/sys/mounts" | grep -q '"secret/"'; then
echo "Enabling KV v2 at path secret"
curl -sSf -X POST -H "X-Vault-Token: $VAULT_TOKEN" -d '{"type":"kv","options":{"version":"2"}}' "$VAULT_ADDR/v1/sys/mounts/secret"
else
echo "KV mount at secret/ already present"
fi
# Write foo=bar to secret path secret/s1 (KV v2)
cat > /tmp/secret-data.json <<EOF
{
"data": {
"foo": "bar"
}
}
EOF
echo "Writing secret to secret/data/s1"
curl -sSf -H "X-Vault-Token: $VAULT_TOKEN" -H "Content-Type: application/json" -X POST -d @/tmp/secret-data.json "$VAULT_ADDR/v1/secret/data/s1"
echo "Secret written"
# Mount jwt auth method if not mounted
if ! curl -sSf -H "X-Vault-Token: $VAULT_TOKEN" "$VAULT_ADDR/v1/sys/auth" | grep -q "jwt-nomad/"; then
echo "Enabling JWT auth method at path jwt-nomad"
curl -sSf -X POST -H "X-Vault-Token: $VAULT_TOKEN" -d '{"type":"jwt"}' "$VAULT_ADDR/v1/sys/auth/jwt-nomad"
else
echo "JWT auth already enabled"
fi
# Configure the JWT auth method to use Nomad JWKS endpoint
JWKS_URL="$NOMAD_ADDR/.well-known/jwks.json"
echo "Configuring JWT auth method to use JWKS URL: $JWKS_URL"
cat > /tmp/auth-config.json <<EOF
{
"jwks_url": "${JWKS_URL}",
"jwt_supported_algs": ["RS256"],
"default_role": "nomad-workloads"
}
EOF
curl -sSf -H "X-Vault-Token: $VAULT_TOKEN" -X POST -d @/tmp/auth-config.json "$VAULT_ADDR/v1/auth/jwt-nomad/config"
# Create a policy for nomad workloads
cat > /tmp/nomad-workloads.rule <<'EOF'
path "auth/jwt-nomad/role/nomad-workloads" {
capabilities = ["read"]
}
path "secret/*" {
capabilities = ["read"]
}
EOF
jo policy=@/tmp/nomad-workloads.rule > /tmp/nomad-workloads.hcl
curl -sSf -H "X-Vault-Token: $VAULT_TOKEN" -X PUT -d @/tmp/nomad-workloads.hcl "$VAULT_ADDR/v1/sys/policies/acl/nomad-workloads"
# Create a role that binds to nomad claims
cat > /tmp/acl-role.json <<EOF
{
"role_type": "jwt",
"bound_audiences": ["nomad"],
"bound_claims": {
"nomad_namespace": "default"
},
"user_claim": "/nomad_job_id",
"user_claim_json_pointer": true,
"claim_mappings": {
"nomad_namespace": "nomad_namespace",
"nomad_job_id": "nomad_job_id",
"nomad_task": "nomad_task"
},
"token_policies": ["nomad-workloads"],
"token_type": "service",
"token_period": "30m",
"token_explicit_max_ttl": 0
}
EOF
curl -sSf -H "X-Vault-Token: $VAULT_TOKEN" -X POST -d @/tmp/acl-role.json "$VAULT_ADDR/v1/auth/jwt-nomad/role/nomad-workloads"
echo "Bootstrap complete"
cat > /tmp/job.hcl <<'EOF'
job "j1" {
type = "batch"
group "g1" {
task "t1" {
driver = "docker"
config {
image = "ubuntu:22.04"
args = ["cat", "local/foo.txt"]
}
# XXX: YOU need vault section here for vault access
vault {
cluster = "default"
}
template {
destination = "local/foo.txt"
data = <<EOD
{{ with secret "secret/data/s1" }}
{{ .Data.data.foo }}
{{ end }}
EOD
}
}
}
}
EOF
cat /tmp/job.hcl
jo JobHCL=@/tmp/job.hcl | tee /tmp/job-req.json | jq .
curl -v -s $NOMAD_ADDR/v1/jobs/parse -H Content-type:application/json -d @/tmp/job-req.json > /tmp/job-p.json
#cat /tmp/job-p.json | jq -r '{"Job":.}' | tee /tmp/job-p-req.json
jq -n --rawfile sub /tmp/job.hcl --slurpfile job /tmp/job-p.json -r '{"Job":$job[0], "Submission":{"Format":"hcl2","Source":$sub}}' | tee /tmp/job-p-req.json
curl -v -D - $NOMAD_ADDR/v1/jobs -H Content-type:application/json -d @/tmp/job-p-req.json
for q in $(seq 1 10); do
ST=$(curl -s -X GET $NOMAD_ADDR/v1/job/j1/evaluations | jq -r '.[].Status')
if [ "$ST" = "complete" ]; then
break
fi
echo "Evaluation status: $ST. Waiting..."
sleep 2
done
echo "========================="
AID=$(curl -s $NOMAD_ADDR/v1/job/j1/allocations | jq -r '.[0].ID')
OUT=$(curl -s "$NOMAD_ADDR/v1/client/fs/logs/$AID?task=t1&type=stdout" | jq -r .Data | base64 -d | tr -d '[:space:]\r\n')
if [ "$OUT" = "bar" ]; then
echo "Success: Retrieved secret value '$OUT' from Vault via Nomad"
else
echo "Failure: Unexpected output '$OUT'"
exit 1
fi
  • 最も記述量の少ない簡素な設定ファイルを作成します
  • nomad valut acl integration を動作させる

References

services:
vault:
image: hashicorp/vault:latest
ports:
- "8200:8200"
environment:
- VAULT_DEV_ROOT_TOKEN_ID=root
- VAULT_DEV_LISTEN_ADDRESS=0.0.0.0:8200
cap_add:
- IPC_LOCK
nomad:
image: hashicorp/nomad:1.11.1
ports:
- "4646:4646"
command: agent -server -config /etc/nomad.d/config.hcl
privileged: true
depends_on:
- vault
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /sys/fs/cgroup:/sys/fs/cgroup:rw
- ./nomad.hcl:/etc/nomad.d/config.hcl:ro
# XXX: nomad を docker から使うために docker socket を渡している
# template の出力が伝播するには docker host 側でも見えるようにする
- /var/lib/nomad/alloc:/var/lib/nomad/alloc:rw
bootstrap:
build:
context: .
dockerfile: Dockerfile.bootstrap
depends_on:
- vault
- nomad
volumes:
- ./bootstrap.sh:/bootstrap.sh:ro
entrypoint: ["/bin/sh", "/bootstrap.sh"]
FROM ubuntu:22.04
RUN apt-get update -y && apt-get install -y curl jo jq
# Nomad Configuration
# Define the Nomad server configuration
# This is a minimal configuration for Nomad
data_dir = "/var/lib/nomad"
bind_addr = "0.0.0.0"
disable_update_check = true
log_level = "DEBUG"
advertise {
http = "nomad"
}
server {
enabled = true
bootstrap_expect = 1
}
client {
enabled = true
}
vault {
enabled = true
address = "http://vault:8200"
# jwt_auth_backend_path = "jwt"
default_identity {
aud = ["nomad"]
ttl = "1h"
}
}
plugin "raw_exec" {
config {
enabled = true
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment