Skip to main content

XRD Annotations Reference

This document provides a complete reference of annotations that control how Crossplane XRDs are transformed into Backstage templates.

Overview​

The ingestor plugin uses annotations on XRDs to control template generation, metadata, and behavior. Annotations provide a declarative way to customize the transformation without modifying code.

Template Selection Annotations​

These annotations control which Handlebars templates are used during transformation.

backstage.io/template​

Purpose: Specifies the main Backstage Template entity structure template.

Default: default

Location: templates/backstage/{value}.hbs

Example:

apiVersion: apiextensions.crossplane.io/v2
kind: CompositeResourceDefinition
metadata:
name: databases.platform.io
annotations:
backstage.io/template: "default"

Use Cases:

  • Use default for standard Crossplane resource templates
  • Create custom template for specific entity structures
  • Override metadata, tags, or spec sections

openportal.dev/template-api​

Purpose: Specifies the API documentation entity template.

Default: default

Location: templates/api/{value}.hbs

Example:

metadata:
annotations:
openportal.dev/template-api: "openapi-v3"

Use Cases:

  • Generate OpenAPI documentation from XRD schema
  • Customize API entity structure
  • Add specific documentation sections

openportal.dev/template-parameters​

Purpose: Specifies the template for scaffolder form parameters.

Default: default

Location: templates/parameters/{value}.hbs

Example:

metadata:
annotations:
openportal.dev/template-parameters: "database"

Use Cases:

  • Custom form layouts for specific resource types
  • Database configuration forms with specialized fields
  • Storage provisioning with capacity calculators
  • Network configuration with CIDR validation

Example Templates:

  • database - Database-specific fields (engine, size, backup settings)
  • storage - Storage provisioning fields (capacity, tier, encryption)
  • network - Network configuration (CIDR, VPC, subnets)

openportal.dev/template-steps​

Purpose: Specifies the template for scaffolder workflow steps.

Default: default

Location: templates/steps/{value}.hbs

Example:

metadata:
annotations:
openportal.dev/template-steps: "gitops"

Use Cases:

  • GitOps workflows with PR creation
  • Multi-step provisioning (create → configure → validate)
  • Custom approval workflows
  • Integration with external systems

Example Templates:

  • gitops - Create PR for resource definition
  • approval - Add approval step before provisioning
  • multi-cluster - Deploy to multiple clusters
  • validation - Validate and test before creation

Metadata Annotations​

These annotations provide metadata about the XRD and generated entities.

backstage.io/title​

Purpose: Human-readable title for the generated template.

Default: Extracted from XRD name (via extractTitle helper)

Example:

metadata:
annotations:
backstage.io/title: "PostgreSQL Database"

Generated Output:

apiVersion: scaffolder.backstage.io/v1beta3
kind: Template
metadata:
title: PostgreSQL Database

backstage.io/description​

Purpose: Description for the generated template.

Default: "Create and manage {XRD kind} resources"

Example:

metadata:
annotations:
backstage.io/description: "Provision and manage PostgreSQL databases with automatic backups"

Generated Output:

metadata:
description: Provision and manage PostgreSQL databases with automatic backups

backstage.io/owner​

Purpose: Team or user who owns the template.

Default: platform-team

Example:

metadata:
annotations:
backstage.io/owner: "database-team"

Generated Output:

spec:
owner: database-team

Tag Annotations​

openportal.dev/tags​

Purpose: Comma-separated list of tags for categorization.

Default: Only includes crossplane and XRD group

Example:

metadata:
annotations:
openportal.dev/tags: "database,postgresql,storage,production"

Generated Output:

metadata:
tags:
- crossplane
- platform.io
- database
- postgresql
- storage
- production

Best Practices:

  • Use lowercase tags
  • Include resource category (database, storage, network)
  • Include technology (postgresql, mysql, redis)
  • Include environment if applicable (production, development)
  • Keep tags consistent across similar resources

Discovery and Filtering Annotations​

terasky.backstage.io/generate-form​

Purpose: Mark XRD for template generation (legacy label, kept for compatibility).

Type: Label (not annotation)

Example:

metadata:
labels:
terasky.backstage.io/generate-form: "true"

Note: In the current system, all XRDs matching the plugin's configuration are processed. This label is optional but can be used for explicit opt-in.

Complete Example​

Here's a complete XRD with all relevant annotations:

apiVersion: apiextensions.crossplane.io/v2
kind: CompositeResourceDefinition
metadata:
name: postgresqldatabases.platform.io
labels:
terasky.backstage.io/generate-form: "true"
annotations:
# Template Selection
openportal.dev/template: "default"
openportal.dev/template-api: "default"
openportal.dev/template-parameters: "database"
openportal.dev/template-steps: "gitops"

# Metadata
backstage.io/title: "PostgreSQL Database"
backstage.io/description: "Provision managed PostgreSQL databases with automatic backups and monitoring"
backstage.io/owner: "database-team"

# Tags
openportal.dev/tags: "database,postgresql,storage,rds,production"
spec:
group: platform.io
names:
kind: PostgreSQLDatabase
plural: postgresqldatabases
versions:
- name: v1alpha1
schema:
openAPIV3Schema:
type: object
properties:
spec:
type: object
properties:
engine:
type: string
description: PostgreSQL version
enum: ["14", "15", "16"]
default: "16"
storageGB:
type: integer
description: Database storage in GB
minimum: 20
maximum: 16384
default: 100
required:
- engine
- storageGB

This XRD will:

  • Use the database parameters template for a database-specific form
  • Use the gitops steps template to create a PR instead of direct apply
  • Be titled "PostgreSQL Database" in the catalog
  • Be owned by the database-team
  • Be tagged with database-related categories

Custom Template Creation​

To use custom templates referenced by annotations:

  1. Create template directory:

    mkdir -p my-templates/parameters
    mkdir -p my-templates/steps
  2. Create custom template:

    vim my-templates/parameters/database.hbs
  3. Configure plugin (in app-config.yaml):

    kubernetesIngestor:
    crossplane:
    xrds:
    templateDir: ./my-templates
  4. Use in XRD:

    metadata:
    annotations:
    openportal.dev/template-parameters: "database"

CLI Usage with Annotations​

When using the xrd-transform CLI, annotations are automatically processed:

# Transform uses annotations from XRD
./scripts/xrd-transform.sh xrd-with-annotations.yaml

# Override template directory
./scripts/xrd-transform.sh -t custom-templates xrd.yaml

# Generate only specific entity type
./scripts/xrd-transform.sh --only template xrd.yaml

Fallback Behavior​

If an annotation is not specified or references a non-existent template:

  1. Template not found: Falls back to default.hbs in the same directory
  2. No default.hbs: Error is thrown with clear message
  3. Invalid annotation value: Uses default value

Example Error:

Error: parameters template not found: custom-db (and no default.hbs)

Solution: Create the template or remove the annotation to use default.

Validation​

The plugin validates:

  • Template file existence
  • Template syntax (Handlebars compilation)
  • YAML output from templates
  • Required XRD schema fields

Validation errors are logged and prevent entity creation.

See Also​