174 lines
7.9 KiB
YAML
174 lines
7.9 KiB
YAML
# k8s/talos-iam/vault-values.yaml
|
|
# HashiCorp Vault — secrets backend for the homelab.
|
|
# Stores OIDC client secrets, TLS certs, and any other sensitive values.
|
|
# Accessed via the `talos` CLI (talos-cli/) which wraps `vault kv get/put`.
|
|
#
|
|
# Storage backend: MinIO S3 (minio.storage.svc.cluster.local) — no extra PVC.
|
|
# Auto-unseal: postStart hook reads unseal keys from vault-unseal-keys Secret
|
|
# (written by setup_vault.sh after operator init; operator must run that script
|
|
# once after first install to initialize and store the keys).
|
|
|
|
# ── Global ────────────────────────────────────────────────────────────────────
|
|
# tlsDisable: true — TLS terminated at the nginx ingress (vault.riotpiao.com)
|
|
# or at port-forward. In-cluster traffic to Vault is plain HTTP; this is acceptable
|
|
# because all clients are on the pod network (not crossing node boundaries).
|
|
global:
|
|
enabled: true
|
|
tlsDisable: true
|
|
|
|
# ── Agent Injector ────────────────────────────────────────────────────────────
|
|
# The injector mutates pods to sidecar Vault Agent for automatic secret injection.
|
|
# Not used here — secrets are fetched explicitly via the talos CLI.
|
|
# Enabling it would add a webhook that intercepts all pod creates cluster-wide,
|
|
# which is unnecessary overhead for a homelab with manual secret management.
|
|
injector:
|
|
enabled: false
|
|
|
|
server:
|
|
replicas: 1
|
|
|
|
annotations:
|
|
secret.reloader.stakater.com/reload: "vault-unseal-keys"
|
|
|
|
resources:
|
|
requests:
|
|
cpu: 100m
|
|
memory: 256Mi
|
|
limits:
|
|
cpu: 500m
|
|
memory: 512Mi
|
|
|
|
# ── Scheduling ─────────────────────────────────────────────────────────────
|
|
# Tolerate cp-1 so Vault can run there if worker-1 is down.
|
|
# Prefer worker-1 under normal conditions (keeps Vault off the same node as etcd).
|
|
tolerations:
|
|
- key: node-role.kubernetes.io/control-plane
|
|
operator: Exists
|
|
effect: NoSchedule
|
|
|
|
affinity:
|
|
nodeAffinity:
|
|
preferredDuringSchedulingIgnoredDuringExecution:
|
|
- weight: 100
|
|
preference:
|
|
matchExpressions:
|
|
- key: node-role.kubernetes.io/worker
|
|
operator: Exists
|
|
|
|
# ── Environment variables ───────────────────────────────────────────────────
|
|
# extraEnvironmentVars: non-secret config passed directly.
|
|
extraEnvironmentVars:
|
|
VAULT_LOG_LEVEL: info
|
|
|
|
# extraSecretEnvironmentVars: pulls values from K8s Secrets into env vars.
|
|
# vault-minio-creds is created by the helmfile presync hook from MINIO_ROOT_USER/PASSWORD.
|
|
# vault-unseal-keys is a placeholder created at first deploy; setup_vault.sh
|
|
# overwrites it with real unseal keys after `vault operator init`.
|
|
# Vault reads the keys from env on every pod start and the postStart hook unseals.
|
|
extraSecretEnvironmentVars:
|
|
- envName: AWS_ACCESS_KEY_ID
|
|
secretName: vault-minio-creds
|
|
secretKey: access_key
|
|
- envName: AWS_SECRET_ACCESS_KEY
|
|
secretName: vault-minio-creds
|
|
secretKey: secret_key
|
|
- envName: VAULT_UNSEAL_KEY_1
|
|
secretName: vault-unseal-keys
|
|
secretKey: key1
|
|
- envName: VAULT_UNSEAL_KEY_2
|
|
secretName: vault-unseal-keys
|
|
secretKey: key2
|
|
- envName: VAULT_UNSEAL_KEY_3
|
|
secretName: vault-unseal-keys
|
|
secretKey: key3
|
|
|
|
# ── Auto-unseal ─────────────────────────────────────────────────────────────
|
|
# Vault starts sealed after every pod restart and can't serve requests until
|
|
# unsealed. postStart runs immediately after the container starts, sleeps 5s
|
|
# to let the Vault process bind its port, then feeds the unseal keys one by one.
|
|
# `|| true` prevents the hook from failing if a key was already used (idempotent).
|
|
# 3-of-5 Shamir unseal is the default — we stored all 3 used keys in the Secret.
|
|
postStart:
|
|
- /bin/sh
|
|
- -c
|
|
- |
|
|
sleep 5
|
|
vault operator unseal "$VAULT_UNSEAL_KEY_1" || true
|
|
vault operator unseal "$VAULT_UNSEAL_KEY_2" || true
|
|
vault operator unseal "$VAULT_UNSEAL_KEY_3" || true
|
|
|
|
# ── Vault config (HCL) ──────────────────────────────────────────────────────
|
|
standalone:
|
|
enabled: true
|
|
config: |
|
|
ui = false # UI served via Vault's own HTTP; enabled below via ui: enabled: true
|
|
|
|
listener "tcp" {
|
|
address = "0.0.0.0:8200"
|
|
tls_disable = "true"
|
|
|
|
# No auth in front of Vault's metrics endpoint — acceptable since all
|
|
# Prometheus scrape traffic stays on the pod network (not exposed via ingress).
|
|
telemetry {
|
|
unauthenticated_metrics_access = "true"
|
|
}
|
|
}
|
|
|
|
telemetry {
|
|
prometheus_retention_time = "30s"
|
|
disable_hostname = true
|
|
}
|
|
|
|
# S3 storage backend pointing at the in-cluster MinIO service.
|
|
# AWS_ env vars (from vault-minio-creds Secret) supply the credentials.
|
|
# s3_force_path_style: MinIO uses path-style URLs (not virtual-hosted).
|
|
# disable_ssl: MinIO in this cluster has no TLS.
|
|
storage "s3" {
|
|
max_parallel = 128
|
|
s3_session_timeout = "5s" endpoint = "http://minio.storage.svc.cluster.local"
|
|
bucket = "vault"
|
|
region = "us-east-1"
|
|
s3_force_path_style = "true"
|
|
disable_ssl = "true"
|
|
}
|
|
|
|
# api_addr: the address other Vault nodes (or HA standbys) use to reach
|
|
# this node. Single-node standalone, but Vault requires it to be set.
|
|
api_addr = "http://vault.storage.svc.cluster.local:8200"
|
|
|
|
# ── Service ─────────────────────────────────────────────────────────────────
|
|
# NodePort 32171 — fallback for direct node access during bootstrap before
|
|
# the ingress is up. Normal access is via nginx ingress (vault.riotpiao.com).
|
|
service:
|
|
type: NodePort
|
|
port: 8200
|
|
nodePort: 32171
|
|
|
|
# ── Persistence ─────────────────────────────────────────────────────────────
|
|
# No PVC — all Vault state (secrets, policies, tokens) is stored in MinIO S3.
|
|
# This means Vault survives node loss as long as MinIO is healthy.
|
|
dataStorage:
|
|
enabled: false
|
|
|
|
auditStorage:
|
|
enabled: false
|
|
|
|
# ── UI ────────────────────────────────────────────────────────────────────────
|
|
# Vault's web UI is used for the OIDC browser login flow (Vault as an OIDC
|
|
# provider, if configured) and for manual operator inspection.
|
|
# Accessible at http://vault.riotpiao.com or via port-forward.
|
|
ui:
|
|
enabled: true
|
|
|
|
# ── Metrics ───────────────────────────────────────────────────────────────────
|
|
# vault_core_unsealed is the availability signal (0 after a restart until the
|
|
# postStart hook above finishes unsealing). Pairs with the telemetry{} stanzas
|
|
# in standalone.config above, which actually turn the /v1/sys/metrics endpoint on.
|
|
serverTelemetry:
|
|
serviceMonitor:
|
|
enabled: true
|
|
selectors: {}
|
|
interval: 30s
|
|
scrapeTimeout: 10s
|
|
|