0ddb57f687
Vault is the source of truth for the sonarr/radarr/prowlarr API keys (override bootstrap): keys are minted in Vault and enforced into each app's /config/config.xml on startup, replacing the images' self-generated keys. - add a VaultAuth 'default' in the arrstack namespace (k8s auth, mount k8s/au/syd1, role default, SA default) mirroring the jellyfin pattern - add a per-app VaultStaticSecret syncing kv/kubernetes/namespace/arrstack/default/<app> (key apitoken) into the <app>-apikey Secret; the default k8s role's templated policy already grants read there, so no terraform-vault change is needed - add an apikey-init initContainer to each deployment that fails closed on a missing/non-hex key and writes/updates only the <ApiKey> element in /config/config.xml (busybox via artifactapi, runs as root) - wire the new manifests into the base and per-app kustomizations nzbget is out of scope (no config.xml <ApiKey>; uses ControlPassword).
116 lines
3.4 KiB
YAML
116 lines
3.4 KiB
YAML
---
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: prowlarr
|
|
namespace: arrstack
|
|
spec:
|
|
replicas: 1
|
|
strategy:
|
|
# RWO config PVC + single stateful SQLite DB: never run two pods at once.
|
|
type: Recreate
|
|
selector:
|
|
matchLabels:
|
|
app: prowlarr
|
|
template:
|
|
metadata:
|
|
labels:
|
|
app: prowlarr
|
|
spec:
|
|
securityContext:
|
|
fsGroup: 1000
|
|
fsGroupChangePolicy: OnRootMismatch
|
|
initContainers:
|
|
# Enforce the Vault-sourced API key in /config/config.xml before the app
|
|
# starts. Vault is source of truth (override bootstrap): the key is minted
|
|
# in Vault, synced by VSO into the prowlarr-apikey Secret, and written here.
|
|
# Runs as root to fix ownership; touches only the <ApiKey> element.
|
|
- name: apikey-init
|
|
image: artifactapi.k8s.syd1.au.unkin.net/dockerhub/library/busybox:1.37.0
|
|
imagePullPolicy: IfNotPresent
|
|
securityContext:
|
|
runAsUser: 0
|
|
env:
|
|
- name: API_KEY
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: prowlarr-apikey
|
|
key: apitoken
|
|
command:
|
|
- sh
|
|
- -c
|
|
- |
|
|
set -eu
|
|
case "$API_KEY" in
|
|
"" | *[!0-9a-fA-F]*)
|
|
echo "apikey-init: API_KEY missing or not hex; refusing" >&2
|
|
exit 1
|
|
;;
|
|
esac
|
|
CFG=/config/config.xml
|
|
if [ ! -f "$CFG" ]; then
|
|
printf '<Config>\n <ApiKey>%s</ApiKey>\n</Config>\n' "$API_KEY" > "$CFG"
|
|
elif grep -q '<ApiKey>' "$CFG"; then
|
|
sed -i "s|<ApiKey>[^<]*</ApiKey>|<ApiKey>${API_KEY}</ApiKey>|" "$CFG"
|
|
else
|
|
sed -i "s|<Config>|<Config>\n <ApiKey>${API_KEY}</ApiKey>|" "$CFG"
|
|
fi
|
|
chown 1000:1000 "$CFG"
|
|
chmod 600 "$CFG"
|
|
echo "apikey-init: <ApiKey> enforced from Vault"
|
|
resources:
|
|
requests:
|
|
cpu: 50m
|
|
memory: 32Mi
|
|
limits:
|
|
cpu: 200m
|
|
memory: 64Mi
|
|
volumeMounts:
|
|
- name: config
|
|
mountPath: /config
|
|
containers:
|
|
- name: prowlarr
|
|
image: artifactapi.k8s.syd1.au.unkin.net/dockerhub/linuxserver/prowlarr:2.5.2
|
|
imagePullPolicy: IfNotPresent
|
|
ports:
|
|
- name: http
|
|
containerPort: 9696
|
|
protocol: TCP
|
|
env:
|
|
- name: PUID
|
|
value: "1000"
|
|
- name: PGID
|
|
value: "1000"
|
|
- name: TZ
|
|
value: Australia/Sydney
|
|
livenessProbe:
|
|
httpGet:
|
|
path: /ping
|
|
port: http
|
|
initialDelaySeconds: 30
|
|
periodSeconds: 30
|
|
timeoutSeconds: 5
|
|
failureThreshold: 3
|
|
readinessProbe:
|
|
httpGet:
|
|
path: /ping
|
|
port: http
|
|
initialDelaySeconds: 10
|
|
periodSeconds: 10
|
|
timeoutSeconds: 5
|
|
failureThreshold: 3
|
|
resources:
|
|
requests:
|
|
cpu: 100m
|
|
memory: 256Mi
|
|
limits:
|
|
cpu: "1"
|
|
memory: 512Mi
|
|
volumeMounts:
|
|
- name: config
|
|
mountPath: /config
|
|
volumes:
|
|
- name: config
|
|
persistentVolumeClaim:
|
|
claimName: prowlarr-config
|