Skip to content

Hashicorp Vault - Desplegar instancia en k8s vía helm.

Introducción

Despliegue de una instancia de Hashicorp Vault utilizando helm chart oficial.

Crear ambiente en k8s

Crear ambiente en minikube

minikube start --addons=ingress --ports=80:80,443:443

Agregar repositorio oficial a las configuraciones de Helm

helm repo add hashicorp https://helm.releases.hashicorp.com
Desplegar con values
helm install --values values.yaml --create-namespace --namespace vault vault hashicorp/vault
Actualizar
helm upgrade --namespace vault --install vault hashicorp/vault -f values.yaml
Eliminar
helm uninstall vault --namespace vault

Inicializar pods

Ejemplo:

image.png

El pod vault-0 no esta ready, ya que la instancia esta configurada como productiva, por lo que falta inicializar:

kubectl exec vault-0 -n vault -- vault operator init -key-shares=1 -key-threshold=1 -format=json > cluster-keys.json
Capturar el valor de unseal key
VAULT_UNSEAL_KEY=$(cat cluster-keys.json | jq -r ".unseal_keys_b64[]")
Unseal Vault
kubectl exec vault-0 -n vault -- vault operator unseal $VAULT_UNSEAL_KEY
image.png

vault cli

Instalación

Documentación Oficial: https://developer.hashicorp.com/vault/install

wget -O - [https://apt.releases.hashicorp.com/gpg](https://apt.releases.hashicorp.com/gpg) | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] [https://apt.releases.hashicorp.com](https://apt.releases.hashicorp.com/) $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
sudo apt update && sudo apt install vault

export VAULT_ADDR="https://vault.homelab.prod"

La autenticación al servidor se puede realizar mediante:

  1. Asignando la variable VAULT_TOKEN
    export VAULT_TOKEN="my_vault_token"
    
  2. Con el pasaje del argumento:
    vault login my_vault_token
    

Comandos útiles

Mostrar estado

vault status
Ejemplo salida de ejecución

Ejemplo salida de ejecución

Mostrar mecanismos de autenticaciones disponibles

vault auth list
Ejemplo salida de ejecución

Ejemplo salida de ejecución

Crear secreto en engine kv (key-value)

vault kv put kv/hello foo=world
Ejemplo salida de ejecución

Ejemplo salida de ejecución

Obtener secreto de engine kv

vault kv get kv/hello
Ejemplo salida de ejecución

Ejemplo salida de ejecución

Agregar autenticación con oidc (keycloak)

vault write auth/oidc/role/default allowed_redirect_uris="[https://vault.homelab.prod/oidc/oidc/callback](https://vault.homelab.prod/oidc/oidc/callback)" allowed_redirect_uris="[https://vault.homelab.prod/ui/vault/auth/oidc/oidc/callback](https://vault.homelab.prod/ui/vault/auth/oidc/oidc/callback)" user_claim="sub" policoes="default" groups_claim="groups"

Ejemplos

Consumir secretos desde python

import hvac
import sys

# Authentication
client = hvac.Client(
    url=VAULT_ADDR,
    token=VAULT_TOKEN,
)

if client.is_authenticated():
    print("✅ Autenticado con éxito en Vault")
else:
    raise Exception("❌ Falló la autenticación en Vault")

# Leer un secreto
secret_path = 'homelab.prod/js7/homelab-automation/data/mysqldb'  # secreto DB

try:
    secret_response = client.secrets.kv.v1.read_secret(path=secret_path,mount_point='kv/data')
    print("🔑 Secreto obtenido:", secret_response['data']['data'])

except hvac.exceptions.InvalidPath as e:
    print("❌ Ruta inválida. ¿Seguro que estás usando KV v1?")
except Exception as e:
    print(f"❌ Error al leer el secreto: {e}")

Salida de ejecución:

image.png

Extras

Cambiar backend storage a postgres

Documentación Oficial: https://developer.hashicorp.com/vault/docs/configuration/storage/postgresql

Luego de crear la base de datos en Postgres, se crean manualmente las tablas e índices indicadas en la documentación oficial.

CREATE TABLE vault_kv_store (
    parent_path TEXT COLLATE "C" NOT NULL,
    path        TEXT COLLATE "C",
    key         TEXT COLLATE "C",
    value       BYTEA,
    CONSTRAINT pkey PRIMARY KEY (path, key)
);

CREATE INDEX parent_path_idx ON vault_kv_store (parent_path);

Y en el values.yaml se indica que va a utilizar el backend storage en conjunto con la cadena de conexión

Ejemplo:

image.png

Cadena de conexión:postgresql://<USERNAME>:<PASSWORD>@<HOST>:5432/<DB_NAME>?sslmode=disable