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.mdto anykestra.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_worldnamespace: 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.
Variables are no longer rendered recursively. See the migration guide for details.
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_variablenamespace: company.team
variables: time: "{{ now() }}"
tasks: - id: log type: io.kestra.plugin.core.log.Log message: "{{ render(vars.time) }}"Without render(), an expression-valued variable resolves to the literal string rather than the evaluated expression.
Set or modify variables at runtime
The SetVariables task updates variables in the execution context. Later tasks see the new values immediately:
id: variables_demonamespace: 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.childVariable 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: varsnamespace: 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?