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
This commit is contained in:
co-authored by
Claude Opus 5
parent
4a5f4d94ab
commit
dcd3583656
@@ -0,0 +1,54 @@
|
|||||||
|
# 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
|
||||||
@@ -132,6 +132,27 @@ appSpec:
|
|||||||
namespace: postgres
|
namespace: postgres
|
||||||
chartDir: postgresql
|
chartDir: postgresql
|
||||||
valuesDir: postgresql
|
valuesDir: postgresql
|
||||||
|
- name: redis
|
||||||
|
# Backs toolshed's managed cache add-on — toolshed provisions a per-app
|
||||||
|
# ACL user, scoped to its own key prefix, on request. Own namespace for
|
||||||
|
# the same reason postgresql has one: addressed over cluster DNS like
|
||||||
|
# any other platform component, outliving whatever consumes it:
|
||||||
|
# redis.redis.svc.cluster.local:6379
|
||||||
|
#
|
||||||
|
# Hand-written chart, not Bitnami's, for the same reason as postgresql
|
||||||
|
# (infra issue #4) — Redis ships no official chart either.
|
||||||
|
#
|
||||||
|
# Authentication is defined by an ACL file with no requirepass, which
|
||||||
|
# is a security property rather than a preference: see the chart's own
|
||||||
|
# values.yaml, where getting it wrong leaves the server open to
|
||||||
|
# unauthenticated access after its first restart.
|
||||||
|
#
|
||||||
|
# Requires secretstores/toolshed-redis-credentials.yaml to have synced
|
||||||
|
# first — the init container cannot seed the ACL file without it.
|
||||||
|
nameOverride: redis
|
||||||
|
namespace: redis
|
||||||
|
chartDir: redis
|
||||||
|
valuesDir: redis
|
||||||
- name: victoria-metrics-single
|
- name: victoria-metrics-single
|
||||||
# Replaces the Prometheus server this entry briefly was (see git
|
# Replaces the Prometheus server this entry briefly was (see git
|
||||||
# history on this file) — same job, lower RAM/disk footprint for the
|
# history on this file) — same job, lower RAM/disk footprint for the
|
||||||
|
|||||||
Reference in New Issue
Block a user