timoni

first impressions of timoni.sh

SEAN K.H. LIAO

timoni

first impressions of timoni.sh

timoni

While undoubtedly popular for distributing customizable Kubernetes manifests, Helm has somewhat of a bad reputation among those who need to author charts, not least because of the way it fundamentally works: plain text templating of yaml without awareness of what they represent.

Timoni is an attempt to address that: while it shares the same general structure and purpose with Helm, instead of text templating, everything passes through cue as structured data.

From a high level of how it works: timoni.cue pulls together user config from values.cue validated against a #Config typedef, along with an instantiation of objects to apply defined in #Instance merged with concrete config values. For module (chart) authors: #Config defines all the values users can be expected to input, and #Instance.objects defines all the resources to apply. Unlike helm where you typically instantiate the resource directly in its own file, individual resources are defined as typedefs.

As an example:

 1// templates/mydeployment.cue
 2#MyDeployment & appsv1.#Deployment {
 3  #config: #Config // input arg: values from user input
 4	apiVersion: "apps/v1"
 5	kind:       "Deployment"
 6	metadata:   #config.metadata // use values from config / values
 7	spec: appsv1.#DeploymentSpec & {
 8	  // ... actual deployment spec in here
 9  }
10}
11
12// templates/config.cue
13#Config: { // define args to the module
14  // bunch of built in fields
15	metadata: timoniv1.#Metadata & {#Version: moduleVersion}
16	metadata: labels: timoniv1.#Labels
17	metadata: annotations?: timoniv1.#Annotations
18}
19
20#Instance: {
21  config: #Config // args to this instance
22  objects: {
23    // actually use the deployment defined above,
24    // passing through config to it.
25    some_identifier: #MyDeployment & {#config: config}
26  }
27}
28
29// timoni.cue
30// user input, validate against #Config
31values: templates.#Config
32
33timoni: {
34  instance: templates.#Instance & {
35    config: values // pass config to an instance
36  }
37
38  // render out the objects from the instance to apply
39  apply: app: [for obj in instance.objects {obj}] 
40}

thoughts

Timoni is at the same time too dynamic (it allows runtime queries for values), and not flexible enough (the options you have are what the chart author exposed). It's a marginal improvement for chart authors in the natural validation you get from types, but there's not much benefit to end users.