Templates a CRD manifest based on input parameters
Input Schema
| Property | Type | Description | Required |
|---|---|---|---|
| kind | string | - | |
| clusters | array | - | |
| nameParam | string | - | |
| apiVersion | string | - | |
| ownerParam | any | - | |
| parameters | object | - | |
| excludeParams | array | - | |
| namespaceParam | string | - | |
| removeEmptyParams | boolean | - |
Output Schema
| Property | Type | Description | Required |
|---|---|---|---|
| manifest | string | - | |
| filePaths | array | - |
Usage Examples
Generate a basic CRD for a single cluster and publish to GitHub
Creates one custom resource manifest using provided name and namespace, then publishes the workspace to GitHub. Use this for a simple one-cluster deployment alongside a base repo structure set up with fetch:template and published via publish:github.
steps:
- id: fetchBase
action: fetch:template
input:
url: ./skeletons/k8s-manifests
targetPath: .
values:
serviceName: ${{ parameters.name }}
- id: generateCrd
action: terasky:crd-template
input:
ownerParam: ${{ parameters.owner }}
parameters:
team: "payments"
tier: "backend"
replicas: 2
image: "ghcr.io/example/widget:1.2.3"
featureFlags:
enableAudit: true
enableCache: false
nameParam: ${{ parameters.name }}
namespaceParam: ${{ parameters.namespace }}
excludeParams:
- internalNotes
apiVersion: ${{ parameters.apiVersion }} # e.g. "example.com/v1"
kind: ${{ parameters.kind }} # e.g. "Widget"
clusters:
- ${{ parameters.cluster }} # e.g. "dev-us-east-1"
- id: publish
action: publish:github
input:
repoUrl: ${{ parameters.repoUrl }} # e.g. "github.com?owner=acme&repo=widget-crds"
defaultBranch: main
description: "CRD manifests for ${{ parameters.name }}"Generate CRDs for multiple clusters and prune empty fields
Creates manifests for several clusters while removing empty values from the parameter map. Use when some inputs are optional and should not appear in the rendered manifest. The repo is prepared with fetch:template and later published with publish:github.
steps:
- id: scaffoldRepo
action: fetch:template
input:
url: ./skeletons/manifest-repo
targetPath: .
values:
name: ${{ parameters.name }}
- id: crdMultiCluster
action: terasky:crd-template
input:
ownerParam: ${{ parameters.owner }}
parameters:
replicas: ${{ parameters.replicas }} # e.g. 1, 2, 3
config:
url: ${{ parameters.configUrl }} # e.g. "https://api.example.com"
timeoutSeconds: 30
extra: {} # pruned when removeEmptyParams is true
notes: "" # pruned
tags:
- "staging"
nameParam: ${{ parameters.name }}
namespaceParam: ${{ parameters.namespace }}
excludeParams:
- notes
apiVersion: "apps.example.com/v1alpha1"
kind: "Widget"
removeEmptyParams: true
clusters: ${{ parameters.clusters }} # e.g. ["dev", "staging", "prod"]
- id: publishRepo
action: publish:github
input:
repoUrl: ${{ parameters.repoUrl }}
defaultBranch: main
description: "Multi-cluster CRD manifests for ${{ parameters.name }}"Exclude non-spec inputs and publish to GitLab
Generates a manifest while excluding fields not meant to be rendered into the CRD. Publishes to GitLab using publish:gitlab after initializing the workspace with fetch:template.
steps:
- id: init
action: fetch:template
input:
url: ./skeletons/k8s-crd-repo
targetPath: .
values:
component: ${{ parameters.name }}
- id: crdExclude
action: terasky:crd-template
input:
ownerParam: ${{ parameters.owner }}
parameters:
replicas: 1
image: "registry.gitlab.com/acme/${{ parameters.name }}:0.4.0"
rolloutStrategy: "RollingUpdate"
debug: ${{ parameters.debug }} # exclude this below
documentationUrl: ${{ parameters.docsUrl }}
nameParam: ${{ parameters.name }}
namespaceParam: ${{ parameters.namespace }}
excludeParams:
- debug
- documentationUrl
apiVersion: "platform.acme.io/v1"
kind: "RuntimeConfig"
clusters:
- "dev-eu-west-1"
- "prod-eu-west-1"
- id: publishGitlab
action: publish:gitlab
input:
repoUrl: ${{ parameters.repoUrl }} # e.g. "gitlab.com?owner=platform&repo=runtime-configs"
defaultBranch: main
description: "RuntimeConfig CRDs for ${{ parameters.name }}"Template a ServiceMonitor CRD with realistic spec fields
Creates a ServiceMonitor custom resource for Prometheus Operator across two clusters. This is useful for exposing service metrics with a known CRD type, combined with fetch:template and publish:github.
steps:
- id: baseFiles
action: fetch:template
input:
url: ./skeletons/observability-repo
targetPath: .
values:
service: ${{ parameters.name }}
- id: serviceMonitor
action: terasky:crd-template
input:
ownerParam: ${{ parameters.owner }}
parameters:
selector:
matchLabels:
app.kubernetes.io/name: ${{ parameters.name }}
namespaceSelector:
matchNames:
- ${{ parameters.namespace }}
endpoints:
- port: "http-metrics"
interval: "30s"
path: "/metrics"
nameParam: "${{ parameters.name }}-sm"
namespaceParam: ${{ parameters.namespace }}
excludeParams: []
apiVersion: "monitoring.coreos.com/v1"
kind: "ServiceMonitor"
removeEmptyParams: true
clusters:
- "dev-us-central1"
- "prod-us-central1"
- id: publishObs
action: publish:github
input:
repoUrl: ${{ parameters.repoUrl }}
defaultBranch: main
description: "ServiceMonitor resources for ${{ parameters.name }}"Environment-suffixed names and cluster fan-out
Appends the environment to the resource name and generates one manifest per cluster. Use this pattern when the same CRD should be deployed with environment-qualified names. The workspace is bootstrapped with fetch:template and published via publish:github.
steps:
- id: prep
action: fetch:template
input:
url: ./skeletons/crd-repo
targetPath: .
values:
env: ${{ parameters.environment }}
- id: crdEnvFanOut
action: terasky:crd-template
input:
ownerParam: ${{ parameters.owner }}
parameters:
image: "ghcr.io/acme/${{ parameters.name }}:${{ parameters.version }}"
replicas: ${{ parameters.replicas }}
resources:
requests:
cpu: "100m"
memory: "128Mi"
limits:
cpu: "500m"
memory: "256Mi"
debug: false
nameParam: "${{ parameters.name }}-${{ parameters.environment }}"
namespaceParam: ${{ parameters.namespace }}
excludeParams:
- debug
apiVersion: "apps.example.com/v1"
kind: "Widget"
clusters:
- "dev-us1"
- "stg-us1"
- "prod-us1"
- id: publishManifests
action: publish:github
input:
repoUrl: ${{ parameters.repoUrl }}
defaultBranch: main
description: "Environment-specific CRDs for ${{ parameters.name }}"