Appearance
Recipes & Examples â
Real-world patterns and solutions for common Konfigo use cases. Each recipe includes the problem, complete solution, and explanation.
Quick Navigation â
đī¸ Deployment Patterns â
đ§ Development Workflows â
đ Advanced Patterns â
Multi-Environment Deployment â
Problem: Deploy the same application to dev, staging, and production with environment-specific settings.
Solution Structure â
configs/
âââ base.yaml # Common settings
âââ environments/
â âââ dev.yaml # Development overrides
â âââ staging.yaml # Staging overrides
â âââ prod.yaml # Production overrides
âââ schema.yaml # Validation rules
Files â
base.yaml
- Common configuration:
yaml
app:
name: "user-service"
version: "1.0.0"
timeout: 30
features:
auth: true
logging: true
database:
port: 5432
pool_size: 10
timeout: 5
monitoring:
enabled: true
metrics_port: 9090
environments/dev.yaml
- Development overrides:
yaml
app:
debug: true
log_level: "debug"
database:
host: "dev-db.company.com"
pool_size: 5
monitoring:
sampling_rate: 1.0
environments/prod.yaml
- Production overrides:
yaml
app:
debug: false
log_level: "info"
replicas: 3
database:
host: "prod-db.company.com"
pool_size: 50
ssl: true
monitoring:
sampling_rate: 0.1
alerts_enabled: true
schema.yaml
- Validation:
yaml
validation:
- path: "app.name"
required: true
type: "string"
- path: "database.host"
required: true
type: "string"
- path: "app.replicas"
type: "number"
min: 1
max: 10
Deployment Commands â
bash
# Development deployment
konfigo -s base.yaml,environments/dev.yaml -S schema.yaml -of dev-config.json
# Staging deployment
konfigo -s base.yaml,environments/staging.yaml -S schema.yaml -of staging-config.json
# Production deployment
konfigo -s base.yaml,environments/prod.yaml -S schema.yaml -of prod-config.json
Automation Script â
bash
#!/bin/bash
# deploy-config.sh
ENVIRONMENT=${1:-dev}
BASE_CONFIG="base.yaml"
ENV_CONFIG="environments/${ENVIRONMENT}.yaml"
SCHEMA="schema.yaml"
OUTPUT="deploy/${ENVIRONMENT}-config.json"
if [[ ! -f "$ENV_CONFIG" ]]; then
echo "Error: Environment config $ENV_CONFIG not found"
exit 1
fi
echo "Generating configuration for $ENVIRONMENT..."
konfigo -s "$BASE_CONFIG,$ENV_CONFIG" -S "$SCHEMA" -of "$OUTPUT"
if [[ $? -eq 0 ]]; then
echo "â
Configuration generated: $OUTPUT"
else
echo "â Configuration generation failed"
exit 1
fi
Usage:
bash
./deploy-config.sh dev
./deploy-config.sh staging
./deploy-config.sh prod
Container & Kubernetes â
Problem: Deploy containerized applications with runtime configuration overrides.
Docker Deployment â
docker-compose.yml
:
yaml
version: '3.8'
services:
app:
image: myapp:latest
environment:
# Override config at runtime
- KONFIGO_KEY_database.host=${DB_HOST:-localhost}
- KONFIGO_KEY_database.password=${DB_PASSWORD}
- KONFIGO_KEY_app.port=${APP_PORT:-8080}
- KONFIGO_KEY_app.environment=${ENVIRONMENT:-development}
volumes:
- ./configs:/app/configs
command: |
sh -c "
konfigo -s /app/configs/base.yaml -of /app/runtime-config.json &&
exec myapp --config /app/runtime-config.json
"
Environment file (.env
):
bash
# .env
DB_HOST=prod-db.company.com
DB_PASSWORD=secure_password
APP_PORT=9090
ENVIRONMENT=production
Run with:
bash
docker-compose up
Kubernetes Deployment â
kubernetes/configmap.yaml
:
yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: app-base-config
data:
base.yaml: |
app:
name: "user-service"
port: 8080
timeout: 30
database:
port: 5432
pool_size: 10
---
apiVersion: v1
kind: Secret
metadata:
name: app-secrets
type: Opaque
data:
database-password: <base64-encoded-password>
kubernetes/deployment.yaml
:
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: user-service
spec:
replicas: 3
selector:
matchLabels:
app: user-service
template:
metadata:
labels:
app: user-service
spec:
containers:
- name: app
image: user-service:latest
env:
# Runtime configuration overrides
- name: KONFIGO_KEY_database.host
value: "prod-db.company.com"
- name: KONFIGO_KEY_database.password
valueFrom:
secretKeyRef:
name: app-secrets
key: database-password
- name: KONFIGO_KEY_app.environment
value: "production"
volumeMounts:
- name: base-config
mountPath: /app/configs
command:
- /bin/sh
- -c
- |
konfigo -s /app/configs/base.yaml -of /app/runtime-config.json
exec /app/user-service --config /app/runtime-config.json
volumes:
- name: base-config
configMap:
name: app-base-config
Team Configuration Management â
Problem: Manage shared team configurations while allowing individual customization.
Solution Structure â
team-configs/
âââ shared/
â âââ base.yaml # Team defaults
â âââ tools.yaml # Shared tool configs
â âââ standards.yaml # Team standards
âââ environments/
â âââ dev.yaml # Development settings
â âââ test.yaml # Testing settings
âââ personal/
â âââ .gitignore # Don't commit personal configs
âââ scripts/
âââ setup-dev.sh # Setup script
Files â
shared/base.yaml
- Team defaults:
yaml
development:
database:
host: "team-dev-db.company.com"
port: 5432
api:
base_url: "https://api-dev.company.com"
timeout: 30
tools:
editor:
tab_size: 2
format_on_save: true
linter:
max_line_length: 100
enforce_style: true
personal/alice.yaml
- Individual overrides:
yaml
development:
database:
host: "localhost" # Local database for development
api:
timeout: 60 # Longer timeout for debugging
tools:
editor:
tab_size: 4 # Personal preference
Setup script (scripts/setup-dev.sh
):
bash
#!/bin/bash
USER=${1:-$(whoami)}
PERSONAL_CONFIG="personal/${USER}.yaml"
DEV_CONFIG="environments/dev.yaml"
echo "Setting up development environment for $USER..."
# Create personal config if it doesn't exist
if [[ ! -f "$PERSONAL_CONFIG" ]]; then
echo "Creating personal config: $PERSONAL_CONFIG"
cp personal/template.yaml "$PERSONAL_CONFIG"
fi
# Generate development configuration
konfigo \
-s shared/base.yaml,shared/tools.yaml,"$DEV_CONFIG","$PERSONAL_CONFIG" \
-of ".dev-config.json"
echo "â
Development configuration ready: .dev-config.json"
echo "đĄ Edit $PERSONAL_CONFIG to customize your settings"
Usage:
bash
# Setup for specific team member
./scripts/setup-dev.sh alice
# Setup for current user
./scripts/setup-dev.sh
Microservices Configuration â
Problem: Generate similar configurations for multiple microservices with service-specific customization.
Solution: Template + Variables â
template.yaml
- Service template:
yaml
service:
name: "${SERVICE_NAME}"
port: "${SERVICE_PORT}"
version: "1.0.0"
database:
host: "${DB_HOST}"
database: "${DB_NAME}"
pool_size: "${DB_POOL_SIZE}"
monitoring:
enabled: true
port: "${METRICS_PORT}"
service_name: "${SERVICE_NAME}"
resources:
memory: "${MEMORY_LIMIT}"
cpu: "${CPU_LIMIT}"
services.yaml
- Service definitions:
yaml
konfigo_forEach:
- name: "user-service"
vars:
SERVICE_NAME: "user-service"
SERVICE_PORT: 8001
DB_NAME: "users"
DB_POOL_SIZE: 20
METRICS_PORT: 9001
MEMORY_LIMIT: "512Mi"
CPU_LIMIT: "500m"
- name: "order-service"
vars:
SERVICE_NAME: "order-service"
SERVICE_PORT: 8002
DB_NAME: "orders"
DB_POOL_SIZE: 30
METRICS_PORT: 9002
MEMORY_LIMIT: "1Gi"
CPU_LIMIT: "1000m"
- name: "payment-service"
vars:
SERVICE_NAME: "payment-service"
SERVICE_PORT: 8003
DB_NAME: "payments"
DB_POOL_SIZE: 15
METRICS_PORT: 9003
MEMORY_LIMIT: "256Mi"
CPU_LIMIT: "250m"
schema.yaml
- Processing rules:
yaml
vars:
- name: "DB_HOST"
value: "postgres.company.com" # Common database host
transforms:
- path: "service.name"
setValue: "${SERVICE_NAME}"
- path: "service.port"
setValue: "${SERVICE_PORT}"
- path: "database.host"
setValue: "${DB_HOST}"
- path: "database.database"
setValue: "${DB_NAME}"
validation:
- path: "service.port"
type: "number"
min: 8000
max: 9000
- path: "service.name"
type: "string"
regex: "^[a-z-]+$"
Generate all service configs:
bash
konfigo -s template.yaml -S schema.yaml -V services.yaml -od configs/
# Creates:
# configs/user-service.yaml
# configs/order-service.yaml
# configs/payment-service.yaml
Kubernetes deployment generation:
bash
# Generate Kubernetes manifests
for config in configs/*.yaml; do
service=$(basename "$config" .yaml)
envsubst < k8s-template.yaml > "k8s/${service}-deployment.yaml"
done
Feature Flag Management â
Problem: Manage feature flags across environments with easy toggle capabilities.
Solution Structure â
features/base.yaml
- Default feature states:
yaml
features:
auth:
oauth_login: true
two_factor: false
social_login: true
payments:
stripe_integration: true
paypal_integration: false
crypto_payments: false
ui:
new_dashboard: false
dark_mode: true
analytics_widget: true
experimental:
ai_recommendations: false
performance_mode: false
features/environments/prod.yaml
- Production overrides:
yaml
features:
auth:
two_factor: true # Enable 2FA in production
payments:
paypal_integration: true # Enable PayPal in prod
ui:
new_dashboard: true # New dashboard ready for prod
experimental:
# Keep experimental features disabled in prod
features/rollout.yaml
- Gradual rollout configuration:
yaml
konfigo_forEach:
- name: "canary"
vars:
ROLLOUT_PERCENTAGE: 5
NEW_DASHBOARD: true
AI_RECOMMENDATIONS: true
- name: "beta"
vars:
ROLLOUT_PERCENTAGE: 25
NEW_DASHBOARD: true
AI_RECOMMENDATIONS: false
- name: "stable"
vars:
ROLLOUT_PERCENTAGE: 100
NEW_DASHBOARD: false
AI_RECOMMENDATIONS: false
features/schema.yaml
- Feature processing:
yaml
transforms:
- path: "features.ui.new_dashboard"
setValue: "${NEW_DASHBOARD}"
- path: "features.experimental.ai_recommendations"
setValue: "${AI_RECOMMENDATIONS}"
- path: "rollout.percentage"
setValue: "${ROLLOUT_PERCENTAGE}"
validation:
- path: "rollout.percentage"
type: "number"
min: 0
max: 100
Usage:
bash
# Generate standard environment configs
konfigo -s features/base.yaml,features/environments/prod.yaml -of prod-features.json
# Generate rollout configurations
konfigo -s features/base.yaml -S features/schema.yaml -V features/rollout.yaml -od rollout/
# Override specific features via environment
KONFIGO_KEY_features.experimental.ai_recommendations=true \
konfigo -s prod-features.json -of runtime-features.json
Configuration Validation Pipeline â
Problem: Ensure all configurations are valid before deployment through automated validation.
CI/CD Pipeline Integration â
.github/workflows/config-validation.yml
:
yaml
name: Configuration Validation
on:
pull_request:
paths:
- 'configs/**'
- 'schemas/**'
jobs:
validate-configs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Download Konfigo
run: |
curl -L https://github.com/ebogdum/konfigo/releases/latest/download/konfigo-linux-amd64 -o konfigo
chmod +x konfigo
sudo mv konfigo /usr/local/bin/
- name: Validate Development Configs
run: |
./scripts/validate-environment.sh dev
- name: Validate Staging Configs
run: |
./scripts/validate-environment.sh staging
- name: Validate Production Configs
run: |
./scripts/validate-environment.sh prod
- name: Generate Test Configs
run: |
./scripts/generate-all-configs.sh --validate-only
Validation script (scripts/validate-environment.sh
):
bash
#!/bin/bash
set -e
ENVIRONMENT=$1
if [[ -z "$ENVIRONMENT" ]]; then
echo "Usage: $0 <environment>"
exit 1
fi
echo "đ Validating $ENVIRONMENT configuration..."
BASE_CONFIG="configs/base.yaml"
ENV_CONFIG="configs/environments/${ENVIRONMENT}.yaml"
SCHEMA="schemas/validation.yaml"
# Check if files exist
for file in "$BASE_CONFIG" "$ENV_CONFIG" "$SCHEMA"; do
if [[ ! -f "$file" ]]; then
echo "â Missing file: $file"
exit 1
fi
done
# Validate configuration
if konfigo -s "$BASE_CONFIG,$ENV_CONFIG" -S "$SCHEMA" --validate-only; then
echo "â
$ENVIRONMENT configuration is valid"
else
echo "â $ENVIRONMENT configuration validation failed"
exit 1
fi
# Test merge output
echo "đ Testing merge output..."
OUTPUT=$(mktemp)
konfigo -s "$BASE_CONFIG,$ENV_CONFIG" -S "$SCHEMA" -of "$OUTPUT"
# Verify required fields exist
REQUIRED_FIELDS=("app.name" "database.host" "app.port")
for field in "${REQUIRED_FIELDS[@]}"; do
if ! jq -e ".$field" "$OUTPUT" > /dev/null; then
echo "â Missing required field: $field"
cat "$OUTPUT"
rm "$OUTPUT"
exit 1
fi
done
rm "$OUTPUT"
echo "â
All required fields present"
Comprehensive validation schema (schemas/validation.yaml
):
yaml
# Input validation
inputSchema:
strict: true
# Core validation rules
validation:
# Application configuration
- path: "app.name"
required: true
type: "string"
regex: "^[a-z][a-z0-9-]*$"
- path: "app.port"
required: true
type: "number"
min: 1024
max: 65535
- path: "app.environment"
required: true
type: "string"
enum: ["development", "staging", "production"]
# Database configuration
- path: "database.host"
required: true
type: "string"
minLength: 3
- path: "database.port"
required: true
type: "number"
min: 1
max: 65535
# Security validation
- path: "database.ssl"
required: true
type: "boolean"
- path: "security.api_keys"
required: false
type: "array"
minItems: 1
# Post-processing validation
transforms:
- path: "metadata.validated_at"
setValue: "${TIMESTAMP}"
- path: "metadata.validation_version"
setValue: "1.0"
# Immutable production settings
immutable:
- "app.name"
- "security"
Local Development Integration â
Pre-commit hook (.git/hooks/pre-commit
):
bash
#!/bin/bash
echo "đ Validating configurations before commit..."
# Find all changed config files
CHANGED_CONFIGS=$(git diff --cached --name-only | grep -E '\.(yaml|yml|json|toml)$' | grep configs/ || true)
if [[ -z "$CHANGED_CONFIGS" ]]; then
echo "âšī¸ No configuration files changed"
exit 0
fi
# Validate each changed config
for config in $CHANGED_CONFIGS; do
echo "Validating $config..."
# Determine environment from path
if [[ "$config" =~ environments/([^/]+)\.yaml$ ]]; then
ENV="${BASH_REMATCH[1]}"
if ! ./scripts/validate-environment.sh "$ENV"; then
echo "â Configuration validation failed for $config"
exit 1
fi
fi
done
echo "â
All configurations valid"
Best Practices Summary â
1. Structure Your Configs â
- Use consistent directory structures
- Separate base configs from environment overrides
- Keep schemas and validation rules in version control
2. Automate Everything â
- Use scripts for common operations
- Integrate validation into CI/CD pipelines
- Set up pre-commit hooks for immediate feedback
3. Security First â
- Never commit secrets to version control
- Use environment variables for sensitive data
- Validate configurations before deployment
4. Documentation â
- Document your configuration patterns
- Provide examples for team members
- Maintain README files for complex setups
5. Testing â
- Test configuration merges in development
- Validate against schemas regularly
- Use dry-run modes when available
These recipes provide proven patterns for real-world Konfigo usage. Adapt them to your specific needs and build upon these foundations!