Files
Mukul SharmaandClaude Opus 5 dcd3583656 Deploy Redis, backing toolshed's managed cache add-on
Registers the new hand-written redis chart (devops-infra-helm-charts,
separate commit) and the ExternalSecret feeding its admin password from
Vault. Own namespace, addressed over cluster DNS like every other platform
component here:

  redis.redis.svc.cluster.local:6379

Only one consumer for the credential, unlike the Postgres one next door:
the server itself, to seed its ACL file on first boot. toolshed's api gets
it from the connection an operator configures in the dashboard, encrypted
in toolshed's own database — so there is deliberately no second
ExternalSecret into the toolshed namespace.

Order matters: put the password in Vault at secret/toolshed/redis before
syncing, or the init container sits in CreateContainerConfigError. The
exact command, the reason the password must be alphanumeric (it is written
into an ACL directive where a space or quote would split it), and the
manual rotation procedure are all recorded in the ExternalSecret's own
header.

Nothing here needs to change for Postgres: toolshed's managed database
add-on points at the existing postgresql.postgres.svc.cluster.local, whose
POSTGRES_USER is the initdb superuser and so already has the CREATEDB and
CREATEROLE that provisioning needs.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Wajog7nELA3i8JWTjxYGHF
2026-09-09 12:35:46 +05:30

55 lines
2.1 KiB
YAML

# Redis admin password, backing toolshed's managed cache add-on.
#
# Only one consumer, unlike the Postgres credential next door: the Redis
# server itself needs it to seed its ACL file on first boot. toolshed's api
# reads it from the *connection* an operator configures in the dashboard
# (encrypted in toolshed's own database via the secretbox keyring), not from
# a Kubernetes Secret — so there is deliberately no second ExternalSecret
# into the toolshed namespace here.
#
# Put the credential in Vault BEFORE syncing this. External Secrets cannot
# create a Secret for a path that does not exist, and the Redis pod's init
# container will sit in CreateContainerConfigError until it can:
#
# kubectl -n vault exec -i vault-0 -- sh -lc '
# vault login <root-token> >/dev/null &&
# vault kv put secret/toolshed/redis \
# password=<a long alphanumeric password>'
#
# Use an alphanumeric password. It is written into the ACL file as
# `user default on ><password> ...` by the init container, where a space or
# a quote would split the directive and produce a server that either fails
# to start or, worse, starts with different rules than intended.
#
# Remember that `kubectl exec` into Vault is unauthenticated by default —
# without the `vault login` the commands fail with a "preflight capability
# check" error that reads like a permissions bug rather than a missing
# login.
#
# Rotating this password later does NOT propagate to a running server: the
# init container only ever writes the ACL file when it is absent, precisely
# so it cannot delete the per-app users toolshed has provisioned into it.
# To rotate, update Vault and then, against the running server:
#
# ACL SETUSER default >newpassword
# ACL SAVE
---
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: redis-credentials
namespace: redis
spec:
refreshInterval: 1h
secretStoreRef:
name: vault-backend
kind: ClusterSecretStore
target:
name: redis-credentials
creationPolicy: Owner
data:
- secretKey: password
remoteRef:
key: toolshed/redis
property: password