Context variables
Context variables are the data you can reference inside Liquid expressions in a workflow. Every execution gets the same core set. Some variables are only populated in certain contexts (for example, foreach.item exists only inside a foreach loop).
This page is the canonical reference. For the mental model and the {{ }} vs. ${{ }} distinction, refer to Templating engine.
Values provided at workflow invocation time. The location of the inputs block in the YAML depends on your version. On stack 9.4 and earlier, inputs sits at the top level of the workflow. On stack 9.5+ and on serverless, inputs sits inside the manual trigger. Refer to Workflow anatomy for the full reference. The reference form {{ inputs.<name> }} is the same in either placement.
inputs:
- name: service_name
type: string
required: true
steps:
- name: search
type: elasticsearch.esql.query
with:
query: "FROM logs-* | WHERE service.name == \"{{ inputs.service_name }}\""
triggers:
- type: manual
inputs:
- name: service_name
type: string
required: true
steps:
- name: search
type: elasticsearch.esql.query
with:
query: "FROM logs-* | WHERE service.name == \"{{ inputs.service_name }}\""
Constants declared at the top of the workflow. Evaluated once at workflow load. They can't reference other context (no inputs, no steps).
consts:
threshold: 70
slack_channel: "#soc-oncall"
steps:
- name: notify
type: slack.postMessage
with:
channel: "{{ consts.slack_channel }}"
text: "Threshold {{ consts.threshold }} exceeded."
The output produced by a previous step. Shape depends on the step type. Refer to each step's reference for what it returns.
steps:
- name: search
type: elasticsearch.search
with: { index: "logs-*", size: 1 }
- name: summarize
type: console
with:
message: "First hit: {{ steps.search.output.hits.hits[0]._id }}"
Error details if the step failed and its on-failure: continue caught the error. null if the step succeeded. Refer to Pass data and handle errors for the continue strategy.
- name: flaky_call
type: http
on-failure:
continue: true
with: { url: "https://flaky.example" }
- name: handle
type: if
condition: "steps.flaky_call.error : null"
steps: [ ... ]
else: [ ... ]
- success path
- failure path (steps.flaky_call.error has detail)
The trigger payload. Shape depends on the trigger type:
| Trigger | event.* structure |
|---|---|
manual |
{} (empty — use inputs.* instead) |
scheduled |
{} (empty) |
alert |
event.alerts (array of alert documents), event.rule (rule metadata), event.spaceId, event.params.* (params from the rule's action configuration) |
workflows.failed |
event.spaceId, event.timestamp, event.workflow.{id, name, spaceId, isErrorHandler}, event.execution.{id, startedAt, failedAt}, event.error.{message, stepId, stepName, stepExecutionId} |
For the full workflows.failed payload, refer to Event-driven triggers.
Alert trigger example:
- name: log
type: console
with:
message: |
Got {{ event.alerts | size }} alerts from rule "{{ event.rule.name }}".
First host: {{ event.alerts[0].host.name }}
Metadata about the current workflow execution.
| Field | Contains |
|---|---|
execution.id |
Execution ID. |
execution.startedAt |
ISO timestamp of start. |
execution.isTestRun |
true if run from the editor's Test button. |
execution.executedBy |
UID of the user or system that invoked the workflow. |
execution.triggeredBy |
Which trigger initiated this execution (manual, scheduled, alert, workflows.failed). |
execution.url |
Deep link to the execution view in Kibana. |
execution.compositionDepth |
0 for a top-level invocation. Increments by 1 for each workflow.execute level. |
execution.parentWorkflowId |
ID of the parent workflow, if this is a composed child execution. |
- name: link
type: console
with:
message: "View this execution: {{ execution.url }}"
Metadata about the workflow itself, not the execution.
| Field | Contains |
|---|---|
workflow.id |
Workflow ID. |
workflow.name |
Workflow name. |
workflow.enabled |
true or false. |
workflow.spaceId |
The Kibana space ID. |
- name: audit
type: elasticsearch.index
with:
index: "workflow-audit"
document:
workflow_id: "{{ workflow.id }}"
workflow_name: "{{ workflow.name }}"
space_id: "{{ workflow.spaceId }}"
execution_id: "{{ execution.id }}"
Available inside a foreach loop body.
| Field | Contains |
|---|---|
foreach.item |
Current iteration's element. |
foreach.index |
Zero-based iteration index. |
foreach.total |
Total items in the array. |
foreach.items |
The full array being iterated. |
- name: process
foreach: "${{ event.alerts }}"
steps:
- name: log
type: console
with:
message: "[{{ foreach.index }}/{{ foreach.total }}] {{ foreach.item._id }}"
Available inside a while loop body. Zero-based iteration counter.
- name: poll
type: while
condition: "steps.check.output.status : 'pending'"
max-iterations: 30
steps:
- name: log
type: console
with: { message: "Attempt {{ while.iteration }}" }
- name: check
type: elasticsearch.search
with: { index: "jobs", size: 1 }
- name: wait
type: wait
with: { duration: "2s" }
Variables set by one or more data.set steps. Global within the workflow execution. Later data.set steps can overwrite earlier values.
- name: init
type: data.set
with:
service: "checkout"
region: "us-east"
- name: query
type: elasticsearch.esql.query
with:
query: "FROM logs-{{ variables.region }}-* | WHERE service.name == \"{{ variables.service }}\""
Current timestamp as an ISO 8601 string. Evaluated per reference, so repeated uses in the same expression will match.
- name: index_row
type: elasticsearch.index
with:
index: "events"
document:
at: "{{ now }}"
formatted: "{{ now | date: '%Y-%m-%d %H:%M' }}"
Base URL of the Kibana instance. Useful for building deep links in notifications.
- name: notify
type: slack.postMessage
with:
channel: "#soc"
text: |
Case created: <{{ kibanaUrl }}/app/security/cases/{{ steps.create_case.output.case.id }}|Open in {{kib}}>
- Templating engine: How Liquid expressions evaluate these variables.
- Liquid filters: Transformations you can apply to any variable.
- Cheat sheet: The condensed version of this table.
- Steps overview: Each step's reference documents what its
outputcontains.