Generating migrations with Jsonnet see history edit this page

Talks about: , , , , and

A migration ladder is just data — a list of version-gated actions. So you can generate it with Jsonnet , publish it once as a Flux artifact with JaaS , and have every StageSet that deploys the app consume it through spec.migrationsSourceRef. One ladder, authored once, shared across namespaces.

The chain mirrors From Jsonnet to a gated rollout , but the rendered artifact is the migrations rather than the manifests:

Jsonnet ladder  →  JaaS (JsonnetSnippet)  →  ExternalArtifact  →  StageSet.migrationsSourceRef

Prerequisites

1. Write the ladder in Jsonnet

The snippet evaluates to a JSON array of migrations — the same shape the ladder file uses, so JaaS’s rendered.json is the ladder. A small helper keeps each entry readable, and the file is trivially parameterizable (per app, per environment) with top-level args:

// migrations/main.jsonnet
local del(name, kind, obj) = {
  name: name,
  delete: { target: { apiVersion: 'v1', kind: kind, name: obj } },
};
[
  {
    name: 'drop-legacy-config',
    to: '2.0.0',
    from: '>=1.0.0',            // explicit operator — a bare "1.0.0" is rejected
    stage: 'db-pre',           // anchors by role; consuming stages declare it
    actions: [del('drop-legacy', 'ConfigMap', 'legacy-config')],
  },
]

Commit it to a Git repo (or push it to an OCI/Bucket source) JaaS can read. Validate it before publishing with the controller’s own checks:

stagesetctl lint-migrations migrations/  # if you render locally; see lint-migrations

2. Render it with JaaS

A JsonnetSnippet points JaaS at the source; JaaS publishes an ExternalArtifact of the same name carrying rendered.json:

apiVersion: jaas.metio.wtf/v1
kind: JsonnetSnippet
metadata:
  name: orders-migrations
  namespace: apps
spec:
  sourceRef:
    kind: GitRepository
    name: orders-migrations-src
    path: ./migrations
  entryFile: main.jsonnet
kubectl apply -f jsonnetsnippet.yaml
kubectl --namespace apps get externalartifact orders-migrations

3. Consume it from a StageSet

Reference the JsonnetSnippet as the migrations source — StageSet resolves the producer to its ExternalArtifact — and declare the db-pre anchor role on the stage the ladder anchors to:

apiVersion: stages.metio.wtf/v1
kind: StageSet
metadata:
  name: orders
  namespace: apps
spec:
  serviceAccountName: orders-deployer
  version:
    fromObject:
      stage: app
      kind: Deployment
      name: orders
  migrationsSourceRef:
    sourceRef:
      kind: JsonnetSnippet
      name: orders-migrations
  stages:
    - name: app
      migrationAnchor: db-pre        # the ladder's stage: db-pre resolves here
      sourceRef:
        kind: JsonnetSnippet
        name: orders

When orders crosses into 2.0.0, the rendered drop-legacy-config migration runs before the app stage. Every other namespace deploying orders references the same orders-migrations snippet output — the ladder lives once, in Jsonnet.

Production notes