Patterns
Categories:
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),
},
],
}