Using Modules
Import reusable workflow units - local or remote - and call their tasks with config and per-call overrides
A module is just a directory with an orchstep.yml - no manifest
required. Import it, then call its tasks like local ones. Modules are how
workflow logic gets shared across projects and teams.
A minimal module
modules/notify/orchstep.yml:
name: notify
desc: "Send a message to a channel"
defaults:
channel: "general"
prefix: "INFO"
tasks:
send:
steps:
- name: emit
func: shell
do: 'echo "[{{ vars.prefix }}] #{{ vars.channel }}: {{ vars.message }}"'
outputs:
line: "{{ result.output }}"Importing and calling it
name: app-workflow
modules:
- name: notifier
source: "./modules/notify"
config:
channel: "deploys" # workflow-wide setting for this module
tasks:
main:
steps:
- name: ping
module: notifier
task: send
with:
message: "build finished"
- name: ping_alerts
module: notifier
task: send
with: # per-call overrides beat config
channel: "alerts"
prefix: "WARN"
message: "disk usage high"Verified output:
[INFO] #deploys: build finished
[WARN] #alerts: disk usage highThe layering: module defaults < import config: < per-call with:.
Module outputs surface on the calling step - steps.ping.line.
Two verified gotchas
with: values are strings. Compare numerically in JavaScript inside
the module (Number(vars.orders) >= Number(vars.min_orders)) rather than
with Go-template gt, which errors on mixed types.
Templates in with: are rendered at the call site - so
with: { min_orders: "{{ vars.min_orders }}" } correctly picks up --var
overrides from the calling workflow.
Remote modules
modules:
- name: release
source: "git:https://github.com/orchstep/orchstep#git-release/v1.0.0"
- name: scanner
source: "@orchstep/demo-security-scan" # registry scope
version: "^1.0.0"See Modules - Registry & Scopes for scope resolution
and the official @orchstep/* catalog.
Run it
orchstep runSee it composed
The Modular Data Pipeline use case builds a multi-region ETL from three modules - including parallel module fan-out and a quality gate with CLI-tunable thresholds.