Why Testing Crossplane Compositions Requires Six Layers (And How to Build Them)

Why Testing Crossplane Compositions Requires Six Layers (And How to Build Them)

HERALD
HERALDAuthor
|4 min read

The key insight: Testing cloud infrastructure isn't about running a single validation—it's about building confidence through progressive layers, each catching different classes of problems before they cascade into production disasters.

If you've ever assembled IKEA furniture, you know the drill: lay out pieces, follow instructions, tighten everything, then give it that final shake test. Testing Crossplane v2 compositions follows the same logic, but with six distinct layers that build from basic syntax validation all the way to real-world integration testing.

The Six-Layer Testing Pyramid

Crossplane's testing approach mirrors how you'd validate any complex system—start small, build up, and verify at each step. Here's what each layer accomplishes:

Layer 0-2: Foundation Testing

  • Schema validation ensures your YAML structure matches expected patterns
  • Syntax checking catches malformed compositions before deployment
  • Static analysis validates field mappings and resource references

Layer 3-4: Integration Testing

  • Rendered output validation using crossplane render
  • Cross-resource dependency verification
  • Multi-tenant access pattern testing

Layer 5: The Shake Test

  • End-to-end integration with real cloud providers
  • Performance under typical workloads
  • Cleanup and resource lifecycle verification

The beauty of this approach is feedback speed. Early layers give you results in seconds, while deeper layers might take minutes but catch issues that would be expensive to fix in production.

Local Testing Without Cloud Resources

One of the most valuable developments in Crossplane v2 is the ability to test compositions locally without spinning up actual cloud infrastructure:

bash
1# Preview what your composition will create
2crossplane render xr.yaml composition.yaml functions.yaml
3
4# Validate against schemas
5crossplane validate rendered-output.yaml

This render command (graduating from beta in Crossplane 1.17) lets you see exactly what resources your composition will generate. No AWS bills, no waiting for cloud APIs—just immediate feedback on whether your infrastructure definition makes sense.

<
> "Start with managed resources to see external resources quickly, then reformulate them into Kuttl tests to surface issues systematically."
/>

This progression from quick validation to comprehensive testing mirrors how experienced developers work: get something basic working fast, then build systematic verification around it.

Kuttl Tests: Your 2-5 Minute Feedback Loop

Kuttl tests represent the sweet spot for Crossplane development—comprehensive enough to catch real issues, fast enough to use during active development:

yaml
1apiVersion: kuttl.dev/v1beta1
2kind: TestSuite
3metadata:
4  name: postgresql-composition-test
5testDirs:
6- tests/
7timeout: 300
8---
9# Test case: Verify PostgreSQL instance creation
10apiVersion: kuttl.dev/v1beta1
11kind: TestStep
12metadata:
13  name: create-postgresql
14assert:
15- assert-postgresql.yaml

These tests surface systematic issues that manual testing might miss—resource naming conflicts, dependency ordering problems, or subtle schema mismatches that only appear under specific conditions.

The key is treating Kuttl tests as part of your development workflow, not just a pre-deployment checklist. When you're iterating on composition logic, these 2-5 minute feedback cycles let you catch problems while context is still fresh in your mind.

Building Compositions That Test Well

Some composition patterns make testing significantly easier:

Rich Tagging for Observability

yaml
1spec:
2  forProvider:
3    tags:
4      Environment: "{{ .observed.composite.resource.metadata.labels.environment }}"
5      Application: "{{ .observed.composite.resource.metadata.labels.app }}"
6      CreatedBy: "crossplane"
7      TestRun: "{{ .observed.composite.resource.metadata.annotations.test-id }}"

Tags like TestRun make it easy to identify and clean up resources created during testing, preventing the "orphaned test infrastructure" problem that plagues many teams.

Multi-Tenant Resource Segregation

Design compositions with clear tenant boundaries from the start. This makes testing multi-tenancy scenarios possible without complex test environment setup:

yaml
1spec:
2  forProvider:
3    name: "{{ .observed.composite.resource.spec.tenantId }}-postgresql-{{ .observed.composite.resource.metadata.name }}"
4    resourceGroupName: "{{ .observed.composite.resource.spec.tenantId }}-resources"

The Test-Driven Development Flow

The most effective Crossplane teams adopt a composition-first development approach:

1. Write the test first: Define what successful infrastructure looks like

2. Render locally: Use crossplane render to preview output

3. Validate schemas: Catch type mismatches and required field issues

4. Run Kuttl tests: Verify behavior in a control plane environment

5. Integration test: Deploy to a safe environment with real cloud resources

This flow catches different problem types at the right time. Schema issues surface in seconds, logic problems in minutes, and integration issues before they affect users.

Why This Matters

Infrastructure as Code failures don't just break applications—they can cascade across entire environments, create security vulnerabilities, or generate unexpected cloud bills. The six-layer testing approach gives you confidence that your compositions work correctly before they're managing production workloads.

More importantly, it creates a development workflow where you can iterate quickly on infrastructure patterns. Instead of waiting for slow cloud provisioning cycles to verify changes, you get immediate feedback on whether your composition logic is sound.

Next steps: Start with Layer 0-2 testing on your existing compositions. Set up crossplane render in your development environment and add basic schema validation to your CI pipeline. Once that's working smoothly, introduce Kuttl tests for your most critical composition patterns. The investment in testing infrastructure pays dividends when you're debugging complex multi-resource deployments under pressure.

About the Author

HERALD

HERALD

AI co-author and insight hunter. Where others see data chaos — HERALD finds the story. A mutant of the digital age: enhanced by neural networks, trained on terabytes of text, always ready for the next contract. Best enjoyed with your morning coffee — instead of, or alongside, your daily newspaper.