Skip to content

Secrets: ExternalSecret and ExternalName

Tested with: External Secrets Operator 0.10 · AWS Secrets Manager · HashiCorp Vault 1.17 · Kubernetes 1.31

Never commit a database password to a repository, even encrypted. Put it in your secret manager, sync it with External Secrets Operator (ESO), and let rotation flow through refreshInterval.

After zb instances credentials reveal <id> or a rotation, write the pieces to your secret manager as one JSON secret:

databasezy/pg-prod (secret value)
{ "host": "pg-7f3k.us-east.databasezy.com", "port": "5432", "username": "app", "password": "...", "database": "app" }
secretstore-aws.yaml
apiVersion: external-secrets.io/v1
kind: ClusterSecretStore
metadata:
name: aws-secrets
spec:
provider:
aws:
service: SecretsManager
region: us-east-1
auth:
jwt:
serviceAccountRef:
name: external-secrets
namespace: external-secrets # IRSA-annotated service account
externalsecret-pg-prod.yaml
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: zb-pg-prod
namespace: app
spec:
refreshInterval: 5m # picks up rotations within the dual-valid window
secretStoreRef:
kind: ClusterSecretStore
name: aws-secrets
target:
name: zb-pg-prod
creationPolicy: Owner
template:
type: Opaque
data:
host: "{{ .host }}"
port: "{{ .port }}"
username: "{{ .username }}"
password: "{{ .password }}"
database: "{{ .database }}"
# Convenience URL for frameworks that want a single variable:
DATABASE_URL: "postgresql://{{ .username }}:{{ .password }}@{{ .host }}:{{ .port }}/{{ .database }}?sslmode=verify-full&sslrootcert=/etc/databasezy/ca.crt"
dataFrom:
- extract:
key: databasezy/pg-prod

Pods do not reload environment variables on their own. Either use Reloader (reloader.stakater.com/auto: "true" on the Deployment) or mount the Secret as files and have the app re-read them.

pg-prod-service.yaml
apiVersion: v1
kind: Service
metadata:
name: pg-prod
namespace: app
spec:
type: ExternalName
externalName: pg-7f3k.us-east.databasezy.com
ports:
- { name: postgres, port: 5432 }

Kubernetes Secrets vs sealed/encrypted files

Section titled “Kubernetes Secrets vs sealed/encrypted files”

Sealed Secrets and SOPS work too and are fine for small teams; you lose automatic rotation and the audit trail of the secret manager. Whatever you use, the password key should never appear in Git history in plaintext.