apply
Securely apply encrypted environment variables to template files, eliminating the need for plaintext secrets or unsafe tools like envsubst.
Synopsis
Section titled “Synopsis”kiln apply -f <file> <template-file> [options]The apply command performs variable substitution in template files using encrypted kiln variables, ensuring secrets never appear in plaintext during the templating process.
Arguments
Section titled “Arguments”<template-file>: Path to the template file containing variable placeholders (required)
Options
Section titled “Options”--file,-f: Environment file from configuration (required)--output,-o: Output file path (default: stdout)--strict: Fail if template variables are not found in kiln environment--left-delimiter: Custom left delimiter for variables (default:$or${)--right-delimiter: Custom right delimiter for variables (default: empty or})
Examples
Section titled “Examples”Basic Usage
Section titled “Basic Usage”# Apply variables to nginx config, output to stdoutkiln apply -f production nginx.conf.template
# Apply and save to filekiln apply -f staging docker-compose.yml.template -o docker-compose.ymlStrict Mode
Section titled “Strict Mode”# Fail if any template variables are missingkiln apply -f production --strict k8s-deployment.yaml.templateCustom Delimiters
Section titled “Custom Delimiters”# Use custom delimiters for templates with [[ ]] syntaxkiln apply -f development --left-delimiter "[[" --right-delimiter "]]" ansible.template
# Use different delimiterskiln apply -f production --left-delimiter "{{" --right-delimiter "}}" config.templatePipeline Integration
Section titled “Pipeline Integration”# Apply and pipe to Dockerkiln apply -f production docker-compose.yml.template | docker-compose -f - up
# Apply and deploy to Kuberneteskiln apply -f staging k8s-manifest.yaml.template | kubectl apply -f -Variable Patterns
Section titled “Variable Patterns”Default Patterns
Section titled “Default Patterns”When no custom delimiters are specified, standard shell-compatible patterns are used:
# Braced variables (recommended)database_url=${DATABASE_URL}api_key=${API_KEY}port=${PORT}
# Simple variables (use with caution)home_dir=$HOMEuser=$USERValidation rules for default patterns:
${VAR}: Strict shell syntax, no whitespace allowed$VAR: Direct variable reference, no whitespace
Custom Delimiter Patterns
Section titled “Custom Delimiter Patterns”When custom delimiters are specified, flexible spacing is allowed:
# Template with custom delimitersdatabase=[[DATABASE_URL]]api=[[ API_KEY ]]port=[[ PORT]]debug=[[ DEBUG_MODE ]]Custom delimiter features:
- Whitespace tolerance:
[[ VAR ]],[[VAR]],[[ VAR]]all work - Any delimiter pair:
{{ }},<% %>,@@ @@, etc. - Escape sequences handled automatically
Template Formats
Section titled “Template Formats”Configuration Files
Section titled “Configuration Files”# app.conf.template[database]url = ${DATABASE_URL}pool_size = ${DB_POOL_SIZE}
[api]key = ${API_KEY}timeout = ${API_TIMEOUT}Docker Compose
Section titled “Docker Compose”# docker-compose.yml.templateversion: '3.8'services: app: image: myapp:latest environment: - DATABASE_URL=${DATABASE_URL} - API_KEY=${API_KEY} - DEBUG=${DEBUG_MODE} ports: - "${PORT}:8080"
redis: image: redis:7 command: redis-server --requirepass ${REDIS_PASSWORD}Kubernetes Manifests
Section titled “Kubernetes Manifests”# deployment.yaml.templateapiVersion: apps/v1kind: Deploymentmetadata: name: myappspec: template: spec: containers: - name: app image: myapp:${IMAGE_TAG} env: - name: DATABASE_URL value: "${DATABASE_URL}" - name: API_KEY value: "${API_KEY}"Nginx Configuration
Section titled “Nginx Configuration”server { listen ${PORT}; server_name ${DOMAIN};
location / { proxy_pass ${BACKEND_URL}; proxy_set_header Authorization "Bearer ${API_TOKEN}"; }
ssl_certificate ${SSL_CERT_PATH}; ssl_certificate_key ${SSL_KEY_PATH};}Shell Scripts
Section titled “Shell Scripts”#!/bin/bash# deploy.sh.template
export DATABASE_URL="${DATABASE_URL}"export API_KEY="${API_KEY}"export LOG_LEVEL="${LOG_LEVEL}"
echo "Deploying to ${ENVIRONMENT}"./app --port=${PORT} --workers=${WORKER_COUNT}Security Features
Section titled “Security Features”Memory Safety
Section titled “Memory Safety”- Template content and variables are wiped from memory after processing
- No sensitive data persists in process memory
- Secure cleanup on interruption or error
Input Validation
Section titled “Input Validation”- Template file path validation prevents directory traversal
- Output path validation with permission checks
- Variable name validation follows standard conventions
- Template content size limits prevent memory exhaustion
Access Control
Section titled “Access Control”- Respects existing file-level access controls from
kiln.toml - Validates user has read access to specified environment file
- Validates write permissions for output file destination
Error Handling
Section titled “Error Handling”Missing Variables
Section titled “Missing Variables”# Non-strict mode (default)kiln apply -f production template.conf# Missing variables are left unchanged: ${MISSING_VAR}
# Strict modekiln apply -f production --strict template.conf# Error: missing variables: [MISSING_VAR, ANOTHER_MISSING]File Access Errors
Section titled “File Access Errors”# Template file not readablekiln apply -f production /etc/shadow# Error: cannot read template file: permission denied
# Output directory not writablekiln apply -f production template.conf -o /etc/output.conf# Error: cannot write output file: permission deniedInvalid Delimiters
Section titled “Invalid Delimiters”# Mismatched delimiterskiln apply -f production --left-delimiter "[[" template.conf# Error: both left and right delimiters must be specified togetherIntegration Patterns
Section titled “Integration Patterns”Development Workflow
Section titled “Development Workflow”# Generate local configurationkiln apply -f development app.conf.template -o config/local.conf
# Start application with generated config./app --config config/local.confCI/CD Deployment
Section titled “CI/CD Deployment”#!/bin/bash# Validate template accessif ! kiln info --file production --verify; then echo "Cannot access production environment" >&2 exit 1fi
# Generate deployment manifestskiln apply -f production k8s-deployment.yaml.template -o deployment.yamlkiln apply -f production k8s-service.yaml.template -o service.yaml
# Deploy to clusterkubectl apply -f deployment.yaml -f service.yamlConfiguration Management
Section titled “Configuration Management”# Generate configs for multiple environmentsfor env in development staging production; do kiln apply -f "$env" nginx.conf.template -o "configs/nginx-$env.conf"done
# Validate generated configsfor config in configs/*.conf; do nginx -t -c "$config"doneDocker Integration
Section titled “Docker Integration”# Generate docker-compose with secretskiln apply -f production docker-compose.yml.template -o docker-compose.prod.yml
# Deploy stackdocker-compose -f docker-compose.prod.yml up -d
# Clean up generated filerm docker-compose.prod.ymlBest Practices
Section titled “Best Practices”Template Design
Section titled “Template Design”- Use descriptive variable names that clearly indicate their purpose
- Group related variables logically in templates
- Include comments to document expected variable types and formats
- Use braced syntax
${VAR}for clarity and safety
Security Guidelines
Section titled “Security Guidelines”- Never commit generated files containing secrets to version control
- Use strict mode in production to catch missing variables early
- Validate output before deploying to ensure all substitutions occurred
- Clean up temporary files containing sensitive data
Error Prevention
Section titled “Error Prevention”# Check template variables before applyinggrep -oP '\$\{[A-Za-z_][A-Za-z0-9_]*\}' template.conf | sort -u
# Validate all required variables existrequired_vars=("DATABASE_URL" "API_KEY" "PORT")for var in "${required_vars[@]}"; do if ! kiln get "$var" --file production >/dev/null 2>&1; then echo "Missing required variable: $var" >&2 exit 1 fidone
# Apply with validationkiln apply -f production --strict template.conf -o output.confComparison with Alternatives
Section titled “Comparison with Alternatives”vs. envsubst
Section titled “vs. envsubst”- Security: kiln keeps secrets encrypted; envsubst requires plaintext environment
- Access Control: kiln enforces file-level permissions; envsubst uses process environment
- Integration: Both support standard shell syntax; kiln adds custom delimiters
vs. Template Engines
Section titled “vs. Template Engines”- Simplicity: kiln uses simple variable substitution; template engines add complexity
- Security: kiln focuses on secret management; template engines focus on logic
- Performance: kiln is optimized for config generation; template engines support programming constructs
vs. Manual Editing
Section titled “vs. Manual Editing”- Automation: kiln enables scriptable configuration generation
- Consistency: Reduces human error in configuration management
- Security: Eliminates need to handle plaintext secrets during deployment