Configuration Best Practices
This guide presents best practices, patterns, and recommendations for creating maintainable, secure, and efficient Xec configurations.
Configuration Organization
File Structure
Organize your configuration files logically:
.xec/
├── config.yaml # Main configuration
├── profiles/ # Environment profiles
│ ├── dev.yaml
│ ├── staging.yaml
│ └── production.yaml
├── tasks/ # Reusable task definitions
│ ├── deploy.yaml
│ ├── backup.yaml
│ └── monitoring.yaml
├── targets/ # Target configurations
│ ├── aws.yaml
│ └── on-premise.yaml
└── scripts/ # Custom scripts
├── health-check.js
└── data-migration.js
Modular Configuration
Break large configurations into modules:
# .xec/config.yaml
version: "1.0"
name: myapp
# Import modular configurations
$import:
- tasks/*.yaml
- profiles/*.yaml
- targets/*.yaml
# Keep main config focused
vars:
appName: myapp
version: "2.0.0"
Separation of Concerns
# Separate by functionality
tasks:
$import:
- tasks/deployment.yaml # Deployment tasks
- tasks/maintenance.yaml # Maintenance tasks
- tasks/monitoring.yaml # Monitoring tasks
Naming Conventions
Consistent Naming
# Good - consistent naming pattern
tasks:
deploy-web:
deploy-api:
deploy-worker:
backup-database:
backup-files:
backup-configs:
# Bad - inconsistent naming
tasks:
deployWeb:
api_deploy:
worker-dpl:
Descriptive Names
# Good - self-documenting
targets:
hosts:
production-web-server:
staging-database-primary:
development-cache:
# Bad - cryptic names
targets:
hosts:
pws1:
sdb-p:
d-cache:
Hierarchical Naming
tasks:
# Group related tasks with prefixes
db:backup:
db:restore:
db:migrate:
app:deploy:
app:rollback:
app:health-check:
Variable Management
Variable Hierarchy
# 1. Global defaults
vars:
timeout: 30000
retries: 3
# 2. Environment-specific
profiles:
production:
vars:
timeout: 60000 # Override for production
# 3. Task-specific
tasks:
long-running:
vars:
timeout: 3600000 # Task-specific override
Variable Documentation
vars:
# API Configuration
# ==================
# Base URL for API endpoints (must include protocol)
apiUrl: https://api.example.com
# API version to use (format: vX)
apiVersion: v2
# Maximum retry attempts for failed API calls
apiMaxRetries: 3
# Timeout for API calls in milliseconds
apiTimeout: 10000
Default Values
vars:
# Always provide defaults
port: ${env.PORT:-8080}
environment: ${env.NODE_ENV:-development}
logLevel: ${env.LOG_LEVEL:-info}
# Computed defaults
workers: ${env.WORKERS:-${runtime.cpus}}
Security Best Practices
Secret Management
# Good - use secret management
vars:
apiKey: ${secrets.api_key}
dbPassword: ${secrets.database_password}
sshKey: ${secrets.deploy_key}
# Bad - hardcoded secrets
vars:
apiKey: "sk-1234567890abcdef" # NEVER DO THIS
dbPassword: "password123" # SECURITY RISK
Secure Defaults
targets:
defaults:
ssh:
strictHostKeyChecking: yes
passwordAuthentication: no
pubkeyAuthentication: yes
docker:
privileged: false
readonlyRootfs: true
noNewPrivileges: true
Principle of Least Privilege
targets:
hosts:
web-server:
username: deploy # Not root
sudo:
enabled: false # Only if needed
containers:
app:
user: nobody # Non-root user
capDrop: [ALL] # Drop all capabilities