Configuración y Secretos
Variables de entorno, config maps, gestión segura de secretos y herramientas como Vault para proteger datos sensibles.
El principio: separar configuración del código
Una de las reglas fundamentales del despliegue moderno es que la configuración no debe vivir en el código. El mismo artefacto (imagen Docker, binario, bundle) debe poder ejecutarse en cualquier entorno — lo único que cambia es la configuración.
Esto incluye:
- URLs de bases de datos y servicios externos
- Credenciales y tokens de acceso
- Feature flags y parámetros de comportamiento
- Niveles de logging y timeouts
- Claves de API de terceros
Variables de entorno
Las variables de entorno son el mecanismo más básico y universal para inyectar configuración en una aplicación.
Ventajas
- Soportadas por todos los lenguajes y plataformas
- Fáciles de configurar en contenedores, CI/CD y cloud providers
- No requieren librerías adicionales
Buenas prácticas
# Nombres descriptivos en UPPER_SNAKE_CASE
DATABASE_URL=postgres://user:pass@host:5432/db
REDIS_URL=redis://localhost:6379
LOG_LEVEL=info
API_TIMEOUT_MS=5000
FEATURE_NEW_CHECKOUT=true
- Usar un archivo
.env.exampleen el repositorio documentando todas las variables necesarias (sin valores reales) - Nunca commitear archivos
.envcon valores reales - Validar las variables al arrancar la aplicación — fallar rápido si falta alguna requerida
Validación al inicio
function validateEnv() {
const required = ['DATABASE_URL', 'REDIS_URL', 'JWT_SECRET'];
const missing = required.filter(key => !process.env[key]);
if (missing.length > 0) {
throw new Error(`Missing env vars: ${missing.join(', ')}`);
}
}
ConfigMaps en Kubernetes
En Kubernetes, los ConfigMaps permiten almacenar configuración no sensible como pares clave-valor y montarlos en los pods.
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
LOG_LEVEL: "info"
API_TIMEOUT: "30s"
MAX_CONNECTIONS: "100"
FEATURE_FLAGS: |
{
"newCheckout": true,
"darkMode": false
}
Inyectar como variables de entorno
spec:
containers:
- name: my-app
envFrom:
- configMapRef:
name: app-config
Montar como archivo
spec:
containers:
- name: my-app
volumeMounts:
- name: config-volume
mountPath: /app/config
volumes:
- name: config-volume
configMap:
name: app-config
Gestión de secretos
Los secretos (contraseñas, tokens, claves privadas) requieren un tratamiento especial. Nunca deben estar en:
- El código fuente
- Archivos de configuración commiteados
- Logs de la aplicación
- Imágenes Docker
Kubernetes Secrets
Kubernetes ofrece un recurso Secret para datos sensibles:
apiVersion: v1
kind: Secret
metadata:
name: app-secrets
type: Opaque
stringData:
DATABASE_PASSWORD: "mi-password-seguro"
JWT_SECRET: "mi-jwt-secret"
API_KEY: "mi-api-key"
Limitación importante: los Secrets de Kubernetes se almacenan en etcd codificados en base64, pero no están encriptados por defecto. Para mayor seguridad, habilitar encryption at rest o usar un gestor de secretos externo.
HashiCorp Vault
Vault es la herramienta más popular para gestión centralizada de secretos:
- Almacenamiento seguro: los secretos se encriptan en reposo
- Acceso controlado: políticas granulares de quién puede leer qué secretos
- Rotación automática: los secretos pueden rotarse sin redesplegar
- Auditoría: registro completo de quién accedió a qué secreto y cuándo
- Secretos dinámicos: genera credenciales temporales bajo demanda (ej: credenciales de DB que expiran en 1 hora)
Otras herramientas
- AWS Secrets Manager: gestión de secretos nativa en AWS con rotación automática
- Google Secret Manager: equivalente en GCP
- Azure Key Vault: equivalente en Azure
- SOPS: encripta archivos de configuración que se pueden commitear de forma segura
Rotación de secretos
Los secretos deben rotarse periódicamente para minimizar el impacto de una filtración:
- Generar nuevo secreto: crear la nueva credencial en el gestor de secretos
- Actualizar la aplicación: la aplicación lee el nuevo secreto (idealmente sin reinicio)
- Verificar funcionamiento: confirmar que todo funciona con el nuevo secreto
- Revocar el secreto anterior: eliminar la credencial antigua
Rotación sin downtime
Para rotar secretos sin downtime, la aplicación debe soportar dual credentials temporalmente:
- Aceptar tanto el secreto viejo como el nuevo durante un período de transición
- Una vez confirmado que todo funciona, revocar el viejo
Buenas prácticas generales
- Principio de mínimo privilegio: cada servicio solo accede a los secretos que necesita
- No loguear secretos: sanitizar los logs para que nunca muestren credenciales
- Encriptar en tránsito y en reposo: TLS para comunicación, encryption at rest para almacenamiento
- Auditar accesos: registrar quién accede a qué secretos y cuándo
- Automatizar la rotación: no depender de procesos manuales para rotar credenciales
- Separar configuración de secretos: la configuración no sensible va en ConfigMaps, los secretos en un gestor dedicado
Resumen
La configuración y los secretos son aspectos críticos del despliegue. Las variables de entorno y ConfigMaps manejan la configuración no sensible, mientras que herramientas como Vault, AWS Secrets Manager o Kubernetes Secrets protegen los datos sensibles. La clave es separar configuración del código, validar al inicio y rotar secretos periódicamente.