HashiCorp Vault — Helm Chart Deployment

2 minute read

Deploy Vault on Kubernetes using the official HashiCorp Helm chart with Raft integrated storage for high availability.


Add Helm Repository

helm repo add hashicorp https://helm.releases.hashicorp.com
helm repo update

Development Mode

Quick deployment for testing:

helm install vault hashicorp/vault \
    --set "server.dev.enabled=true"

This runs a single Vault server in dev mode (unsealed, root token = root).


Production HA Deployment

values.yaml

global:
  enabled: true
  tlsDisable: false

server:
  # 3-node HA cluster
  ha:
    enabled: true
    replicas: 3
    raft:
      enabled: true
      config: |
        ui = true

        listener "tcp" {
          tls_disable = 0
          address = "[::]:8200"
          cluster_address = "[::]:8201"
          tls_cert_file = "/vault/userconfig/vault-tls/tls.crt"
          tls_key_file  = "/vault/userconfig/vault-tls/tls.key"
          tls_client_ca_file = "/vault/userconfig/vault-tls/ca.crt"
        }

        storage "raft" {
          path = "/vault/data"
        }

        service_registration "kubernetes" {}

  # Resource limits
  resources:
    requests:
      memory: 256Mi
      cpu: 250m
    limits:
      memory: 512Mi
      cpu: 500m

  # Persistent storage
  dataStorage:
    enabled: true
    size: 10Gi
    storageClass: null  # Uses default StorageClass

  # Audit log storage
  auditStorage:
    enabled: true
    size: 10Gi

  # Extra volumes for TLS
  extraVolumes:
    - type: secret
      name: vault-tls

  # Pod annotations
  annotations:
    prometheus.io/scrape: "true"
    prometheus.io/port: "8200"
    prometheus.io/path: "/v1/sys/metrics"

# Vault Agent Injector
injector:
  enabled: true
  replicas: 2
  resources:
    requests:
      memory: 64Mi
      cpu: 50m
    limits:
      memory: 128Mi
      cpu: 100m

# Vault UI
ui:
  enabled: true
  serviceType: ClusterIP

Deploy

helm install vault hashicorp/vault \
    --namespace vault \
    --create-namespace \
    -f values.yaml

Initialize and Unseal

# Wait for pods to be running
kubectl -n vault get pods -w

# Initialize the first node
kubectl -n vault exec vault-0 -- vault operator init \
    -key-shares=5 \
    -key-threshold=3 \
    -format=json > vault-init.json

# Extract keys and root token
KEYS=$(cat vault-init.json | jq -r '.unseal_keys_b64[]')
ROOT_TOKEN=$(cat vault-init.json | jq -r '.root_token')

# Unseal vault-0 (need 3 of 5 keys)
kubectl -n vault exec vault-0 -- vault operator unseal $(echo "$KEYS" | sed -n '1p')
kubectl -n vault exec vault-0 -- vault operator unseal $(echo "$KEYS" | sed -n '2p')
kubectl -n vault exec vault-0 -- vault operator unseal $(echo "$KEYS" | sed -n '3p')

Join and Unseal Other Nodes

# Join vault-1 to the Raft cluster
kubectl -n vault exec vault-1 -- vault operator raft join \
    http://vault-0.vault-internal:8200

# Unseal vault-1
kubectl -n vault exec vault-1 -- vault operator unseal $(echo "$KEYS" | sed -n '1p')
kubectl -n vault exec vault-1 -- vault operator unseal $(echo "$KEYS" | sed -n '2p')
kubectl -n vault exec vault-1 -- vault operator unseal $(echo "$KEYS" | sed -n '3p')

# Repeat for vault-2
kubectl -n vault exec vault-2 -- vault operator raft join \
    http://vault-0.vault-internal:8200

kubectl -n vault exec vault-2 -- vault operator unseal $(echo "$KEYS" | sed -n '1p')
kubectl -n vault exec vault-2 -- vault operator unseal $(echo "$KEYS" | sed -n '2p')
kubectl -n vault exec vault-2 -- vault operator unseal $(echo "$KEYS" | sed -n '3p')

Verify Cluster

# Check Raft peers
kubectl -n vault exec vault-0 -- vault operator raft list-peers

# Check status
kubectl -n vault exec vault-0 -- vault status

Access Vault

# Port forward the UI
kubectl -n vault port-forward svc/vault 8200:8200

# In another terminal
export VAULT_ADDR=http://127.0.0.1:8200
vault login $ROOT_TOKEN
vault status

TLS Setup

Create TLS certificates before deploying:

# Create TLS secret (use Vault PKI, cert-manager, or manual certs)
kubectl -n vault create secret generic vault-tls \
    --from-file=tls.crt=vault.crt \
    --from-file=tls.key=vault.key \
    --from-file=ca.crt=ca.crt

Quick Reference

Command Description
helm install vault hashicorp/vault ... Deploy Vault
helm upgrade vault hashicorp/vault ... Upgrade Vault
helm uninstall vault -n vault Remove Vault
kubectl -n vault exec vault-0 -- vault status Check Vault status

Next: Kubernetes Auth