Configure and Use Dynamic Variables with Pebble Templating

For the complete documentation index, see llms.txt. For a full content snapshot, see llms-full.txt. Append .md to any kestra.io/docs/* URL for plain Markdown.

Variables are key-value pairs that let you reuse values across tasks in a flow, or across multiple flows when stored at the namespace level.

For sensitive values such as API keys, use Secrets instead. For values that must persist across executions or be shared between flows without being embedded in YAML, use the KV Store. For a full comparison, see Choosing where to store sensitive and shared values.

Declaring variables

The variables key at the flow level defines a map of named values. Each variable is accessible in any dynamic property via {{ vars.variable_name }}:

id: hello_world
namespace: company.team
variables:
myvar: hello
numeric_variable: 42
tasks:
- id: log
type: io.kestra.plugin.core.debug.Return
format: "{{ vars.myvar }} world {{ vars.numeric_variable }}"

Rendering

Variables are rendered by the Pebble templating engine, which processes expressions with filters and functions. You can use variables in any task property marked as dynamic.

Dynamic variables

If a variable contains an expression, wrap it with render() when using it in a task. Without it, the expression is treated as a literal string:

id: dynamic_variable
namespace: company.team
variables:
time: "{{ now() }}"
tasks:
- id: log
type: io.kestra.plugin.core.log.Log
message: "{{ render(vars.time) }}"

Set or modify variables at runtime

The SetVariables task updates variables in the execution context. Later tasks see the new values immediately:

id: variables_demo
namespace: company.team
variables:
status: pending
tasks:
- id: update
type: io.kestra.plugin.core.execution.SetVariables
variables:
status: complete
- id: log
type: io.kestra.plugin.core.log.Log
message: "Status is now {{ vars.status }}"

Unset variables

The UnsetVariables task deletes variables from the execution context. It supports dot notation for nested keys:

- id: deleteVariables
type: io.kestra.plugin.core.execution.UnsetVariables
variables:
- state
- ansibleTicket
- nested.child

Variable behavior

Escaping Pebble expressions in variable values

The {% raw %} and {% endraw %} tags prevent a Pebble expression from being evaluated. The following returns the string {{ myvar }} literally:

{% raw %}{{ myvar }}{% endraw %}

See Pebble syntax for details.

Variable resolution order

Inputs are resolved first, before the execution starts; an invalid input value prevents the execution from being created. Inputs are usable within variables, but variables are not usable within inputs (see Dynamic Inputs for the exception).

Triggers are resolved before the execution starts, like inputs, so trigger variables are referenceable inside variables, but inputs are not referenceable within triggers unless they have defaults.

Pebble filters and functions in variable values

Pebble filters and functions work in any dynamic property. A variable can store a format string and apply it with the date filter:

variables:
DATE_FORMAT: "yyyy-MM-dd"
tasks:
- id: formatted
type: io.kestra.plugin.core.debug.Return
format: "{{ execution.startDate | date(vars.DATE_FORMAT) }}"

See the Expressions reference for the full list of available filters and functions.

Nested variables and json() access

json(item.value).key accesses fields on a nested object:

id: vars
namespace: company.myteam
variables:
servers:
- fqn: server01.mydomain.io
user: root
- fqn: server02.mydomain.io
user: guest
tasks:
- id: loop
type: io.kestra.plugin.core.flow.Loop
concurrencyLimit: 0
values: "{{ vars.servers }}"
tasks:
- id: log
type: io.kestra.plugin.core.log.Log
message:
- "{{ item.value }}"
- "{{ json(item.value).fqn }}"
- "{{ json(item.value).user }}"

Was this page helpful?