Patterns

Reference documentation for Etcha Patterns

Patterns are what Etcha uses to build and run Commands.

Build vs Run

Patterns have two separate list of Commands: build and run. build Commands are ran on the local instance when the Pattern is built using etcha build. run Commands are ran on an instance when a Pattern is push, pulled, manually applied via CLI, or triggered via eventsReceive and webhookPaths in a source.

Jsonnet

Patterns are typically written in Jsonnet. A Pattern will have one “entrypoint” file with the extension .jsonnet, such as main.jsonnet. This file should return a JSON object containing the Pattern Properties. It can import other Jsonnet files (with the file extension .libsonnet) or any other file to create the Pattern.

Properties

audience

String, a list of audience values to set in the JWT aud property.

build

A list of Commands to execute when building a JWT.

buildExec

See exec. Specifies a custom exec configuration for the Pattern build Commands. Parent exec configurations must allow overrides for this to work.

buildOutput

Specifies the path and filename for the output build JWT. Defaults to etcha.jwt.

expiresInSec

Integer, specifies the number of seconds from the current time until the JWT expires. Defaults to 0/JWTs do not expire. If a JWT expires, it will not be trusted/ran.

id

String, the ID to set in the JWT jti property.

issuer

String, the Issuer to set in the JWT iss property.

run

A list of Commands to execute when a Pattern is push, pulled, manually applied via CLI, or triggered via eventsReceive and webhookPaths in a source.

runExec

See exec. Specifies a custom exec configuration for the Pattern run Commands. Parent exec configurations must allow overrides for this to work.

runVars

A map of values that will be combined with vars when the Pattern is rendered. These can be set for Patterns by specifying them in the Pattern config, or by using the runVar_ build event.

These are exposed using the Jsonnet native function, getConfig, for rendering these values during a run:

{
  run: [
    id: 'run a thing',
    change: std.native('getConfig')().vars.myVar,
  ],
}

subject

String, the Subject to set in the JWT sub property.

Rendering

Patterns are rendered from Jsonnet everytime they are ran. That means all of the Jsonnet functions, lookups, and environment variables are all executed/evaluated on the current instance that is running the Pattern.

Variables

The native Jsonnet function, getConfig() object, can be used to retrieve the combined exec, targets, and vars for the source. Given a configuration like this:

{
  "sources": {
    "source1": {
      "exec": {
        "command": "/bin/bash"
      },
      "vars": {
        "var1": false,
        "var2": "value"
      }
    }
  },
  "targets": {
    "host1": {
      "hostname": "host1.example.com"
    },
    "host2": {}
  },
  "vars": {
    "var1": true,
    "var2": "original"
  }
}

Running getConfig().exec within a Pattern for the source source1 will render a Jsonnet object like this:

{
  "command": "/bin/bash"
}

Running getConfig().targets within a Pattern for the source source1 will render a Jsonnet object like this:

{
  "host1": {
    "hostname": "host1.example.com"
  },
  "host2": {}
}

Running getConfig().vars within a Pattern for the source source1 will render a Jsonnet object like this:

{
  "var1": false,
  "var2": "value",
  "var3": "original"
}

Variables are rendered both on the builder (during build) and the runner (during run) and may lead to different values. Jsonnet Native Functions, used to inject runtime values via environment variables, files, or HTTP addresses, support caching and can be used to inject the value retrieved during build into the run process:

local vars = {
  a: std.native('get')(myobject, '.a.b[0]'),  // This will cache the value of myobject.a.b[0] at build time for run.
  b: std.native('getCmd')(command='ls -al', cache=true),  // This will cache the value of the `ls -al` output at build time for run.
  c: std.native('getEnv')(key='MY_ENV', cache=true),  // This will cache the value of MY_ENV at build time for run.
  d: std.native('getFile')(path='/etc/os-release', cache=true),  // This will cache the contents of the file `/etc/os-release` at build time for run.
  e: std.native('getRecord')(type='A', name='example.com', cache=true),  // This will cache the DNS resolution of `example.com` at build time for run.
};

{
  run: [
    {
      id: 'use cached things',
      always: true,
      change: 'echo %s > /tmp/vars' % std.manifestJson(vars),
    },
  ],
}