There are many ways to use expressions in Kestra. This page will guide you through different types of expressions.

Flow and Execution expressions

Flow and Execution expressions allow using the current execution context to set task properties. For example: name a file with the current date or the current execution id.

The following table lists all the default expressions available on each execution.

ParameterDescription
{{ flow.id }}The identifier of the flow.
{{ flow.namespace }}The name of the flow namespace.
{{ flow.tenantId }}The identifier of the tenant (EE only).
{{ flow.revision }}The revision of the flow.
{{ execution.id }}The execution ID, a generated unique id for each execution.
{{ execution.startDate }}The start date of the current execution, can be formatted with {{ execution.startDate | date("yyyy-MM-dd HH:mm:ss.SSSSSS") }}.
{{ execution.originalId }}The original execution ID, this id will never change even in case of replay and keep the first execution ID.
{{ task.id }}The current task ID
{{ task.type }}The current task Type (Java fully qualified class name).
{{ taskrun.id }}The current task run ID.
{{ taskrun.startDate }}The current task run start date.
{{ taskrun.parentId }}The current task run parent identifier. Only available with tasks inside a Flowable Task.
{{ taskrun.value }}The value of the current task run, only available with tasks wrapped in Flowable Tasks.
{{ taskrun.attemptsCount }}The number of attempts for the current task (when retry or restart is performed).
{{ parent.taskrun.value }}The value of the closest (first) parent task run, only available with tasks inside a Flowable Task.
{{ parent.outputs }}The outputs of the closest (first) parent task run Flowable Task, only available with tasks wrapped in a Flowable Task.
{{ parents }}The list of parent tasks, only available with tasks wrapped in a Flowable Task.
{{ labels }}The executions labels accessible by keys, for example: {{ labels.myKey1 }} .

If execution is created from a Schedule-type trigger, these expressions are also available:

ParameterDescription
{{ trigger.date }}The date of the current schedule.
{{ trigger.next }}The date of the next schedule.
{{ trigger.previous }}The date of the previous schedule.

If execution is created from a Flow-type trigger, these expressions are also available:

ParameterDescription
{{ trigger.executionId }}The ID of the execution that triggers the current flow.
{{ trigger.namespace }}The namespace of the flow that triggers the current flow.
{{ trigger.flowId }}The ID of the flow that triggers the current flow.
{{ trigger.flowRevision }}The revision of the flow that triggers the current flow.

All these expressions can be accessed using the Pebble template syntax {{expression}}:

yaml
id: expressions
namespace: dev

tasks:
  - id: echo
    type: io.kestra.core.tasks.debugs.Return
    format: |
      taskid: {{ task.id }}
      date: {{  execution.startDate | date("yyyy-MM-dd HH:mm:ss.SSSSSS") }}

Environment variables

By default, Kestra allows access to environment variables that start with KESTRA_ unless configured otherwise, see how you can configure environment variables in the variables configuration in your Kestra server settings.

To access an environment variable KESTRA_FOO from one of your tasks, you can use {{ envs.foo }}, the variable's name is the part after the KESTRA_ prefix in lowercase.

Global variables

You can define global variables inside Kestra's configuration files and access them using {{ globals.foo }}.

Flow variables

You can declare variables at the flow level with the variables property, then refer to these variables using the vars.my_variable syntax, for example:

yaml
id: flow_variables
namespace: dev

variables:
  my_variable: "my_value"

tasks:

  - id: print_variable
    type: io.kestra.core.tasks.debugs.Return
    format: "{{ vars.my_variable }}"

Inputs

You can use any flow inputs using inputs.inputName, for example:

yaml
id: render_inputs
namespace: dev

inputs:
  - id: myInput
    type: STRING

tasks:
  - id: myTask
    type: io.kestra.core.tasks.debugs.Return
    format: "{{ inputs.myInput }}"

Secrets

You can retrieve secrets in your flow using the secret() function. Here is an example:

yaml
id: use_secret_in_flow
namespace: dev

