Crossplane Renderer & Validator
When This Skill Activates
This skill automatically activates when:
- •Rendering Crossplane compositions for testing
- •Validating composition security and policies
- •Previewing resources before deployment
- •User mentions "render", "crossplane", "polaris", "validate", "security"
- •Testing composition changes during development
- •Debugging composition issues
Relationship with KCL Validator
Standalone Use: Quick composition testing and security validation during development
Integrated Use: Part of the complete validation workflow with kcl-composition-validator skill
- •Stage 1: KCL Formatting (
kcl fmt) - •Stage 2: KCL Syntax Validation (
kcl run) - •Stage 3: Composition Rendering (this skill)
- •Stage 4: Security/Policy Validation (this skill)
For complete pre-commit validation, use kcl-composition-validator which runs all stages.
Core Rendering Workflow
Basic Rendering
Purpose: Test that composition renders successfully and preview resources
Command Pattern:
cd infrastructure/base/crossplane/configuration crossplane render \ examples/<claim-file>.yaml \ <composition-file>.yaml \ functions.yaml \ --extra-resources examples/environmentconfig.yaml \ > /tmp/rendered.yaml
Available Compositions:
- •
App Composition (
app-composition.yaml)- •Examples:
app-basic.yaml,app-complete.yaml - •Progressive complexity: minimal to production-ready
- •Features: deployment, database, cache, storage, autoscaling, HA
- •Examples:
- •
SQLInstance Composition (
sql-instance-composition.yaml)- •Examples:
sqlinstance-basic.yaml,sqlinstance-complete.yaml - •PostgreSQL via CloudNativePG
- •Features: backup, HA, migrations
- •Examples:
- •
EKS Pod Identity (
epi-composition.yaml)- •Example:
epi.yaml - •IAM roles for service accounts
- •Example:
Rendering Examples
Test basic App configuration:
cd infrastructure/base/crossplane/configuration crossplane render \ examples/app-basic.yaml \ app-composition.yaml \ functions.yaml \ --extra-resources examples/environmentconfig.yaml \ > /tmp/app-basic-rendered.yaml
Test complete App configuration:
crossplane render \ examples/app-complete.yaml \ app-composition.yaml \ functions.yaml \ --extra-resources examples/environmentconfig.yaml \ > /tmp/app-complete-rendered.yaml
Test SQLInstance:
crossplane render \ examples/sqlinstance-complete.yaml \ sql-instance-composition.yaml \ functions.yaml \ --extra-resources examples/environmentconfig.yaml \ > /tmp/sqlinstance-rendered.yaml
Security & Policy Validation
CRITICAL: Every composition change must pass security and policy validation before committing.
Validation Targets
- •Polaris: Security & best practices - Target score: 85+
- •kube-linter: Kubernetes best practices - Target: No errors
- •Datree: Policy enforcement - Target: No violations (warnings acceptable if documented)
Step-by-Step Validation
Step 1: Render the Composition
cd infrastructure/base/crossplane/configuration crossplane render examples/app-complete.yaml app-composition.yaml functions.yaml \ --extra-resources examples/environmentconfig.yaml > /tmp/rendered.yaml
Step 2: Polaris Security Audit
polaris audit --audit-path /tmp/rendered.yaml --format=pretty
Expected output:
- •Overall score: 85+ (Green/Yellow acceptable)
- •No critical security issues
- •Resource limits defined
- •Health checks configured
Common Polaris Issues:
- •Missing resource limits → Add requests/limits in composition
- •No health checks → Add liveness/readiness probes
- •Running as root → Add securityContext with non-root user
- •Privileged containers → Remove privileged: true unless required
Step 3: kube-linter Validation
kube-linter lint /tmp/rendered.yaml
Expected: Clean output with no errors
Common kube-linter Issues:
- •Missing liveness/readiness probes
- •No resource limits
- •Incorrect label schemas
- •Deprecated API versions
Step 4: Datree Policy Check
datree test /tmp/rendered.yaml --ignore-missing-schemas
Expected: No policy violations (warnings acceptable if documented)
Common Datree Issues:
- •Missing labels (app.kubernetes.io/*)
- •Incorrect image tags (using 'latest')
- •Missing owner references
- •Network policy gaps
Security Validation Checklist
Before committing composition changes:
- • Composition renders successfully without errors
- • Polaris score is 85+ with no critical issues
- • kube-linter passes with no errors
- • Datree policy check passes (or warnings documented)
- • Resource limits are defined for all containers
- • Health checks (liveness/readiness) are configured
- • Security contexts are properly set
- • No privileged containers (unless justified)
- • Images use specific tags (not 'latest')
- • Network policies are defined (where applicable)
Rendered Output Analysis
Inspect Resources
Count resources by kind:
grep "^kind:" /tmp/rendered.yaml | sort | uniq -c
Extract specific resource:
# Get Deployment yq 'select(.kind == "Deployment")' /tmp/rendered.yaml # Get Service yq 'select(.kind == "Service")' /tmp/rendered.yaml # Get HTTPRoute yq 'select(.kind == "HTTPRoute")' /tmp/rendered.yaml
Check readiness annotations:
# Find resources marked as ready grep -B 5 'krm.kcl.dev/ready: "True"' /tmp/rendered.yaml
Verify Resource Correctness
Deployment checks:
# Check replicas yq 'select(.kind == "Deployment") | .spec.replicas' /tmp/rendered.yaml # Check image yq 'select(.kind == "Deployment") | .spec.template.spec.containers[0].image' /tmp/rendered.yaml # Check resource limits yq 'select(.kind == "Deployment") | .spec.template.spec.containers[0].resources' /tmp/rendered.yaml
Service checks:
# Check service type yq 'select(.kind == "Service") | .spec.type' /tmp/rendered.yaml # Check ports yq 'select(.kind == "Service") | .spec.ports' /tmp/rendered.yaml
HTTPRoute checks:
# Check hostnames yq 'select(.kind == "HTTPRoute") | .spec.hostnames' /tmp/rendered.yaml # Check backend refs yq 'select(.kind == "HTTPRoute") | .spec.rules[0].backendRefs' /tmp/rendered.yaml
Detecting Duplicate Resources
Issue: KCL mutation patterns can cause duplicate resources (see kcl-composition-validator skill)
Detection:
# Count Deployments (should match expected count) grep -c "kind: Deployment" /tmp/rendered.yaml # Count Services grep -c "kind: Service" /tmp/rendered.yaml # Find duplicate resource names grep "name:" /tmp/rendered.yaml | sort | uniq -d
If duplicates found:
- •Check KCL code for mutation patterns
- •Use
kcl-composition-validatorskill for detailed guidance - •Refactor to use inline conditionals
- •Re-render and verify
Development Workflow
Quick Iteration Cycle
When developing new composition features:
# 1. Make changes to KCL composition vim infrastructure/base/crossplane/configuration/kcl/app/main.k # 2. Quick render test cd infrastructure/base/crossplane/configuration crossplane render examples/app-complete.yaml app-composition.yaml functions.yaml \ --extra-resources examples/environmentconfig.yaml > /tmp/test.yaml # 3. Check output less /tmp/test.yaml # 4. Iterate until correct
When changes look good:
# 5. Run security validation polaris audit --audit-path /tmp/test.yaml --format=pretty kube-linter lint /tmp/test.yaml datree test /tmp/test.yaml --ignore-missing-schemas # 6. Run complete validation (includes KCL formatting/syntax) ./scripts/validate-kcl-compositions.sh
Testing Different Scenarios
Test with minimal configuration:
crossplane render examples/app-basic.yaml app-composition.yaml functions.yaml \ --extra-resources examples/environmentconfig.yaml > /tmp/minimal.yaml
Test with complete configuration:
crossplane render examples/app-complete.yaml app-composition.yaml functions.yaml \ --extra-resources examples/environmentconfig.yaml > /tmp/complete.yaml
Compare outputs:
diff -u /tmp/minimal.yaml /tmp/complete.yaml | less
Creating Custom Test Examples
Create a custom claim for testing:
# /tmp/my-test-app.yaml
apiVersion: cloud.ogenki.io/v1alpha1
kind: App
metadata:
name: test-app
namespace: apps
spec:
image: nginx:1.25
replicas: 3
database:
enabled: true
size: small
autoscaling:
enabled: true
minReplicas: 2
maxReplicas: 5
Render custom claim:
cd infrastructure/base/crossplane/configuration crossplane render /tmp/my-test-app.yaml app-composition.yaml functions.yaml \ --extra-resources examples/environmentconfig.yaml > /tmp/my-test-rendered.yaml
Troubleshooting Rendering Issues
Issue: Composition Not Found
Symptom: Error: composition not found
Fix:
- •Ensure you're in
infrastructure/base/crossplane/configuration/directory - •Verify composition file exists and path is correct
- •Check composition file syntax with
yqorkubectl
Issue: Function Not Found
Symptom: Error: function not found or unknown function
Fix:
- •Verify
functions.yamlexists in the same directory - •Check function images are accessible
- •Ensure Docker is running (required for
crossplane render)
Issue: EnvironmentConfig Missing
Symptom: References to environment config fail
Fix:
- •Always include
--extra-resources examples/environmentconfig.yaml - •Verify the EnvironmentConfig file exists
- •Check the EnvironmentConfig spec matches composition expectations
Issue: Render Succeeds but Resources Are Wrong
Symptom: Render completes but output doesn't match expectations
Debug steps:
- •Check the claim file matches the composition schema
- •Verify EnvironmentConfig has required fields
- •Review KCL code in
infrastructure/base/crossplane/configuration/kcl/<module>/ - •Check for conditional logic that might affect output
- •Use
kcl-composition-validatorskill to validate KCL syntax
Issue: Docker Not Available
Symptom: Error: cannot connect to Docker daemon
Fix:
# Start Docker sudo systemctl start docker # Or use podman with docker alias alias docker=podman
Integration with Complete Validation
For pre-commit validation, use the comprehensive script:
./scripts/validate-kcl-compositions.sh
This runs:
- •KCL formatting (
kcl fmt) - •KCL syntax validation (
kcl run) - •Crossplane rendering (this skill)
For security validation (additional step):
# After rendering polaris audit --audit-path /tmp/rendered.yaml --format=pretty kube-linter lint /tmp/rendered.yaml datree test /tmp/rendered.yaml --ignore-missing-schemas
Common Validation Scenarios
Scenario 1: Testing New Feature in Composition
# 1. Modify composition KCL vim infrastructure/base/crossplane/configuration/kcl/app/main.k # 2. Render with feature enabled cd infrastructure/base/crossplane/configuration crossplane render examples/app-complete.yaml app-composition.yaml functions.yaml \ --extra-resources examples/environmentconfig.yaml > /tmp/test.yaml # 3. Verify feature resources exist grep "kind:" /tmp/test.yaml | sort | uniq -c # 4. Security validation polaris audit --audit-path /tmp/test.yaml --format=pretty
Scenario 2: Validating Database Integration
# Render SQLInstance crossplane render examples/sqlinstance-complete.yaml sql-instance-composition.yaml functions.yaml \ --extra-resources examples/environmentconfig.yaml > /tmp/db.yaml # Check generated resources yq 'select(.kind == "Cluster")' /tmp/db.yaml # CloudNativePG Cluster yq 'select(.kind == "ScheduledBackup")' /tmp/db.yaml # Backup config yq 'select(.kind == "AtlasMigration")' /tmp/db.yaml # Migrations # Validate security polaris audit --audit-path /tmp/db.yaml --format=pretty
Scenario 3: Testing Environment-Specific Configuration
# Create test EnvironmentConfig cat > /tmp/test-env.yaml <<EOF apiVersion: cloud.ogenki.io/v1alpha1 kind: EnvironmentConfig metadata: name: test-env data: environment: prod region: us-west-2 EOF # Render with custom environment crossplane render examples/app-complete.yaml app-composition.yaml functions.yaml \ --extra-resources /tmp/test-env.yaml > /tmp/prod-app.yaml # Verify environment-specific settings yq 'select(.kind == "Deployment") | .spec.replicas' /tmp/prod-app.yaml
Performance Optimization
Faster Rendering
Render specific composition only (skip others):
# Instead of running full validation script crossplane render examples/app-basic.yaml app-composition.yaml functions.yaml \ --extra-resources examples/environmentconfig.yaml
Use local function images (if available):
# Pull function images once docker pull xpkg.upbound.io/crossplane-contrib/function-kcl:latest # Subsequent renders will use cached image
Selective Validation
During development, validate only what changed:
# Skip Polaris/kube-linter/Datree during rapid iteration # Only run these before commit
Before commit, run all validations:
# Complete validation ./scripts/validate-kcl-compositions.sh # Security validation polaris audit --audit-path /tmp/rendered.yaml --format=pretty kube-linter lint /tmp/rendered.yaml datree test /tmp/rendered.yaml --ignore-missing-schemas
Additional Resources
- •Security validation details: See
security-validation.mdin this skill folder - •Rendering examples and scenarios: See
examples.mdin this skill folder - •Quick command reference: See
quick-reference.mdin this skill folder - •KCL-specific validation: Use
kcl-composition-validatorskill
Success Criteria
Validation is successful when:
- •✅ Composition renders without errors
- •✅ No duplicate resources in output
- •✅ Polaris score is 85+ with no critical issues
- •✅ kube-linter reports no errors
- •✅ Datree policy check passes (or warnings documented)
- •✅ Resources match expected count and structure
- •✅ All required fields are populated correctly