# Copies the CNPG-generated temporal-db-role Secret from the ddb namespace # into the temporal namespace, as a plain (non-SOPS) k8s Secret with the same # keys. Kubernetes Secrets are strictly namespace-scoped - a Deployment in # `temporal` cannot reference a Secret living in `ddb` via secretKeyRef, and # temporal-values.yaml's server.config.persistence.*.sql.existingSecret: # temporal-db-role expects to find it in ITS OWN namespace (temporal). # # Deliberately a standalone directory (no kustomization.yaml) applied as its # own small Application - avoids the k8s/applications/temporal/kustomization.yaml # `namespace: temporal` transformer, which would silently force-rewrite this # Job's ddb-scoped RoleBinding back to temporal (same class of bug fixed # earlier in k8s/security/iam/kustomization.yaml - see that file's comments). # # PreSync + BeforeHookCreation: reruns on every ArgoCD sync of the temporal # app group, so it re-copies the password if CNPG ever rotates it. Runs # before the main `temporal` Application (sync-wave 8) since this app is # registered at sync-wave 7. apiVersion: v1 kind: ServiceAccount metadata: name: temporal-db-secret-sync namespace: temporal --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: temporal-db-secret-sync rules: - apiGroups: [""] resources: ["secrets"] verbs: ["get", "list", "create", "update", "patch"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: temporal-db-secret-sync namespace: ddb subjects: - kind: ServiceAccount name: temporal-db-secret-sync namespace: temporal roleRef: kind: ClusterRole name: temporal-db-secret-sync apiGroup: rbac.authorization.k8s.io --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: temporal-db-secret-sync namespace: temporal subjects: - kind: ServiceAccount name: temporal-db-secret-sync namespace: temporal roleRef: kind: ClusterRole name: temporal-db-secret-sync apiGroup: rbac.authorization.k8s.io --- apiVersion: batch/v1 kind: Job metadata: name: temporal-db-secret-sync namespace: temporal annotations: argocd.argoproj.io/hook: PreSync argocd.argoproj.io/hook-delete-policy: BeforeHookCreation spec: ttlSecondsAfterFinished: 600 backoffLimit: 5 template: spec: serviceAccountName: temporal-db-secret-sync restartPolicy: Never securityContext: runAsNonRoot: true runAsUser: 1000 seccompProfile: type: RuntimeDefault containers: - name: copy image: bitnami/kubectl:1.30 securityContext: allowPrivilegeEscalation: false capabilities: drop: ["ALL"] command: - /bin/sh - -c - | set -e echo "waiting for ddb/temporal-db-role..." until kubectl -n ddb get secret temporal-db-role >/dev/null 2>&1; do echo " not ready yet, retrying..." sleep 5 done USERNAME=$(kubectl -n ddb get secret temporal-db-role -o jsonpath='{.data.username}' | base64 -d) PASSWORD=$(kubectl -n ddb get secret temporal-db-role -o jsonpath='{.data.password}' | base64 -d) kubectl -n temporal create secret generic temporal-db-role \ --from-literal=username="$USERNAME" \ --from-literal=password="$PASSWORD" \ --dry-run=client -o yaml | kubectl apply -f - echo "synced temporal-db-role -> temporal namespace"