# PushSecret dataTo Examples

This page provides practical examples of using the `dataTo` field in PushSecret to bulk-push secrets to external providers.

## Prerequisites

Before using these examples, ensure you have:

- External Secrets Operator installed in your cluster
- A configured SecretStore (or ClusterSecretStore)
- A source Kubernetes Secret with the data you want to push

## Example 1: Basic Database Credentials Push

Push all database-related secrets with organized naming.

**Source Secret:**
```yaml
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:**
```yaml
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/host`
- `myapp/production/database/port`
- `myapp/production/database/username`
- `myapp/production/database/password`
- `myapp/production/database/database`
- `myapp/production/database/ssl-mode`

## Example 2: Multi-Environment Configuration

Push the same secrets to different environments with different prefixes.

**Source Secret:**
```yaml
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:**
```yaml
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:**
```yaml
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/"
```

## Example 3: Organizing Secrets by Category

Push different types of secrets to organized paths.

**Source Secret:**
```yaml
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:**
```yaml
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/host`
- `config/database/password`
- `config/api/github-token`
- `config/api/stripe-key`
- `config/tls/cert`
- `config/tls/key`

## Example 4: Template Transformation

Use Go templates to transform key names with advanced logic.

**Source Secret:**
```yaml
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 %}
```yaml
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_KEY`
- `services/EMAIL_SERVICE_KEY`
- `services/STORAGE_SERVICE_KEY`

## Example 5: Chained Transformations

Apply multiple transformations sequentially for complex key restructuring.

**Source Secret:**
```yaml
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:**
```yaml
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/host`
- `migrated/db/replica/host`
- `migrated/cache/redis/url`

## Example 6: Override Specific Keys

Use both dataTo and explicit data to handle exceptions.

**Source Secret:**
```yaml
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:**
```yaml
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)

## Example 7: AWS Secrets Manager with Metadata

Push secrets with AWS-specific metadata tags.

**PushSecret with Metadata:**
```yaml
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
```

## Example 8: Vault with KV Version 2

Push secrets to HashiCorp Vault KV v2 engine with proper paths.

**Source Secret:**
```yaml
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:**
```yaml
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-key`
- `services/b/api-key`
- `shared/secret`

## Example 9: Azure Key Vault

Push secrets to Azure Key Vault with naming constraints (alphanumeric and hyphens only).

**PushSecret for Azure:**
```yaml
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-"
```

## Example 10: Migration from One Provider to Another

Backup secrets from AWS to GCP while maintaining structure.

**Step 1: Pull from AWS using ExternalSecret:**
```yaml
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:**
```yaml
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/"
```

## Troubleshooting

### Check PushSecret Status

```bash
kubectl get pushsecret <name> -n <namespace> -o yaml
```

Look for the `status.conditions` field for error messages.

### View Synced Secrets

```bash
kubectl get pushsecret <name> -n <namespace> -o jsonpath='{.status.syncedPushSecrets}' | jq
```

### Common Issues

**1. No keys matched:**

- Verify the source Secret has keys matching your pattern
- Check regexp syntax: `kubectl get secret <name> -o jsonpath='{.data}' | jq 'keys'`

**2. Invalid regexp error:**

- Validate your regexp using an online regexp tester
- Ensure special characters are properly escaped

**3. Duplicate remote keys:**

- Check if your rewrites produce unique keys
- Adjust patterns or use explicit data overrides

## Best Practices

1. **Start with match-all to verify**: Test with `dataTo: [{storeRef: {name: your-store}}]` first
2. **Test regexp patterns**: Use `kubectl get secret -o jsonpath='{.data}' | jq 'keys'`
3. **Use descriptive patterns**: Make regexp patterns self-documenting
4. **Monitor status**: Check PushSecret status after creation
5. **Version control**: Keep PushSecret manifests in git
6. **Document transformations**: Add comments explaining complex rewrites

## See Also

- [PushSecret dataTo Guide](../guides/pushsecret-datato.md)
- [PushSecret API Reference](../api/pushsecret.md)
- [Provider Documentation](../provider/)
