278 lines
6.7 KiB
Markdown
278 lines
6.7 KiB
Markdown
|
|
# KCL Package Examples
|
||
|
|
|
||
|
|
This directory contains practical examples demonstrating how to use the provisioning KCL package schemas.
|
||
|
|
|
||
|
|
## Example Files
|
||
|
|
|
||
|
|
### 📄 `basic_server.k`
|
||
|
|
**Simple server configurations for different use cases**
|
||
|
|
- Web server with nginx and monitoring
|
||
|
|
- Database server with PostgreSQL
|
||
|
|
- Development server with Docker
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Validate and run
|
||
|
|
kcl run basic_server.k
|
||
|
|
|
||
|
|
# Export to JSON
|
||
|
|
kcl run basic_server.k --format json
|
||
|
|
```
|
||
|
|
|
||
|
|
### 📄 `simple_workflow.k`
|
||
|
|
**Basic workflow example with sequential operations**
|
||
|
|
- Database server creation
|
||
|
|
- Web server deployment
|
||
|
|
- Application configuration with dependencies
|
||
|
|
|
||
|
|
Demonstrates:
|
||
|
|
- Sequential dependencies
|
||
|
|
- Retry policies
|
||
|
|
- Basic monitoring
|
||
|
|
- Filesystem storage
|
||
|
|
|
||
|
|
### 📄 `kubernetes_deployment.k`
|
||
|
|
**Complete Kubernetes deployment examples**
|
||
|
|
- Web application with resources and affinity
|
||
|
|
- PostgreSQL with persistent storage
|
||
|
|
- Prometheus monitoring stack
|
||
|
|
|
||
|
|
Features:
|
||
|
|
- Resource limits and requests
|
||
|
|
- Persistent volumes
|
||
|
|
- Services and networking
|
||
|
|
- ConfigMaps and secrets
|
||
|
|
- Anti-affinity rules
|
||
|
|
|
||
|
|
### 📄 `mixed_provider_workflow.k`
|
||
|
|
**Advanced multi-cloud deployment**
|
||
|
|
- UpCloud compute infrastructure
|
||
|
|
- AWS managed services (RDS, ElastiCache)
|
||
|
|
- Kubernetes cluster setup
|
||
|
|
- Cross-cloud connectivity
|
||
|
|
|
||
|
|
Advanced features:
|
||
|
|
- Multiple providers in single workflow
|
||
|
|
- Complex dependency chains
|
||
|
|
- Production-grade monitoring
|
||
|
|
- Encrypted state storage
|
||
|
|
- Comprehensive retry and rollback strategies
|
||
|
|
|
||
|
|
## Running Examples
|
||
|
|
|
||
|
|
### Basic Validation
|
||
|
|
```bash
|
||
|
|
# Check syntax and validate schemas
|
||
|
|
kcl fmt examples/*.k
|
||
|
|
kcl run examples/basic_server.k
|
||
|
|
```
|
||
|
|
|
||
|
|
### JSON Output for Integration
|
||
|
|
```bash
|
||
|
|
# Generate JSON for Nushell/Rust integration
|
||
|
|
kcl run examples/simple_workflow.k --format json > workflow.json
|
||
|
|
|
||
|
|
# Use with Nushell
|
||
|
|
let workflow = (open workflow.json)
|
||
|
|
echo $"Workflow: ($workflow.name)"
|
||
|
|
echo $"Operations: ($workflow.operations | length)"
|
||
|
|
```
|
||
|
|
|
||
|
|
### Validation with Different Configurations
|
||
|
|
```bash
|
||
|
|
# Test with custom values
|
||
|
|
kcl run examples/basic_server.k -D hostname="my-server" -D user="ubuntu"
|
||
|
|
|
||
|
|
# Override workflow settings
|
||
|
|
kcl run examples/simple_workflow.k -D max_parallel_operations=5
|
||
|
|
```
|
||
|
|
|
||
|
|
## Integration Patterns
|
||
|
|
|
||
|
|
### With Nushell Scripts
|
||
|
|
```nushell
|
||
|
|
# Load and submit workflow
|
||
|
|
def submit-workflow [file: string] {
|
||
|
|
let workflow = (kcl run $file --format json | from json)
|
||
|
|
$workflow | to json | http post http://localhost:8080/workflows/batch/submit
|
||
|
|
}
|
||
|
|
|
||
|
|
# Monitor workflow progress
|
||
|
|
def monitor-workflow [workflow_id: string] {
|
||
|
|
while true {
|
||
|
|
let status = (http get $"http://localhost:8080/workflows/batch/($workflow_id)")
|
||
|
|
print $"Status: ($status.status)"
|
||
|
|
if $status.status in ["completed", "failed"] { break }
|
||
|
|
sleep 10sec
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### With Rust Orchestrator
|
||
|
|
```rust
|
||
|
|
use serde_json;
|
||
|
|
use std::process::Command;
|
||
|
|
|
||
|
|
// Generate workflow from KCL
|
||
|
|
let output = Command::new("kcl")
|
||
|
|
.args(&["run", "examples/simple_workflow.k", "--format", "json"])
|
||
|
|
.output()?;
|
||
|
|
|
||
|
|
// Parse and execute
|
||
|
|
let workflow: BatchWorkflow = serde_json::from_slice(&output.stdout)?;
|
||
|
|
let executor = BatchExecutor::new(workflow);
|
||
|
|
executor.execute().await?;
|
||
|
|
```
|
||
|
|
|
||
|
|
## Customization Examples
|
||
|
|
|
||
|
|
### Server Configuration Variants
|
||
|
|
```kcl
|
||
|
|
import ..main
|
||
|
|
|
||
|
|
# High-performance server
|
||
|
|
performance_server: main.Server = main.Server {
|
||
|
|
hostname: "perf-01"
|
||
|
|
title: "High Performance Server"
|
||
|
|
labels: "env: prod, tier: compute, performance: high"
|
||
|
|
user: "performance"
|
||
|
|
|
||
|
|
# Override defaults for high-performance needs
|
||
|
|
running_timeout: 300
|
||
|
|
|
||
|
|
taskservs: [
|
||
|
|
main.TaskServDef {
|
||
|
|
name: "tuned"
|
||
|
|
install_mode: "server"
|
||
|
|
profile: "performance"
|
||
|
|
}
|
||
|
|
]
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### Workflow Customization
|
||
|
|
```kcl
|
||
|
|
import ..main
|
||
|
|
|
||
|
|
# Custom retry policy for network operations
|
||
|
|
network_retry_policy: main.RetryPolicy = main.RetryPolicy {
|
||
|
|
max_attempts: 5
|
||
|
|
initial_delay: 10
|
||
|
|
max_delay: 120
|
||
|
|
backoff_multiplier: 1.5
|
||
|
|
retry_on_errors: ["connection_error", "dns_error", "timeout"]
|
||
|
|
}
|
||
|
|
|
||
|
|
# Workflow with custom settings
|
||
|
|
custom_workflow: main.BatchWorkflow = main.BatchWorkflow {
|
||
|
|
workflow_id: "custom_001"
|
||
|
|
name: "Custom Network Deployment"
|
||
|
|
|
||
|
|
# Use custom retry policy for all operations
|
||
|
|
default_retry_policy: network_retry_policy
|
||
|
|
|
||
|
|
operations: [
|
||
|
|
# ... your operations
|
||
|
|
]
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
## Best Practices Demonstrated
|
||
|
|
|
||
|
|
### 1. **Dependency Management**
|
||
|
|
- Use sequential dependencies for ordered operations
|
||
|
|
- Use conditional dependencies for health checks
|
||
|
|
- Set appropriate timeouts for each dependency
|
||
|
|
|
||
|
|
### 2. **Resource Configuration**
|
||
|
|
- Always set resource limits for Kubernetes deployments
|
||
|
|
- Use appropriate server plans based on workload
|
||
|
|
- Configure persistent storage for stateful services
|
||
|
|
|
||
|
|
### 3. **Monitoring & Observability**
|
||
|
|
- Enable monitoring for production workflows
|
||
|
|
- Configure appropriate log levels
|
||
|
|
- Set up notifications for critical operations
|
||
|
|
|
||
|
|
### 4. **Error Handling**
|
||
|
|
- Configure retry policies based on operation type
|
||
|
|
- Use rollback strategies for critical deployments
|
||
|
|
- Set appropriate timeouts for different operations
|
||
|
|
|
||
|
|
### 5. **Security**
|
||
|
|
- Use encrypted storage for sensitive workflows
|
||
|
|
- Configure proper network isolation
|
||
|
|
- Use secrets management for credentials
|
||
|
|
|
||
|
|
## Troubleshooting
|
||
|
|
|
||
|
|
### Common Issues
|
||
|
|
|
||
|
|
**Schema Validation Errors**
|
||
|
|
```bash
|
||
|
|
# Check for typos in schema names
|
||
|
|
kcl run examples/basic_server.k --debug
|
||
|
|
|
||
|
|
# Validate against specific schema
|
||
|
|
kcl vet examples/basic_server.k --schema main.Server
|
||
|
|
```
|
||
|
|
|
||
|
|
**Missing Required Fields**
|
||
|
|
```bash
|
||
|
|
# Error: attribute 'labels' of Server is required
|
||
|
|
# Solution: Always provide required fields
|
||
|
|
server: main.Server = main.Server {
|
||
|
|
hostname: "web-01"
|
||
|
|
title: "Web Server"
|
||
|
|
labels: "env: prod" # ✅ Required field
|
||
|
|
user: "admin" # ✅ Required field
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Import Errors**
|
||
|
|
```bash
|
||
|
|
# Use relative imports within the package
|
||
|
|
import ..main # ✅ Correct
|
||
|
|
|
||
|
|
# Not absolute imports
|
||
|
|
import provisioning.main # ❌ May not work in examples
|
||
|
|
```
|
||
|
|
|
||
|
|
### Testing Examples
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Run all examples to verify they work
|
||
|
|
for file in examples/*.k; do
|
||
|
|
echo "Testing $file"
|
||
|
|
kcl run "$file" > /dev/null && echo "✅ PASS" || echo "❌ FAIL"
|
||
|
|
done
|
||
|
|
|
||
|
|
# Test JSON serialization
|
||
|
|
kcl run examples/simple_workflow.k --format json | jq '.workflow_id'
|
||
|
|
```
|
||
|
|
|
||
|
|
## Contributing Examples
|
||
|
|
|
||
|
|
When adding new examples:
|
||
|
|
|
||
|
|
1. **Follow naming convention**: `{purpose}_{type}.k`
|
||
|
|
2. **Include comprehensive comments**
|
||
|
|
3. **Demonstrate specific features**
|
||
|
|
4. **Test before committing**
|
||
|
|
5. **Update this README**
|
||
|
|
|
||
|
|
Example template:
|
||
|
|
```kcl
|
||
|
|
# {Purpose} Example
|
||
|
|
# Demonstrates {specific features}
|
||
|
|
|
||
|
|
import ..main
|
||
|
|
|
||
|
|
# Clear, descriptive variable names
|
||
|
|
example_resource: main.ResourceType = main.ResourceType {
|
||
|
|
# Well-commented configuration
|
||
|
|
required_field: "value"
|
||
|
|
|
||
|
|
# Explain non-obvious settings
|
||
|
|
optional_field: "explained_value" # Why this value
|
||
|
|
}
|
||
|
|
```
|