Skip to content
Sohaib Iftikhar edited this page Oct 14, 2019 · 27 revisions

Templates Directory

On startup, Cluster Broccoli tries to read job templates from the templates directory. The default location is templates, but it can be configured by setting broccoli.templates.storage.fs.path.

The directory must contain one sub-directory for each template. These template directories contain a template for a Nomad job (template.json) and an optional file with meta information (template.conf).

Example Directory Layout

templates
├── http-server
│   ├── template.conf
│   └── template.json
├── jupyter
│   └── template.json
└── zeppelin
    ├── template.conf
    └── template.hcl

Template Definition

Nomad JSON Template File

The template file is a Jinja2 template of a Nomad job file in JSON format. In order to allow for customization (e.g. launching multiple instances of the same job with different names or settings), you can add parameters. A parameter is enclosed in two curly brackets ({{...}}). For more details about the template syntax please refer to the Jinja2 and Jinjava documentation.

Each template has to have at least a parameterized job ID:

{
    "Job": {
        "Region": "global",
        "ID": "{{id}}",
        "Name": "{{id}}",
        ...
    }
}

For your convenience you can write the job in HCL syntax and convert it using nomad run -output template.hcl > template.json.

Note: Nomad jobs have a template stanza that uses Consul Template. Both Jinja2 and Consul Template use curly brackets for variables by default. To resolve the conflict between template engines, one can use Nomad's LeftDelim and RightDelim parameters to change Consul Template's syntax (requires Nomad >= 0.5.5).

Nomad HCL Template File

Alternatively, if you are using a nomad version >= 0.8.3 you can write HCL templates directly with the same templating syntax as above. The order of picking templates from the folder is: JSON, HCL. So if both files are present the JSON file takes preference. See GitHub issue for more details on how this is implemented. Both templates follow the same rules.

Meta Information File

Currently you can provide two types of meta information about a template: A description and parameter information.

{
  "description": "A simple Python HTTP request handler. This class serves files from the current directory and below, directly mapping the directory structure to HTTP requests.",
  "parameters": {
    "cpu": {
      "default": "100",
      "type": "raw"
    },
    "password": {
      "secret": true,
      "type": "string"
    }
  }
}

Description

The description can be used to briefly describe your template. It will be shown in the user interface to explain what to expect when creating a new instance based on this template.

{
  "description": "This is my great Broccoli template. Apply gently for extreme awesomeness!"
}

Parameter Information

The template file usually contains different parameters. For a parameter to be rendered correctly, it needs to be specified within the template.conf file. Every parameter can have additional properties, however it is required to have a type.

Parameter types

Every parameter has to have a type. The parameter value will be rendered according to the type.

{
  "parameters": {
    "password": {
      "type": "string"
    }
  }
}

The following parameter types are supported:

Type Description Input Output
string Escape quotes to safely use inside JSON string. {{x}} \"foo\"
raw Insert the value without any conversion. Use with caution! {{x}} "foo"
integer 32 bit precision integer number {{x}} 5
decimal 64 bit precision double number {{x}} 10.5
list Lists of any of the simple types {{x}} 10

The list types works a little differently than the others. The actual value that is replaced inside the template file is still a simple type such as a string or an integer. The difference lies in how it is rendered to the in the Broccoli UI. A list parameter type gets rendered as a drop down single select list using which you can restrict the user to the specified values. On submission, the selected value goes back to the backend as a simple type. A list of strings can be specified statically or dynamically. For this reason every list must have a provider. A list type is specified as below:

type {
  name = "list"
  metadata = {
    provider = "StaticIntListProvider"
    values = [1, 2, 3, 4, 5]
  }
}

At present the following list providers are supported:

  • StaticIntListProvider
  • StaticDoubleListProvider
  • StaticStringListProvider

In the future dynamic providers such as those for ldap groups could be added.

Parameter Name

Parameters will be sorted in the UI based on their identifier (e.g. cpu). If a parameter name is given (e.g. CPU Resources, this one will be shown, otherwise the identifier is used.

{
  "parameters": {
    "cpu": {
      "name": "CPU Resources"
    }
  }
}
Default Values

In order to avoid having to fill all parameter values on instance creation you can provide default values.

{
  "parameters": {
    "cpu": {
      "default": "100"
    }
  }
}
Secret Parameters

Sometimes you want parameters to be not visible to non-administrators. In this case you can mark a parameter as 'secret'.

{
  "parameters": {
    "password": {
      "secret": true
    }
  }
}

Template Reloading

In order to load new templates you can either restart Broccoli or send SIGURS2, which will trigger a hot reload.

docker kill -s SIGUSR2 <broccoli-container-id>

Another method to refresh templates was added since #20. The HTTP endpoint /api/v1/templates/refresh can be used to send a request with the following format:

{
    "token": "<refresh_token>",
    "returnTemplates": true
}

The token is the templates.reload-token specified in application.conf. The token is used to authorize the request. The returnTemplates parameter specified if the request should return the newly loaded templates or just a 200 OK response