Use variables
Here you will find some examples to illustrate the available variables, and how to get the value you need.
Here is a typical payload for variables:
globals:
my-global-string: string
my-global-int: 1
my-global-bool: true
task:
id: float
type: io.kestra.core.tasks.debugs.Return
taskrun:
id: 5vPQJxRGCgJJ4mubuIJOUf
startDate: 2020-12-18T12:46:36.018869Z
attemptsCount: 0
value: value2
parent:
taskrun:
value: valueA
outputs:
int: 1
parents:
- taskrun:
value: valueA
outputs:
int: 1
- taskrun:
value: valueB
outputs:
int: 2
flow:
id: inputs
namespace: io.kestra.tests
execution:
id: 42mXSJ1MRCdEhpbGNPqeES
startDate: 2020-12-18T12:45:28.489187Z
outputs:
my-task-id-1: # standard task outputs
value: output-string
my-task-id-2: # standard task outputs
value: 42
my-each-task-id: # dynamic task (each)
value1: # outputs for value1
value: here is value1
value2: # outputs for value2
value: here is value2
inputs:
file: kestra:///org/kestra/tests/inputs/executions/42mXSJ1MRCdEhpbGNPqeES/inputs/file/application.yml
string: myString
instant: 2019-10-06T18:27:49Z
Common variables
As you can see, there are a lot of common variables that can be used in your flow, some of the most common examples are: {{ execution.id }}
, {{ execution.startDate }}
that allows you to change a file name or SQL query, for example.
Input variables
Input variables are simple to access with {{ execution.NAME }}
, where NAME
is the name of the declared in your flow. The data will be dependent on the type
of the inputs.
One special case for input variables is the FILE
type, where the file is prepended by kestra://
. This means the file is inside the internal Kestra storage. Most tasks will take this kind of URI as a property and will provide the same property output. This type of input variable allows the full file generated by one task to be used in another task.
Outputs variables
One of Kestra's most important abilities is to use all outputs from previous tasks in the next one.
Without dynamic tasks (Each)
This is the simplest and most common way to use outputs in the next task. In order to fetch a variable, just use {{ outputs.ID.NAME }}
where :
ID
is the task idNAME
is the name of the output. Each task type can have any outputs that are documented on the part outputs of their docs. For example, Bash task can have{{ outputs.ID.exitCode }}
,{{ outputs.ID.outputFiles }}
,{{ outputs.ID.stdErrLineCount }}
, etc...
With dynamic tasks (Each)
This option is more complicated since Kestra will change the way the outputs are generated, since there can be multiple tasks with the same id, you will need to use {{ outputs.ID.VALUE.NAME }}
.
Most of the time, using Dynamic Tasks, you will need to fetch the current value of the iteration. This is done easily with {{ taskrun.value }}
.
But what if a more complex flow is built, for example, with each containing 1 task (t1
) to download a file (based on each value), and a second one (t2
) that needs the output of t1
. Such a flow would look something like this:
id: each-sequential-nested
namespace: io.kestra.tests
tasks:
- id: each
type: io.kestra.core.tasks.flows.EachSequential
value: '["s1", "s2", "s3"]'
tasks:
- id: t1
type: io.kestra.core.tasks.debugs.Return
format: "{{task.id}} > {{taskrun.value}}"
- id: t2
type: io.kestra.core.tasks.debugs.Return
format: "{{task.id}} > {{ (get outputs.t1 taskrun.value).value }} > {{taskrun.startDate}}"
- id: end
type: io.kestra.core.tasks.debugs.Return
format: "{{task.id}}"
In this case, you would need to use {{ (get outputs.t1 taskrun.value).value }}
, which means give me from outputs.t1
the index results from taskrun.value
.
With Flowable Task nested.
If you have many Flowable Tasks, it can be complex to use the get
function, and moreover, the taskrun.value
is only available during the direct task from each. If you have any Flowable Tasks after, the taskrun.value
of the first iteration will be lost (or overwritten). To deal with this, we have included the parent
& parents
vars.
This is illustrated in the flow below:
id: each-switch
namespace: io.kestra.tests
tasks:
- id: t1
type: io.kestra.core.tasks.debugs.Return
format: "{{task.id}} > {{taskrun.startDate}}"
- id: 2_each
type: io.kestra.core.tasks.flows.EachSequential
value: '["a", "b"]'
tasks:
# Switch
- id: 2-1_switch
type: io.kestra.core.tasks.flows.Switch
value: "{{taskrun.value}}"
cases:
a:
- id: 2-1_switch-letter-a
type: io.kestra.core.tasks.debugs.Return
format: "{{task.id}}"
b:
- id: 2-1_switch-letter-b
type: io.kestra.core.tasks.debugs.Return
format: "{{task.id}}"
- id: 2-1_each
type: io.kestra.core.tasks.flows.EachSequential
value: '["1", "2"]'
tasks:
- id: 2-1-1_switch
type: io.kestra.core.tasks.flows.Switch
value: "{{taskrun.value}}"
cases:
1:
- id: 2-1-1_switch-number-1
type: io.kestra.core.tasks.debugs.Return
format: "{{parents[0].taskrun.value}}"
2:
- id: 2-1-1_switch-number-2
type: io.kestra.core.tasks.debugs.Return
format: "{{parents[0].taskrun.value}} {{parents[1].taskrun.value}}"
- id: 2_end
type: io.kestra.core.tasks.debugs.Return
format: "{{task.id}} > {{taskrun.startDate}}"
As you can see, the parent
will give direct access to the first parent output and the value of the current one, while the parents[INDEX]
lets go you deeper down the tree.
In the task 2-1-1_switch-number-2
:
{{taskrun.value}}
: mean the value of the task2-1-1_switch
{{parents[0].taskrun.value}}
or{{parent.taskrun.value}}
: mean the value of the task2-1_each
{{parents[1].taskrun.value}}
: mean the value of the task2-1_switch
{{parents[2].taskrun.value}}
: mean the value of the task2_each