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.
Declaring variables
Define variables under the variables key in a flow and reference them with {{ 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 — otherwise 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) }}"Always wrap expression-valued variables with render() when referencing them in tasks.
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.childFAQ
How do I escape a Pebble expression so it is not evaluated?
Use the {% raw %} and {% endraw %} tags. The following returns the string {{ myvar }} literally:
{% raw %}{{ myvar }}{% endraw %}See Pebble syntax for details.
In what order are inputs and variables resolved?
Inputs are resolved first, before the execution starts — an invalid input value prevents the execution from being created. You can use inputs within variables, but not variables within inputs (see Dynamic Inputs for the exception).
Triggers are resolved like inputs — before the execution starts — so you can reference trigger variables inside variables, but not inputs within triggers unless they have defaults.
Can I transform variables with Pebble expressions?
Yes. Pebble filters and functions work in any dynamic property. For example, use a variable to store a date format 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.
Can I use nested variables?
Yes. Use json(item.value).key to access 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?