Skip to content

Conversation

@dirien
Copy link
Contributor

@dirien dirien commented Dec 29, 2025

Summary

This PR introduces the Template CRD, a powerful new feature that brings kro-style dynamic CRD generation to the Pulumi Kubernetes Operator. It enables platform engineers to define custom Kubernetes APIs backed by Pulumi infrastructure without writing any controller code.

What is this?

Think of it as Crossplane Compositions meets kro meets Pulumi:

  • Like Crossplane: Define platform abstractions that provision real cloud infrastructure
  • Like kro: Dynamically generate CRDs at runtime from templates
  • Powered by Pulumi: Access 180+ cloud providers, use real programming constructs, and leverage Pulumi's state management

Key Features

  • Dynamic CRD Generation: Define a Template CR, and the operator automatically generates and registers a new CRD
  • Expression Language: Simple ${schema.spec.X} substitution with fallback support (${schema.spec.name || schema.metadata.name})
  • External Packages: Import custom Pulumi components via the packages field
  • Pulumi ESC Integration: Native support for Pulumi ESC environments for secrets management
  • Full Lifecycle: Automatic resource cleanup with destroyOnDelete: true
  • GitOps Ready: Server-Side Apply for proper field ownership
  • Observable: Prometheus metrics for templates, instances, and reconciliation duration

Example

Define a Template:

apiVersion: pulumi.com/v1alpha1
kind: Template
metadata:
  name: city-website
spec:
  crd:
    apiVersion: websites.example.com/v1
    kind: CityWebsite
  schema:
    spec:
      city:
        type: string
        required: true
  resources:
    bucket:
      type: aws:s3:Bucket
      properties:
        bucket: ${schema.metadata.namespace}-${schema.metadata.name}
  outputs:
    websiteUrl: ${bucket.websiteEndpoint}
  stackConfig:
    environment:
      - pulumi-idp/auth

Users can then create instances:

apiVersion: websites.example.com/v1
kind: CityWebsite
metadata:
  name: tokyo
spec:
  city: Tokyo

The operator handles everything: creating the Program CR, Stack CR, managing the Pulumi workspace, and syncing outputs back to the instance status.

Files Changed

  • New Types: operator/api/pulumi/v1alpha1/template_types.go
  • Controller: operator/internal/controller/pulumi/template_controller.go
  • Metrics: operator/internal/controller/pulumi/metrics_template.go
  • Tests: Comprehensive unit tests for controller and metrics
  • Examples: city-website, random-password, do-sample-app templates
  • Documentation: Design doc, API reference, README with examples

Test Plan

  • Unit tests pass (make test)
  • Manual testing with city-website template (S3 static sites)
  • Manual testing with do-sample-app template (DigitalOcean App Platform)
  • Verified destroyOnDelete cleanup works correctly
  • Verified Pulumi ESC environment integration
  • Verified external packages support
  • Verified integer type rendering in nested structures

This feature enables platform engineers to define custom Kubernetes APIs
backed by Pulumi infrastructure without writing controller code.

Key features:
- Define custom CRDs with OpenAPI schemas
- Expression language for value substitution
- External package support for custom Pulumi components
- Pulumi ESC environment integration
- Full lifecycle management with destroyOnDelete
- Prometheus metrics for observability
- Server-Side Apply for GitOps compatibility
- Graceful conflict handling during status updates

Includes:
- Template CRD type definitions
- TemplateReconciler controller implementation
- Prometheus metrics (templates_active, template_instances_total, etc.)
- Comprehensive test suite
- Example templates (city-website, random-password, do-sample-app)
- Design documentation and API reference
@codecov
Copy link

codecov bot commented Dec 29, 2025

Codecov Report

❌ Patch coverage is 23.77193% with 869 lines in your changes missing coverage. Please review.
✅ Project coverage is 46.95%. Comparing base (f2a3513) to head (648159a).
⚠️ Report is 74 commits behind head on master.

Files with missing lines Patch % Lines
.../internal/controller/pulumi/template_controller.go 20.00% 838 Missing and 10 partials ⚠️
operator/cmd/main.go 14.28% 12 Missing ⚠️
operator/api/pulumi/v1alpha1/template_types.go 61.53% 5 Missing ⚠️
...tor/internal/controller/pulumi/metrics_template.go 92.45% 2 Missing and 2 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1087      +/-   ##
==========================================
- Coverage   53.03%   46.95%   -6.09%     
==========================================
  Files          34       37       +3     
  Lines        4646     5214     +568     
==========================================
- Hits         2464     2448      -16     
- Misses       1987     2546     +559     
- Partials      195      220      +25     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

This refactors the Template CRD structure to consolidate CRD identity
fields (apiVersion, kind, plural, scope, etc.) into the schema section
rather than having a separate "crd" section.

Before:
  spec:
    crd:
      apiVersion: example.com/v1
      kind: MyResource
    schema:
      spec: {...}

After:
  spec:
    schema:
      apiVersion: example.com/v1
      kind: MyResource
      spec: {...}

Changes:
- Removed CRDSpec type, merged fields into TemplateSchema
- Made schema.spec optional (only apiVersion and kind are required)
- Updated controller to use template.Spec.Schema for all CRD identity
- Updated validation error messages to use "schema." prefix
- Updated all examples to use the new structure
- Regenerated CRD manifests and documentation
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant