Using Templates in Peak-SDK and Peak-CLI

Getting familiar with Templates

For this example, we will use a fictional file called my_image_template.yaml.j2 template, that lives in the templates directory which itself is a top-level directory in a user project.

# my_image_template.yaml.j2
body:
    name: "{{ name }}"
    version: "0.0.1"
    type: "workflow"
    description: "This is an image for a workflow"
    buildDetails:
        source: "upload"
        buildArguments:
            - name: GITHUB_TOKEN
              value: "{{ github_token }}"
            - name: PARAMETER
              value: "{{ parameter }}"
            - name: VARIABLE
              value: "{{ variable }}"
        context: "."
        dockerfilePath: "Dockerfile"
artifact:
    path: "."
    ignore_files:
        - ".gitignore"
        - ".dockerignore"

Using template loader along with your own code.

This example shows how to use the templates in your own code with the sdk clients.

from typing import Any, Optional

import pathlib
from peak.template import load_template

# Setup a helper function to load the template with user parameters


def my_template_generator(
    params: dict[str, Any], file: Optional[pathlib.Path] = None
) -> dict[str, Any]:
    """This function loads the template and returns a dictionary."""
    _file: pathlib.Path = (
        pathlib.Path(__file__).parent.parent.resolve() / "templates/my_template.yaml.j2"
    )

    if file is not None:
        _file = file

    return dict(**load_template(file=_file, params=params))


# Consuming the template with user parameters

parameters = {
    "name": "my-image",
    "github_token": "my_github_token",
    "parameter": "my_parameter",
    "variable": "my_variable",
}

final = my_template_generator(parameters)
print(final)
{
    "body": {
        "name": "my-image",
        "version": "0.0.1",
        "type": "workflow",
        "description": "This is an image for a workflow",
        "buildDetails": {
            "buildArguments": [
                { "name": "GITHUB_TOKEN", "value": "my_github_token" },
                { "name": "PARAMETER", "value": "my_parameter" },
                { "name": "VARIABLE", "value": "my_variable" }
            ],
            "context": ".",
            "dockerfile": "Dockerfile"
        }
    },
    "artifact": { "path": ".", "ignore_files": [".gitignore", ".dockerignore"] }
}

Using template loader with CLI commands.

  • The examples below demonstrate typical template usage within cli commands.

  • But before we get into the examples, let’s take a moment to understand the template loading logic used within the cli commands.

Visualizing the template loading logic used within CLI commands

There is a slight difference when it comes to the handling of templates within the cli as compared to sdk, the following graph shows the logic used to load the templates.

How the CLI loads templates or doesn't.

CLI Template Loading Logic

Usage Examples

Passing parameters in bulk.

  • You can pass parameters in bulk from a json file using the --params-file flag, this will load all the parameters from the file and pass them to the template. for this example we will assume there exists a values file called my_values.json in a directory named values, with the following contents:

{
    "name": "my-image",
    "github_token": "my_github_token",
    "parameter": "my_parameter",
    "variable": "my_variable"
}
peak create images templates/my_image_template.yaml.j2 --params-file values/my_values.json

Passing parameters one by one.

  • You can pass parameters one by one using the --parameter flag, this will load the parameter from the file and pass it to the template. for this example we will pass all parameters one by one.

  • Note: The --params flag can be used multiple times to pass multiple parameters and must always be in the form of --params "key=value"

  • Note: --params will always override --params-file when both are used, similarly --params also have an order of precedence, the last --params flag will always override the previous ones.

peak create images templates/my_image_template.yaml.j2 --params "name=my-image" --params "github_token=my_github_token" --params "parameter=my_parameter" --params "variable=my_variable"
  • Here the first name parameter will be overridden by the last name parameter.

peak create images templates/my_image_template.yaml.j2 --params "name=my-image" --params "github_token=my_github_token" --params "parameter=my_parameter" --params "variable=my_variable" --params "name=my-image-2"

A short guide to parameter conventions used within the CLI.

  • Within the cli you will find two conventions being followed, one where all underlying api parameters are exposed, and the other where the api parameters are nested under a single parent object called body, this is 1:1 with the underlying api methods, so if the underlying api method has a body parameter, then the cli will also have a body parameter, and if the underlying api method exposes the parameters directly, then the cli will also expose the parameters directly.

  • In addition to this, the cli also puts parameters needed for ancillary operations under a single parent object that is named after the operation, for example, if a certain create operation also needs the cli to prepare the artifact for upload, then the cli will expose a artifact parameter alongside the other top level parameters, this is intentionally done to make the cli level operations explicit, fully testable, and traceable within the user’s version control systems.

  • All cli commands have a --help flag that can be used to get more information about the command and its parameters.