tasks:
  - id: myTask
    type: io.kestra.core.tasks.debugs.Return
    format: "{{ secret('MY_SECRET') }}"

Secrets can be provided on both open-source and Enterprise Edition. Check the Secrets documentation for more details.

Namespace variables (EE)

Namespace variables are key-value pairs defined in a YAML configurtion. They can be nested and used in your flows using the dot notation e.g. {{ namespace.myproject.myvariable }}. You can define namespace variables in the Variables tab in the UI.

Namespace variables are scoped to the specific namespace and are inherited by child namespaces. Your flow then refers to these variables using the namespace.your_variable syntax, for example:

yaml
id: namespace_variables
namespace: dev

tasks:
  - id: myTask
    type: io.kestra.core.tasks.debugs.Return
    format: "{{ namespace.your_variable }}"

However, note that if your namespace variable contains Pebble expressions like e.g. {{ secret('GITHUB_TOKEN') }}, you must use the render function to render the variable. Assuming the following code being added to the Variables tab in a Namespace UI:

yaml
github:
  token: "{{ secret('GITHUB_TOKEN') }}"

To reference the github.token variable in your flow, you must use the render function:

yaml
id: recursive_namespace_variables_rendering
namespace: dev
tasks:
  - id: myTask
    type: io.kestra.core.tasks.debugs.Return
    format: "{{ render(namespace.github.token) }}"

The render() function is required to parse Namespace or Flow variables that contain Pebble expressions, as this function allows for recursive rendering. If you don't use the render function, the variable will be rendered as a string, and the Pebble expressions within the variable will not be evaluated.

Outputs

You can use any task output attributes using "{{ outputs.taskId.outputAttribute }}" where:

  • the taskId is the ID of the task.
  • the outputAttribute is the attribute of the task output you want to use; each task can emit various output attributes — check the task documentation for the list of output attributes for any given task.

Example of a flow using outputs to pass data between tasks:

yaml
id: pass_data_between_tasks
namespace: dev

tasks:
    - id: first
      type: io.kestra.core.tasks.debugs.Return
      format: First output value

    - id:
      type: io.kestra.core.tasks.debugs.Return
      format: Second output value

    - id: print_both_outputs
      type: io.kestra.core.tasks.log.Log
      message: |
        First: {{ outputs.first.value }}
        Second: {{ outputs['second-task'].value }}

Pebble templating: example

The example below will parse the Pebble expressions within the variables based on the inputs and trigger values. Both variables use the Null-Coalescing Operator to use the first non-null value.

Here, the first variable trigger_or_yesterday will evaluate to a trigger.date if the flow runs on schedule. Otherwise, it will evaluate to the yesterday's date by using the execution.startDate minus one day.

The second variable input_or_yesterday will evaluate to the mydate input if it's provided. Otherwise, it will evaluate to the yesterday's date — again, using the execution.startDate and subtracting one day with the help of the dateAdd function.

yaml
id: render_complex_expressions
namespace: dev

inputs:
  - id: mydate
    type: DATETIME
    required: false

variables:
  trigger_or_yesterday: "{{ trigger.date ?? (execution.startDate | dateAdd(-1, 'DAYS')) }}"
  input_or_yesterday: "{{ inputs.mydate ?? (execution.startDate | dateAdd(-1, 'DAYS')) }}"

tasks:
  - id: yesterday
    type: io.kestra.core.tasks.log.Log
    message: "{{ render(vars.trigger_or_yesterday) }}"

  - id: input_or_yesterday
    type: io.kestra.core.tasks.log.Log
    message: "{{ render(vars.input_or_yesterday) }}"

Note how we use the render function to render the variables. This function is required when you want to render a variable that contains Pebble expressions, allowing for recursive rendering. If you don't use the render function, the variable will be rendered as a string, and the Pebble expressions within the variable will not be evaluated.

Pebble templating: deep dive

Pebble templating offers a myriad of ways to parse expressions.