Secrets
The secrets resource type manages sensitive data like passwords, API keys, and certificates. Teabar can generate secrets automatically or fetch them from external secret managers.
Basic Usage
spec:
resources:
secrets:
- name: db-password
type: generated
spec:
length: 24 Schema Reference
secrets:
- name: string # Required: Secret identifier
type: string # Required: Secret type (generated, external, static)
enabled: boolean # Optional: Enable/disable this secret (default: true)
count: integer # Optional: Create multiple secrets with {{ .Index }}
spec: # Required: Type-specific configuration
# For 'generated' type
length: integer # Password length
charset: string # Character set (alphanumeric, alphanumeric-special, numeric, hex)
# For 'external' type
provider: string # External provider (vault, aws-secrets-manager, azure-keyvault)
path: string # Secret path in provider
key: string # Specific key within secret
# For 'static' type
value: string # Static secret value (use sparingly!)
dependsOn: # Optional: Resource dependencies
- string Secret Types
Generated Secrets
Automatically generate secure random secrets:
secrets:
# Basic password
- name: admin-password
type: generated
spec:
length: 24
charset: alphanumeric
# Complex password with special characters
- name: db-password
type: generated
spec:
length: 32
charset: alphanumeric-special
# Numeric PIN
- name: access-code
type: generated
spec:
length: 6
charset: numeric
# Hex string (for tokens, keys)
- name: api-token
type: generated
spec:
length: 64
charset: hex Character Sets:
| Charset | Characters | Example |
|---|---|---|
alphanumeric | a-zA-Z0-9 | K7mPx2nQw9 |
alphanumeric-special | a-zA-Z0-9!@#$%^&* | K7m!Px@2n# |
numeric | 0-9 | 847291 |
hex | 0-9a-f | a7f3c2e1 |
External Secrets
Fetch secrets from external secret managers:
secrets:
- name: api-credentials
type: external
spec:
provider: vault
path: secret/data/myapp/production
key: api_key
- name: db-credentials
type: external
spec:
provider: vault
path: secret/data/databases/postgres
# Fetch entire secret as JSONStatic Secrets
For secrets that must be specified directly (use sparingly):
secrets:
- name: license-key
type: static
spec:
value: "XXXX-YYYY-ZZZZ-1234" Warning
Using Secrets
In Helm Values
spec:
resources:
secrets:
- name: gitlab-root-password
type: generated
spec:
length: 24
helm:
- name: gitlab
cluster: main
namespace: gitlab
chart: gitlab/gitlab
values:
global:
initialRootPassword:
secret: gitlab-initial-password
key: password Then create the Kubernetes secret:
manifests:
- name: gitlab-password-secret
cluster: main
namespace: gitlab
template: |
apiVersion: v1
kind: Secret
metadata:
name: gitlab-initial-password
type: Opaque
stringData:
password: "{{ .Resources.secrets.gitlab-root-password.value }}" In Kubernetes Manifests
spec:
resources:
secrets:
- name: api-key
type: generated
spec:
length: 32
charset: hex
manifests:
- name: app-secrets
cluster: main
template: |
apiVersion: v1
kind: Secret
metadata:
name: app-secrets
type: Opaque
stringData:
API_KEY: "{{ .Resources.secrets.api-key.value }}"
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
spec:
template:
spec:
containers:
- name: app
envFrom:
- secretRef:
name: app-secrets In VM Cloud-Init
spec:
resources:
secrets:
- name: ssh-key
type: external
spec:
provider: vault
path: secret/data/ssh/training
key: private_key
vms:
- name: bastion
provider: hetzner
type: cx21
userData: |
#cloud-config
write_files:
- path: /root/.ssh/id_rsa
permissions: '0600'
content: |
{{ .Resources.secrets.ssh-key.value | indent 16 }} Per-Participant Secrets
Generate unique secrets for each participant:
spec:
variables:
- name: participant_count
type: integer
default: 10
resources:
secrets:
- name: "participant-{{ .Index }}-password"
type: generated
count: "{{ .Variables.participant_count }}"
spec:
length: 16
charset: alphanumeric
manifests:
- name: participant-secrets
cluster: main
count: "{{ .Variables.participant_count }}"
template: |
apiVersion: v1
kind: Secret
metadata:
name: participant-credentials
namespace: participant-{{ .Index }}
type: Opaque
stringData:
password: "{{ (index .Resources.secrets (printf "participant-%d-password" .Index)).value }}" Secret Outputs
Access secret values in templates:
# Reference secret value
{{ .Resources.secrets.my-secret.value }}
# Reference with index (for counted secrets)
{{ (index .Resources.secrets "participant-0-password").value }}
# Dynamic index
{{ (index .Resources.secrets (printf "participant-%d-password" .Index)).value }} Available secret outputs:
| Output | Description |
|---|---|
.value | The secret value |
.name | Secret name |
.type | Secret type (generated, external, static) |
.length | Length (for generated secrets) |
Common Patterns
Database Credentials
spec:
resources:
secrets:
- name: postgres-password
type: generated
spec:
length: 32
charset: alphanumeric
helm:
- name: postgresql
cluster: main
namespace: database
chart: bitnami/postgresql
values:
auth:
postgresPassword: "{{ .Resources.secrets.postgres-password.value }}"
database: myapp TLS Certificates
For external certificates:
secrets:
- name: tls-cert
type: external
spec:
provider: vault
path: secret/data/certs/wildcard
key: certificate
- name: tls-key
type: external
spec:
provider: vault
path: secret/data/certs/wildcard
key: private_key Then use in Kubernetes:
manifests:
- name: tls-secret
cluster: main
namespace: ingress-nginx
template: |
apiVersion: v1
kind: Secret
metadata:
name: wildcard-tls
type: kubernetes.io/tls
stringData:
tls.crt: |
{{ .Resources.secrets.tls-cert.value | indent 10 }}
tls.key: |
{{ .Resources.secrets.tls-key.value | indent 10 }} GitLab Runner Registration
spec:
resources:
secrets:
- name: runner-token
type: external
spec:
provider: vault
path: secret/data/gitlab/runners
key: registration_token
vms:
- name: runner
provider: hetzner
type: cx31
userData: |
#cloud-config
runcmd:
- |
gitlab-runner register
--non-interactive
--url "https://gitlab.{{ .Environment.Domain }}"
--registration-token "{{ .Resources.secrets.runner-token.value }}"
--executor docker
--docker-image alpine:latest OAuth/API Keys
spec:
resources:
secrets:
- name: github-oauth-id
type: external
spec:
provider: vault
path: secret/data/oauth/github
key: client_id
- name: github-oauth-secret
type: external
spec:
provider: vault
path: secret/data/oauth/github
key: client_secret
helm:
- name: gitlab
values:
global:
appConfig:
omniauth:
providers:
- secret: gitlab-oauth-secrets External Provider Configuration
HashiCorp Vault
Configure Vault access at the organization level:
# Organization settings (not in blueprint)
secrets:
vault:
address: https://vault.example.com
auth:
method: kubernetes
role: teabar-reader
# Or with token
auth:
method: token
token: hvs.xxx # From environment variable Blueprint usage:
secrets:
- name: my-secret
type: external
spec:
provider: vault
path: secret/data/myapp/config
key: api_key AWS Secrets Manager
# Organization settings
secrets:
aws:
region: us-east-1
# Uses IAM role or environment credentials Blueprint usage:
secrets:
- name: rds-password
type: external
spec:
provider: aws-secrets-manager
path: prod/rds/master
key: password Azure Key Vault
# Organization settings
secrets:
azure:
tenantId: xxx-xxx-xxx
# Uses managed identity or service principal Blueprint usage:
secrets:
- name: storage-key
type: external
spec:
provider: azure-keyvault
vault: my-keyvault
path: storage-connection-string Security Best Practices
Never Commit Static Secrets
# Bad: Secret in blueprint
secrets:
- name: api-key
type: static
spec:
value: "sk_live_abc123" # Don't do this!
# Good: Use external provider
secrets:
- name: api-key
type: external
spec:
provider: vault
path: secret/data/api-keys
key: stripe
# Good: Generate at runtime
secrets:
- name: api-key
type: generated
spec:
length: 32 Use Appropriate Character Sets
# Database passwords - avoid special chars that break connection strings
secrets:
- name: db-password
type: generated
spec:
length: 32
charset: alphanumeric # Safe for URLs and connection strings
# API tokens - hex is URL-safe
secrets:
- name: api-token
type: generated
spec:
length: 64
charset: hex Limit Secret Scope
Create secrets only where needed:
# Create in specific namespace
manifests:
- name: app-secret
cluster: main
namespace: myapp # Not in default namespace
template: |
apiVersion: v1
kind: Secret
# ... Rotate Generated Secrets
Generated secrets are unique per environment. When you need rotation:
# Destroy and recreate environment
teactl env delete my-env
teactl env create -f blueprint.yaml --name my-env Note
Troubleshooting
Secret Not Available
If a secret reference fails:
# Check secret was created
teactl env secrets list my-env
# View secret metadata (not value)
teactl env secrets get my-env/db-password External Secret Fetch Failed
Check provider connectivity:
# Test Vault connection
teactl secrets test vault --path secret/data/test
# Test AWS Secrets Manager
teactl secrets test aws-secrets-manager --path test/secret Related Resources
- Kubernetes Manifests - Use secrets in manifests
- Helm Releases - Use secrets in Helm values
- VMs - Inject secrets into VMs
- Templating - Secret value templating