The Blueprint

3 min read

A Blueprint is one YAML file that describes an operator: the CRDs it reconciles and what each of their CRs becomes. Inrun installs no CRDs of its own; in a cluster the Blueprint is a ConfigMap (inrun generate configmap), so the only CRDs in the API server are the ones you defined.

apiVersion: inrun.dev/v1
kind: Blueprint
metadata:
  name: hello-website
  version: 0.1.0
spec:
  crds:
    website:
      crdFile: ./manifests/crd.yaml
      operatorBox:
        reconcile:
          onCreate:
            deployments:
              - name: "{{ .metadata.name }}"
                image: "{{ .spec.image }}"
        emit:
          status:
            fields:
              - path: phase
                value: Running

Top level

KeyHolds
metadataname, version, author, description, tags
spec.crdsone entry per CRD, keyed by a short name
spec.importsModules whose resources this Blueprint takes in
spec.finalizersfinalizers added to every CR, besides Inrun’s own
importsother Blueprints and Stacks to merge in: from the registry, files or Helm
functionsyour own template functions, beside the built-in ones
presetsnamed settings (resources, probes, autoscaling, PDBs…) templates can refer to
securitydeletion and namespace protection, admission and conversion webhooks
gatewaythe gateway’s endpoint, API, tokens and clusters
lifecyclematurity, compatibility and deprecation, for registry consumers
policywhat a Stack accepts from its imports (policy.lifecycle.minMaturity)
publishwhat inrun push publishes to a registry

A CRD entry

KeyHolds
crdFile / apiTypesthe CRD: a manifest, or group, version, kind and plural (apiTypes.location makes it typed)
operatorBoxhow CRs are reconciled, in five blocks (below)
servehow callers reach it through the gateway
admissionvalidation, mutation and conversion rules
migratemoving stored CRs to another CRD (migrate.to), scoped by migrate.selection; a field’s move to a new path is serve.fields[*].migrate.from (../Migration)
dependsOnCRDs that must be ready first
labels, annotationsset on the CRD’s CRs
enabledturn an entry off without deleting it

The operatorBox blocks, in the order a reconcile meets them:

BlockDecides
observewhat else triggers a reconcile: watched kinds, Kubernetes events, cross-CRD reads
preReconcilewhether to reconcile now (when / or gates)
runtimeallowed and restricted namespaces, finalizers, deletion protection, worker autoscale, cleanup
reconcilethe reconciler (templates, hooks, a constructor or a remote endpoint) with args, external, managedResources, prune, requeue, and its workers, queue and resync
emitstatus fields and events written back to the CR

Templates and functions

Any string value can be a Go template over the CR ({{ .spec.image }}), the results of reconcile.external calls (.external.<name>), cross-CRD reads, and runtime context (.inrun.namespace). Functions are what those templates can call: Kubernetes-aware helpers (pod readiness, job completion, HPA, quantities, cron, semver…) from kel, and your own from functions:. inrun functions lists and searches them.

Validation

inrun validate checks a Blueprint block by block, in the order above, and prints the RBAC it needs with --full. The runtime and the gateway run the same validation at startup; a Blueprint that fails it never starts.

Blueprints, Stacks and Modules

  • A Module is a reusable set of resources with named inputs, which a Blueprint imports into a CRD’s reconciler.
  • A Stack composes several Blueprints and Modules into one operator.
  • inrun push and inrun pull move them through a registry.