This page provides practical examples of using the dataTo field in PushSecret to bulk-push secrets to external providers.
Before using these examples, ensure you have:
Push all database-related secrets with organized naming.
Source Secret:
apiVersion: v1
kind: Secret
metadata:
name: db-credentials
namespace: myapp
type: Opaque
stringData:
db-host: "prod-db.example.com"
db-port: "5432"
db-username: "app_user"
db-password: "super-secret-password"
db-database: "myapp_db"
db-ssl-mode: "require"
PushSecret with dataTo:
apiVersion: external-secrets.io/v1alpha1
kind: PushSecret
metadata:
name: push-db-credentials
namespace: myapp
spec:
refreshInterval: 1h
secretStoreRefs:
- name: aws-secrets-manager
kind: SecretStore
selector:
secret:
name: db-credentials
dataTo:
- storeRef:
name: aws-secrets-manager
match:
regexp: "^db-.*"
rewrite:
- regexp:
source: "^db-"
target: "myapp/production/database/"
Result in AWS Secrets Manager:
myapp/production/database/hostmyapp/production/database/portmyapp/production/database/usernamemyapp/production/database/passwordmyapp/production/database/databasemyapp/production/database/ssl-modePush the same secrets to different environments with different prefixes.
Source Secret:
apiVersion: v1
kind: Secret
metadata:
name: app-config
namespace: myapp
type: Opaque
stringData:
api-key: "abc123xyz"
api-secret: "secret456"
redis-url: "redis://cache:6379"
postgres-url: "postgres://db:5432/mydb"
Development Environment:
apiVersion: external-secrets.io/v1alpha1
kind: PushSecret
metadata:
name: push-dev-config
namespace: myapp
spec:
secretStoreRefs:
- name: vault-dev
selector:
secret:
name: app-config
dataTo:
- storeRef:
name: vault-dev
rewrite:
- regexp:
source: "^"
target: "dev/myapp/"
Production Environment:
apiVersion: external-secrets.io/v1alpha1
kind: PushSecret
metadata:
name: push-prod-config
namespace: myapp
spec:
secretStoreRefs:
- name: vault-prod
selector:
secret:
name: app-config
dataTo:
- storeRef:
name: vault-prod
rewrite:
- regexp:
source: "^"
target: "prod/myapp/"
Push different types of secrets to organized paths.
Source Secret:
apiVersion: v1
kind: Secret
metadata:
name: mixed-secrets
namespace: myapp
type: Opaque
stringData:
db-host: "database.local"
db-password: "dbpass"
api-github-token: "ghp_xxx"
api-stripe-key: "sk_live_xxx"
tls-cert: "-----BEGIN CERTIFICATE-----"
tls-key: "-----BEGIN PRIVATE KEY-----"
PushSecret with Multiple Patterns:
apiVersion: external-secrets.io/v1alpha1
kind: PushSecret
metadata:
name: organize-secrets
namespace: myapp
spec:
secretStoreRefs:
- name: vault-store
selector:
secret:
name: mixed-secrets
dataTo:
# Database credentials -> config/database/*
- storeRef:
name: vault-store
match:
regexp: "^db-.*"
rewrite:
- regexp:
source: "^db-"
target: "config/database/"
# API keys -> config/api/*
- storeRef:
name: vault-store
match:
regexp: "^api-.*"
rewrite:
- regexp:
source: "^api-"
target: "config/api/"
# TLS certificates -> config/tls/*
- storeRef:
name: vault-store
match:
regexp: "^tls-.*"
rewrite:
- regexp:
source: "^tls-"
target: "config/tls/"
Result:
config/database/hostconfig/database/passwordconfig/api/github-tokenconfig/api/stripe-keyconfig/tls/certconfig/tls/keyUse Go templates to transform key names with advanced logic.
Source Secret:
apiVersion: v1
kind: Secret
metadata:
name: service-keys
namespace: myapp
type: Opaque
stringData:
payment-gateway-key: "pk_xxx"
email-service-key: "es_xxx"
storage-service-key: "ss_xxx"
PushSecret with Template: {% raw %}
apiVersion: external-secrets.io/v1alpha1
kind: PushSecret
metadata:
name: push-service-keys
namespace: myapp
spec:
secretStoreRefs:
- name: gcp-secret-manager
selector:
secret:
name: service-keys
dataTo:
- storeRef:
name: gcp-secret-manager
rewrite:
- transform:
template: "services/{{ .value | upper | replace \"-\" \"_\" }}"
{% endraw %}
Result:
services/PAYMENT_GATEWAY_KEYservices/EMAIL_SERVICE_KEYservices/STORAGE_SERVICE_KEYApply multiple transformations sequentially for complex key restructuring.
Source Secret:
apiVersion: v1
kind: Secret
metadata:
name: legacy-secrets
namespace: myapp
type: Opaque
stringData:
old-db-primary-host: "db1.old.local"
old-db-replica-host: "db2.old.local"
old-cache-redis-url: "redis://old-cache:6379"
PushSecret with Chained Rewrites:
apiVersion: external-secrets.io/v1alpha1
kind: PushSecret
metadata:
name: migrate-legacy-secrets
namespace: myapp
spec:
secretStoreRefs:
- name: aws-secrets-manager
selector:
secret:
name: legacy-secrets
dataTo:
- storeRef:
name: aws-secrets-manager
rewrite:
# First: Remove "old-" prefix
- regexp:
source: "^old-"
target: ""
# Second: Add "migrated/" prefix
- regexp:
source: "^"
target: "migrated/"
# Third: Replace hyphens with slashes for hierarchy
- regexp:
source: "-"
target: "/"
Result:
migrated/db/primary/hostmigrated/db/replica/hostmigrated/cache/redis/urlUse both dataTo and explicit data to handle exceptions.
Source Secret:
apiVersion: v1
kind: Secret
metadata:
name: app-secrets
namespace: myapp
type: Opaque
stringData:
db-host: "database.local"
db-port: "5432"
db-user: "app"
db-password: "secret123"
db-admin-password: "admin-secret" # Should go to different location
PushSecret with Override:
apiVersion: external-secrets.io/v1alpha1
kind: PushSecret
metadata:
name: push-with-override
namespace: myapp
spec:
secretStoreRefs:
- name: vault-store
selector:
secret:
name: app-secrets
# Push all db-* keys to app/database/*
dataTo:
- storeRef:
name: vault-store
match:
regexp: "^db-.*"
rewrite:
- regexp:
source: "^db-"
target: "app/database/"
# Except db-admin-password which goes to admin/
data:
- match:
secretKey: db-admin-password
remoteRef:
remoteKey: admin/database/password
Result:
app/database/host (from dataTo)app/database/port (from dataTo)app/database/user (from dataTo)app/database/password (from dataTo)admin/database/password (from explicit data override)Push secrets with AWS-specific metadata tags.
PushSecret with Metadata:
apiVersion: external-secrets.io/v1alpha1
kind: PushSecret
metadata:
name: push-with-aws-tags
namespace: myapp
spec:
secretStoreRefs:
- name: aws-secrets-manager
selector:
secret:
name: app-config
dataTo:
- storeRef:
name: aws-secrets-manager
match:
regexp: "^prod-.*"
rewrite:
- regexp:
source: "^prod-"
target: "myapp/prod/"
metadata:
tags:
- key: Environment
value: production
- key: Application
value: myapp
- key: ManagedBy
value: external-secrets-operator
Push secrets to HashiCorp Vault KV v2 engine with proper paths.
Source Secret:
apiVersion: v1
kind: Secret
metadata:
name: vault-secrets
namespace: myapp
type: Opaque
stringData:
service-a-key: "key-a"
service-b-key: "key-b"
shared-secret: "shared"
PushSecret for Vault:
apiVersion: external-secrets.io/v1alpha1
kind: PushSecret
metadata:
name: push-to-vault
namespace: myapp
spec:
secretStoreRefs:
- name: vault-kv-v2
selector:
secret:
name: vault-secrets
dataTo:
# Service-specific secrets
- storeRef:
name: vault-kv-v2
match:
regexp: "^service-.*-key$"
rewrite:
- regexp:
source: "^service-(.*)-key$"
target: "services/$1/api-key" # Use capture group
# Shared secrets
- storeRef:
name: vault-kv-v2
match:
regexp: "^shared-.*"
rewrite:
- regexp:
source: "^shared-"
target: "shared/"
Result:
services/a/api-keyservices/b/api-keyshared/secretPush secrets to Azure Key Vault with naming constraints (alphanumeric and hyphens only).
PushSecret for Azure:
apiVersion: external-secrets.io/v1alpha1
kind: PushSecret
metadata:
name: push-to-azure
namespace: myapp
spec:
secretStoreRefs:
- name: azure-key-vault
selector:
secret:
name: app-secrets
dataTo:
- storeRef:
name: azure-key-vault
rewrite:
# Azure Key Vault only allows alphanumeric and hyphens
# Convert underscores to hyphens
- regexp:
source: "_"
target: "-"
# Add prefix
- regexp:
source: "^"
target: "myapp-"
Backup secrets from AWS to GCP while maintaining structure.
Step 1: Pull from AWS using ExternalSecret:
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: pull-from-aws
namespace: backup
spec:
refreshInterval: 1h
secretStoreRef:
name: aws-secrets-manager
target:
name: aws-backup-secrets
dataFrom:
- find:
name:
regexp: "^myapp/.*"
Step 2: Push to GCP with dataTo:
apiVersion: external-secrets.io/v1alpha1
kind: PushSecret
metadata:
name: backup-to-gcp
namespace: backup
spec:
secretStoreRefs:
- name: gcp-secret-manager
selector:
secret:
name: aws-backup-secrets
dataTo:
- storeRef:
name: gcp-secret-manager
rewrite:
# Maintain structure but add backup prefix
- regexp:
source: "^"
target: "backup-from-aws/"
kubectl get pushsecret <name> -n <namespace> -o yaml
Look for the status.conditions field for error messages.
kubectl get pushsecret <name> -n <namespace> -o jsonpath='{.status.syncedPushSecrets}' | jq
1. No keys matched:
kubectl get secret <name> -o jsonpath='{.data}' | jq 'keys'2. Invalid regexp error:
3. Duplicate remote keys:
dataTo: [{storeRef: {name: your-store}}] firstkubectl get secret -o jsonpath='{.data}' | jq 'keys'