Jikkou Templates

Learn how to use Jinja templating to dynamically define resource configuration files in Jikkou.

Template helps you to dynamically define resource definition files from external data.

Template Engine

Jikkou provides a simple templating mechanism based-on Jinjava, a Jinja template engine for Java.

Read the official documentation of Jinja to learn more about the syntax and semantics of the template engine.

How Does It Work ?

Jikkou performs the rendering of your template in two phases:

  1. First, an initial rendering is performed using only the values and labels passed through the command-lines arguments.
    • Thus, it is perfectly OK if your resource file is not initially a valid YAML file.
  2. Then, a second and final rendering is performed after parsing the YAML resource file using the additional values and labels as defined into the YAML resource file.
    • Therefore, it’s important that your resource file is converted into a valid YAML file after the first rendering.

Variables

Jikkou defines a number of top-level variables that are passed to the template engine.

  • values:

    • The values passed into the template through the command-line --values-files and/or --set-value arguments
    • In addition, values can be defined into the application.conf file and directly into the template file using the property template.values.
    • By default, values is empty.
  • labels:

    • The labels passed into the template through the command-line argument: --set-label.
    • In addition, labels can be defined into the template file using the property metadata.labels.
    • By default, labels is empty.
  • system.env:

    • This provides access to all environment variables.
  • system.props:

    • This provides access to all system properties.

Template Values

When using templating, a resource definition file may contain the additional property template. fields:

apiVersion: The api version (required)
kind: The resource kind (required)
metadata:
  labels: The set of key/value pairs that you can use to describe your resource file (optional)
  annotations: The set of key/value pairs automatically generated by the tool (optional)
template:
  values: The set of key/value pairs to be passed to the template engine (optional)
spec: Specification of the resource

Values Data File

Values Data File are used to define all the necessary values (i.e., the variables) to be used for generating a template.

Example

# file: ./values.yaml
topicConfigs:
  partitions: 4
  replicas: 3
topicPrefix: "{{ system.env.TOPIC_PREFIX | default('test', true) }}"
countryCodes:
  - fr
  - be
  - de
  - es
  - uk
  - us

Template Resource File

Example

# file: ./kafka-topics.tpl
apiVersion: 'kafka.jikkou.io/v1beta2'
kind: 'KafkaTopicList'
items:
  { % for country in values.countryCodes % }
  - metadata:
      name: "{{ values.topicPrefix}}-iot-events-{{ country }}"
    spec:
      partitions: { { values.topicConfigs.partitions } }
      replicas: { { values.topicConfigs.replicas } }
      configMapRefs:
        - TopicConfig
    { % endfor % }
---
apiVersion: "core.jikkou.io/v1beta2"
kind: "ConfigMap"
metadata:
  name: TopicConfig
template:
  values:
    default_min_insync_replicas: "{{ values.topicConfigs.replicas | default(3, true) | int | add(-1) }}"
data:
  retention.ms: 3600000
  max.message.bytes: 20971520
  min.insync.replicas: '{% raw %}{{ values.default_min_insync_replicas }}{% endraw %}'

Command

$  TOPIC_PREFIX=local jikkou validate --files topics.tpl --values-files values.yaml 

(Output)

---
apiVersion: "kafka.jikkou.io/v1beta2"
kind: "KafkaTopicList"
metadata:
  labels: { }
  annotations:
    jikkou.io/resource-location: "file:///tmp/jikkou/topics.tpl"
spec:
  topics:
    - metadata:
        name: "local-iot-events-fr"
      spec:
        partitions: 4
        replicas: 3
        configs:
          min.insync.replicas: "2"
          retention.ms: 3600000
          max.message.bytes: 20971520
    - metadata:
        name: "local-iot-events-be"
      spec:
        partitions: 4
        replicas: 3
        configs:
          min.insync.replicas: "2"
          retention.ms: 3600000
          max.message.bytes: 20971520
    - metadata:
        name: "local-iot-events-de"
      spec:
        partitions: 4
        replicas: 3
        configs:
          min.insync.replicas: "2"
          max.message.bytes: 20971520
          retention.ms: 3600000
    - metadata:
        name: "local-iot-events-es"
      spec:
        partitions: 4
        replicas: 3
        configs:
          min.insync.replicas: "2"
          max.message.bytes: 20971520
          retention.ms: 3600000
    - metadata:
        name: "local-iot-events-uk"
      spec:
        partitions: 4
        replicas: 3
        configs:
          min.insync.replicas: "2"
          max.message.bytes: 20971520
          retention.ms: 3600000
    - metadata:
        name: "local-iot-events-us"
      spec:
        partitions: 4
        replicas: 3
        configs:
          min.insync.replicas: "2"
          max.message.bytes: 20971520
          retention.ms: 3600000

Configuration

jinja {
  # Enable/Disable recursive macro calls for rendering
  enableRecursiveMacroCalls = false
}