Modules Examples
uasic module
Section titled โuasic moduleโBasic Module Usage
# Example: Basic Module Usage# Import a reusable module and call its tasks from your workflow.## Any directory with an orchstep.yml can be used as a module -- no# special metadata file is required (implicit module). You reference# a module by giving it a name and a source path.## Then call its tasks with `module: <name>` and `task: <task>`.## Try: orchstep run
name: basic-module-demodesc: "Simple module usage with implicit modules"
# Import the greeting module from a local directorymodules:- name: greetersource: "./modules/greeting"# No config needed -- uses the module's defaults
tasks:main:desc: "Use the greeting module"steps: # Call the module's "greet" task - name: say_hello module: greeter task: greet
# Access the module's step outputs - name: show_result func: shell do: | echo "Module returned: {{ steps.say_hello.greeting }}" echo "Recipient was: {{ steps.say_hello.recipient }}"
- name: explain func: shell do: | echo "" echo "=== Module Basics ===" echo "1. Create a directory with an orchstep.yml" echo "2. Import it: modules: [{name: x, source: ./path}]" echo "3. Call tasks: module: x, task: task_name" echo "4. Read outputs: steps.<step_name>.<output_name>"๐ฆ Loaded module 'greeter' from './modules/greeting'
โญโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎโ ๐ WORKFLOW: basic-module-demoโ ๐ Simple module usage with implicit modulesโฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏ
โโ ๐ฏ TASK: mainโ ๐ก Use the greeting moduleโโโ โก STEP: say_helloโ โโ ๐ INVOKING SUBTASK: greeter.greetโโ ๐ป COMMAND: echo "Hello from the greeting module, World!"โโ ๐ค OUTPUT: โญโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎ โ Hello from the greeting module, World! โฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏโ โโ โ
SUBTASK 'greeter.greet' COMPLETEDโ โ
STEP COMPLETEDโโโ โก STEP: show_resultโ โโ ๐ป COMMAND: echo "Module returned: Hello from the greeting module, World!"echo "Recipient was: World"โ โโ ๐ค OUTPUT:โ โญโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎโ โ Module returned: Hello from the greeting module, World!โ โ Recipient was: Worldโ โฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏโ โ
STEP COMPLETEDโโโ โก STEP: explainโโ ๐ป COMMAND: echo ""echo "=== Module Basics ==="echo "1. Create a directory with an orchstep.yml"echo "2. Import it: modules: [{name: x, source: ./path}]"echo "3. Call tasks: module: x, task: task_name"echo "4. Read outputs: steps.<step_name>.<output_name>"โโ ๐ค OUTPUT: โญโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎ โ โ === Module Basics === โ 1. Create a directory with an orchstep.yml โ 2. Import it: modules: [{name: x, source: ./path}] โ 3. Call tasks: module: x, task: task_name โ 4. Read outputs: steps.<step_name>.<output_name> โฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏโ
STEP COMPLETEDโโ โ
TASK 'main' COMPLETED
โญโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎโ โ
WORKFLOW COMPLETED SUCCESSFULLY โโฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏmodule overrides
Section titled โmodule overridesโModule Overrides with with:
# Example: Module Overrides with `with:`# After setting config at import time, you can further override# values for a specific call using `with:`. This is useful when# different steps need different settings from the same module.## Precedence: with > config > module defaults## Try: orchstep run
name: module-overrides-demodesc: "Override module defaults with 'with:' for specific calls"
modules:- name: dbsource: "./modules/database"config: connection: host: "prod-db.example.com" port: 5432 pool_size: 50 operation: timeout: 60 retry: 5
tasks:main:desc: "Show how 'with:' overrides config per call"steps: # Call 1: Use the import-time config as-is - name: normal_query desc: "Normal query uses config values" module: db task: query # pool_size=50, timeout=60 (from config)
# Call 2: Override specific values for this call only - name: lightweight_query desc: "Quick query with reduced pool and timeout" module: db task: query with: connection: pool_size: 5 # Override for this call only operation: timeout: 10 # Fast timeout for quick queries
# Call 3: Back to normal -- 'with' does not persist - name: another_normal_query desc: "Back to config defaults (with does not persist)" module: db task: query
- name: compare func: shell do: | echo "=== Override Comparison ===" echo "" echo "Normal query: pool={{ steps.normal_query.pool }}, timeout={{ steps.normal_query.timeout }}" echo "Lightweight: pool={{ steps.lightweight_query.pool }}, timeout={{ steps.lightweight_query.timeout }}" echo "Back to normal: pool={{ steps.another_normal_query.pool }}, timeout={{ steps.another_normal_query.timeout }}" echo "" echo "Precedence: with > config > module defaults" echo "'with:' only affects the step it is on."๐ฆ Loaded module 'db' from './modules/database'
โญโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎโ ๐ WORKFLOW: module-overrides-demoโ ๐ Override module defaults with 'with:' for specific callsโฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏ
โโ ๐ฏ TASK: mainโ ๐ก Show how 'with:' overrides config per callโโโ โก STEP: normal_queryโ ๐ Normal query uses config valuesโ โโ ๐ INVOKING SUBTASK: db.queryโโ ๐ป COMMAND: echo "Connecting to prod-db.example.com:5432"echo "Pool size: 50"echo "Timeout: 60s"echo "Retries: 5"echo "Query executed successfully"โโ ๐ค OUTPUT: โญโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎ โ Connecting to prod-db.example.com:5432 โ Pool size: 50 โ Timeout: 60s โ Retries: 5 โ Query executed successfully โฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏโ โโ โ
SUBTASK 'db.query' COMPLETEDโ โ
STEP COMPLETEDโโโ โก STEP: lightweight_queryโ ๐ Quick query with reduced pool and timeoutโ โโ ๐ INVOKING SUBTASK: db.queryโโ ๐ป COMMAND: echo "Connecting to prod-db.example.com:5432"echo "Pool size: 5"echo "Timeout: 10s"echo "Retries: 5"echo "Query executed successfully"โโ ๐ค OUTPUT: โญโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎ โ Connecting to prod-db.example.com:5432 โ Pool size: 5 โ Timeout: 10s โ Retries: 5 โ Query executed successfully โฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏโ โโ โ
SUBTASK 'db.query' COMPLETEDโ โ
STEP COMPLETEDโโโ โก STEP: another_normal_queryโ ๐ Back to config defaults (with does not persist)โ โโ ๐ INVOKING SUBTASK: db.queryโโ ๐ป COMMAND: echo "Connecting to prod-db.example.com:5432"echo "Pool size: 50"echo "Timeout: 60s"echo "Retries: 5"echo "Query executed successfully"โโ ๐ค OUTPUT: โญโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎ โ Connecting to prod-db.example.com:5432 โ Pool size: 50 โ Timeout: 60s โ Retries: 5 โ Query executed successfully โฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏโ โโ โ
SUBTASK 'db.query' COMPLETEDโ โ
STEP COMPLETEDโโโ โก STEP: compareโโ ๐ป COMMAND: echo "=== Override Comparison ==="echo ""echo "Normal query: pool=50, timeout=60"echo "Lightweight: pool=5, timeout=10"echo "Back to normal: pool=50, timeout=60"echo ""echo "Precedence: with > config > module defaults"echo "'with:' only affects the step it is on."โโ ๐ค OUTPUT: โญโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎ โ === Override Comparison === โ โ Normal query: pool=50, timeout=60 โ Lightweight: pool=5, timeout=10 โ Back to normal: pool=50, timeout=60 โ โ Precedence: with > config > module defaults โ 'with:' only affects the step it is on. โฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏโ
STEP COMPLETEDโโ โ
TASK 'main' COMPLETED
โญโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎโ โ
WORKFLOW COMPLETED SUCCESSFULLY โโฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏmodule variaule scoping
Section titled โmodule variaule scopingโModule Variable Scoping
# Example: Module Variable Scoping# Modules are scope-isolated: they cannot see the consumer's variables# and the consumer cannot see the module's internal variables.## Data flows into a module through `config:` and `with:`.# Data flows out through step outputs.## If both the consumer and a module define the same variable name,# each sees its own value -- no collision.## Try: orchstep run
name: module-variable-scopingdesc: "How variables resolve in modules -- scope isolation"
defaults:app_name: "consumer-app"region: "us-east-1"
modules:- name: greetersource: "./modules/greeting"config: # These values are visible inside the module message: "Hello from config" recipient: "Production Team"
tasks:main:desc: "Demonstrate scope isolation between consumer and module"steps: # Consumer sees its own variables - name: consumer_vars desc: "Consumer's own variables" func: shell do: | echo "=== Consumer Scope ===" echo "app_name = {{ vars.app_name }}" echo "region = {{ vars.region }}"
# Module sees config values, not consumer variables - name: module_call desc: "Module sees config values, not consumer vars" module: greeter task: greet
# Consumer can read module outputs but not module internals - name: read_outputs desc: "Consumer reads module outputs" func: shell do: | echo "=== Module Outputs ===" echo "greeting = {{ steps.module_call.greeting }}" echo "recipient = {{ steps.module_call.recipient }}"
# Override for a specific call - name: module_with_override desc: "Use 'with:' to override for this call" module: greeter task: greet with: message: "Overridden greeting" recipient: "Staging Team"
- name: show_override func: shell do: | echo "=== With Override ===" echo "greeting = {{ steps.module_with_override.greeting }}"
- name: summary func: shell do: | echo "" echo "=== Variable Scoping Rules ===" echo " 1. Module cannot see consumer variables" echo " 2. Consumer cannot see module internal variables" echo " 3. Data in: config: and with:" echo " 4. Data out: step outputs" echo " 5. Same variable name in consumer and module = no collision" echo "" echo " Precedence inside module:" echo " with > config > task vars > module defaults"๐ฆ Loaded module 'greeter' from './modules/greeting'
โญโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎโ ๐ WORKFLOW: module-variable-scopingโ ๐ How variables resolve in modules -- scope isolationโฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏ
โโ ๐ฏ TASK: mainโ ๐ก Demonstrate scope isolation between consumer and moduleโโโ โก STEP: consumer_varsโ ๐ Consumer's own variablesโ โโ ๐ป COMMAND: echo "=== Consumer Scope ==="echo "app_name = consumer-app"echo "region = us-east-1"โ โโ ๐ค OUTPUT:โ โญโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎโ โ === Consumer Scope ===โ โ app_name = consumer-appโ โ region = us-east-1โ โฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏโ โ
STEP COMPLETEDโโโ โก STEP: module_callโ ๐ Module sees config values, not consumer varsโ โโ ๐ INVOKING SUBTASK: greeter.greetโโ ๐ป COMMAND: echo "Hello from config, Production Team!"โโ ๐ค OUTPUT: โญโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎ โ Hello from config, Production Team! โฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏโ โโ โ
SUBTASK 'greeter.greet' COMPLETEDโ โ
STEP COMPLETEDโโโ โก STEP: read_outputsโ ๐ Consumer reads module outputsโ โโ ๐ป COMMAND: echo "=== Module Outputs ==="echo "greeting = Hello from config, Production Team!"echo "recipient = Production Team"โ โโ ๐ค OUTPUT:โ โญโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎโ โ === Module Outputs ===โ โ greeting = Hello from config, Production Team!โ โ recipient = Production Teamโ โฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏโ โ
STEP COMPLETEDโโโ โก STEP: module_with_overrideโ ๐ Use 'with:' to override for this callโ โโ ๐ INVOKING SUBTASK: greeter.greetโโ ๐ป COMMAND: echo "Overridden greeting, Staging Team!"โโ ๐ค OUTPUT: โญโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎ โ Overridden greeting, Staging Team! โฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏโ โโ โ
SUBTASK 'greeter.greet' COMPLETEDโ โ
STEP COMPLETEDโโโ โก STEP: show_overrideโ โโ ๐ป COMMAND: echo "=== With Override ==="echo "greeting = Overridden greeting, Staging Team!"โ โโ ๐ค OUTPUT:โ โญโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎโ โ === With Override ===โ โ greeting = Overridden greeting, Staging Team!โ โฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏโ โ
STEP COMPLETEDโโโ โก STEP: summaryโโ ๐ป COMMAND: echo ""echo "=== Variable Scoping Rules ==="echo " 1. Module cannot see consumer variables"echo " 2. Consumer cannot see module internal variables"echo " 3. Data in: config: and with:"echo " 4. Data out: step outputs"echo " 5. Same variable name in consumer and module = no collision"echo ""echo " Precedence inside module:"echo " with > config > task vars > module defaults"โโ ๐ค OUTPUT: โญโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎ โ โ === Variable Scoping Rules === โ 1. Module cannot see consumer variables โ 2. Consumer cannot see module internal variables โ 3. Data in: config: and with: โ 4. Data out: step outputs โ 5. Same variable name in consumer and module = no collision โ โ Precedence inside module: โ with > config > task vars > module defaults โฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏโ
STEP COMPLETEDโโ โ
TASK 'main' COMPLETED
โญโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎโ โ
WORKFLOW COMPLETED SUCCESSFULLY โโฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏmodule with config
Section titled โmodule with configโModule Configuration
# Example: Module Configuration# When importing a module, pass `config:` to override the module's# default variable values. Config is applied at import time and# affects all calls to that module.## Try: orchstep run
name: module-with-config-demodesc: "Module configuration overrides defaults"
# Import the service module with custom configurationmodules:- name: apisource: "./modules/service"config: service: name: "payments-api" port: 9000 replicas: 5 features: cache: true logging: "debug"
tasks:main:desc: "Deploy and check the configured service"steps: # The module sees our config values, not its defaults - name: deploy_api module: api task: deploy
- name: check_api module: api task: status
- name: show_result func: shell do: | echo "Deployed: {{ steps.deploy_api.service_name }}" echo "Port: {{ steps.deploy_api.service_port }}" echo "Replicas: {{ steps.deploy_api.replicas }}" echo "" echo "=== Module Config ===" echo "Module defaults: name=default-service, port=8080, replicas=1" echo "Our config: name=payments-api, port=9000, replicas=5" echo "" echo "Config overrides defaults at import time."๐ฆ Loaded module 'api' from './modules/service'
โญโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎโ ๐ WORKFLOW: module-with-config-demoโ ๐ Module configuration overrides defaultsโฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏ
โโ ๐ฏ TASK: mainโ ๐ก Deploy and check the configured serviceโโโ โก STEP: deploy_apiโ โโ ๐ INVOKING SUBTASK: api.deployโโ ๐ป COMMAND: echo "=== Deploying Service ==="echo "Name: payments-api"echo "Port: 9000"echo "Replicas: 5"echo "Cache: true"echo "Logging: debug"โโ ๐ค OUTPUT: โญโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎ โ === Deploying Service === โ Name: payments-api โ Port: 9000 โ Replicas: 5 โ Cache: true โ Logging: debug โฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏโ โโ โ
SUBTASK 'api.deploy' COMPLETEDโ โ
STEP COMPLETEDโโโ โก STEP: check_apiโ โโ ๐ INVOKING SUBTASK: api.statusโโ ๐ป COMMAND: echo "payments-api is running on port 9000"โโ ๐ค OUTPUT: โญโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎ โ payments-api is running on port 9000 โฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏโ โโ โ
SUBTASK 'api.status' COMPLETEDโ โ
STEP COMPLETEDโโโ โก STEP: show_resultโโ ๐ป COMMAND: echo "Deployed: payments-api"echo "Port: 9000"echo "Replicas: 5"echo ""echo "=== Module Config ==="echo "Module defaults: name=default-service, port=8080, replicas=1"echo "Our config: name=payments-api, port=9000, replicas=5"echo ""echo "Config overrides defaults at import time."โโ ๐ค OUTPUT: โญโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎ โ Deployed: payments-api โ Port: 9000 โ Replicas: 5 โ โ === Module Config === โ Module defaults: name=default-service, port=8080, replicas=1 โ Our config: name=payments-api, port=9000, replicas=5 โ โ Config overrides defaults at import time. โฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏโ
STEP COMPLETEDโโ โ
TASK 'main' COMPLETED
โญโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎโ โ
WORKFLOW COMPLETED SUCCESSFULLY โโฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏnested modules
Section titled โnested modulesโNested Modules
# Example: Nested Modules# Modules can import other modules, creating a dependency chain.# OrchStep resolves the full chain and executes bottom-up.## In this example:# Consumer (this file)# -> app-stack module# -> database module (from the same modules/ directory)## Each layer is scope-isolated. Config flows down through imports;# outputs flow up through step outputs.## Try: orchstep run
name: nested-modules-demodesc: "Composing modules that use other modules"
# Import the top-level module (it imports its own dependencies)modules:- name: stacksource: "./modules/app-stack"config: region: "us-west-2" app_name: "order-service" app_version: "2.1.0"
tasks:main:desc: "Deploy a full application stack through nested modules"steps: # One call triggers the entire chain: # app-stack -> database -> (network if configured) - name: deploy_stack module: stack task: deploy
- name: show_result func: shell do: | echo "=== Deployment Complete ===" echo "Deployment ID: {{ steps.deploy_stack.deployment_id }}" echo "App URL: {{ steps.deploy_stack.app_url }}" echo "Status: {{ steps.deploy_stack.status }}"
- name: explain func: shell do: | echo "" echo "=== Module Nesting ===" echo "Execution chain:" echo " 1. Consumer calls app-stack.deploy" echo " 2. app-stack calls database.query" echo " 3. Each layer is scope-isolated" echo "" echo "Config flows DOWN through module imports." echo "Outputs flow UP through step outputs." echo "" echo "OrchStep tracks nesting depth and warns if" echo "the chain becomes too deep (> 3 levels)."๐ฆ Loaded module 'stack' from './modules/app-stack'๐ฆ Loaded module 'database' from '../database'
โญโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎโ ๐ WORKFLOW: nested-modules-demoโ ๐ Composing modules that use other modulesโฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏ
โโ ๐ฏ TASK: mainโ ๐ก Deploy a full application stack through nested modulesโโโ โก STEP: deploy_stackโ โโ ๐ INVOKING SUBTASK: stack.deployโ โโ ๐ INVOKING SUBTASK: database.queryโโ ๐ป COMMAND: echo "Connecting to db-{{ vars.region }}.internal:5432"echo "Pool size: 20"echo "Timeout: 30s"echo "Retries: 3"echo "Query executed successfully"โโ ๐ค OUTPUT: โญโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎ โ Connecting to db-{{ vars.region }}.internal:5432 โ Pool size: 20 โ Timeout: 30s โ Retries: 3 โ Query executed successfully โฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏโ โโ โ
SUBTASK 'database.query' COMPLETEDโ โโ ๐ป COMMAND: echo "Building order-service:2.1.0"echo "Database: db-{{ vars.region }}.internal"โ โโ ๐ค OUTPUT:โ โญโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎโ โ Building order-service:2.1.0โ โ Database: db-{{ vars.region }}.internalโ โฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏโโ ๐ป COMMAND: echo "Deploying order-service:2.1.0"echo "Region: us-west-2"โโ ๐ค OUTPUT: โญโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎ โ Deploying order-service:2.1.0 โ Region: us-west-2 โฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏโ โโ โ
SUBTASK 'stack.deploy' COMPLETEDโ โ
STEP COMPLETEDโโโ โก STEP: show_resultโ โโ ๐ป COMMAND: echo "=== Deployment Complete ==="echo "Deployment ID: deploy-order-service-001"echo "App URL: https://order-service.us-west-2.example.com"echo "Status: deployed"โ โโ ๐ค OUTPUT:โ โญโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎโ โ === Deployment Complete ===โ โ Deployment ID: deploy-order-service-001โ โ App URL: https://order-service.us-west-2.example.comโ โ Status: deployedโ โฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏโ โ
STEP COMPLETEDโโโ โก STEP: explainโโ ๐ป COMMAND: echo ""echo "=== Module Nesting ==="echo "Execution chain:"echo " 1. Consumer calls app-stack.deploy"echo " 2. app-stack calls database.query"echo " 3. Each layer is scope-isolated"echo ""echo "Config flows DOWN through module imports."echo "Outputs flow UP through step outputs."echo ""echo "OrchStep tracks nesting depth and warns if"echo "the chain becomes too deep (> 3 levels)."โโ ๐ค OUTPUT: โญโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎ โ โ === Module Nesting === โ Execution chain: โ 1. Consumer calls app-stack.deploy โ 2. app-stack calls database.query โ 3. Each layer is scope-isolated โ โ Config flows DOWN through module imports. โ Outputs flow UP through step outputs. โ โ OrchStep tracks nesting depth and warns if โ the chain becomes too deep (> 3 levels). โฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏโ
STEP COMPLETEDโโ โ
TASK 'main' COMPLETED
โญโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎโ โ
WORKFLOW COMPLETED SUCCESSFULLY โโฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏself contained module
Section titled โself contained moduleโSelf-Contained Module
# Example: Self-Contained Module# A module can be a single YAML file that contains everything:# metadata, config schema, exports, and task implementations.## This is ideal for simple, portable modules that you want to# share without a directory structure.## The module file: modules/deploy.yml## Try: orchstep run# Try: orchstep run deploy_with_custom_replicas
name: self-contained-module-demodesc: "Module with full metadata, exports, and config schema in one file"
# Import a single-file module (direct file reference, not a directory)modules:- name: deployersource: "./modules/deploy.yml"config: environment: "staging" registry: "my-registry.example.com"
tasks:# Basic deployment using module defaultsdeploy_basic:desc: "Deploy with default replicas"steps: - name: deploy_app module: deployer task: deploy with: app_name: "user-service" version: "v2.0.0" # replicas omitted -- uses module default (3)
- name: show_result func: shell do: | echo "Deployment ID: {{ steps.deploy_app.deployment_id }}" echo "Status: {{ steps.deploy_app.status }}" echo "Replicas: {{ steps.deploy_app.replicas }}"
# Deployment with all params specifieddeploy_with_custom_replicas:desc: "Deploy with custom replica count"steps: - name: deploy_scaled module: deployer task: deploy with: app_name: "order-service" version: "v3.5.1" replicas: 10
- name: show_result func: shell do: | echo "App: {{ steps.deploy_scaled.app_name }}" echo "Version: {{ steps.deploy_scaled.version }}" echo "Replicas: {{ steps.deploy_scaled.replicas }}"
main:desc: "Run both deployment scenarios"steps: - name: basic task: deploy_basic
- name: custom task: deploy_with_custom_replicas
- name: summary func: shell do: | echo "" echo "=== Self-Contained Modules ===" echo "A single .yml file can contain:" echo " - metadata: name, version, author, license" echo " - config: schema with validation rules" echo " - exports: public task interfaces with params/returns" echo " - tasks: the actual implementation" echo "" echo "Import with: source: ./path/to/module.yml"๐ฆ Loaded module 'deployer' from './modules/deploy.yml'
โญโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎโ ๐ WORKFLOW: self-contained-module-demoโ ๐ Module with full metadata, exports, and config schema in one fileโฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏ
โโ ๐ฏ TASK: mainโ ๐ก Run both deployment scenariosโโโ โก STEP: basicโ โโ ๐ INVOKING SUBTASK: deploy_basic
โโ ๐ฏ TASK: deploy_basicโ ๐ก Deploy with default replicasโโโ โก STEP: deploy_appโ โโ ๐ INVOKING SUBTASK: deployer.deployโโ ๐ป COMMAND: echo "Deploying user-service:v2.0.0"echo "Environment: staging"echo "Registry: my-registry.example.com"echo "Replicas: 3"โโ ๐ค OUTPUT: โญโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎ โ Deploying user-service:v2.0.0 โ Environment: staging โ Registry: my-registry.example.com โ Replicas: 3 โฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏโ โโ โ
SUBTASK 'deployer.deploy' COMPLETEDโ โ
STEP COMPLETEDโโโ โก STEP: show_resultโโ ๐ป COMMAND: echo "Deployment ID: deploy-staging-user-service-001"echo "Status: deployed"echo "Replicas: 3"โโ ๐ค OUTPUT: โญโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎ โ Deployment ID: deploy-staging-user-service-001 โ Status: deployed โ Replicas: 3 โฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏโ
STEP COMPLETEDโโ โ
TASK 'deploy_basic' COMPLETEDโ โโ โ
SUBTASK 'deploy_basic' COMPLETEDโ โ
STEP COMPLETEDโโโ โก STEP: customโ โโ ๐ INVOKING SUBTASK: deploy_with_custom_replicas
โโ ๐ฏ TASK: deploy_with_custom_replicasโ ๐ก Deploy with custom replica countโโโ โก STEP: deploy_scaledโ โโ ๐ INVOKING SUBTASK: deployer.deployโโ ๐ป COMMAND: echo "Deploying order-service:v3.5.1"echo "Environment: staging"echo "Registry: my-registry.example.com"echo "Replicas: 10"โโ ๐ค OUTPUT: โญโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎ โ Deploying order-service:v3.5.1 โ Environment: staging โ Registry: my-registry.example.com โ Replicas: 10 โฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏโ โโ โ
SUBTASK 'deployer.deploy' COMPLETEDโ โ
STEP COMPLETEDโโโ โก STEP: show_resultโโ ๐ป COMMAND: echo "App: order-service"echo "Version: v3.5.1"echo "Replicas: 10"โโ ๐ค OUTPUT: โญโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎ โ App: order-service โ Version: v3.5.1 โ Replicas: 10 โฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏโ
STEP COMPLETEDโโ โ
TASK 'deploy_with_custom_replicas' COMPLETEDโ โโ โ
SUBTASK 'deploy_with_custom_replicas' COMPLETEDโ โ
STEP COMPLETEDโโโ โก STEP: summaryโโ ๐ป COMMAND: echo ""echo "=== Self-Contained Modules ==="echo "A single .yml file can contain:"echo " - metadata: name, version, author, license"echo " - config: schema with validation rules"echo " - exports: public task interfaces with params/returns"echo " - tasks: the actual implementation"echo ""echo "Import with: source: ./path/to/module.yml"โโ ๐ค OUTPUT: โญโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎ โ โ === Self-Contained Modules === โ A single .yml file can contain: โ - metadata: name, version, author, license โ - config: schema with validation rules โ - exports: public task interfaces with params/returns โ - tasks: the actual implementation โ โ Import with: source: ./path/to/module.yml โฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏโ
STEP COMPLETEDโโ โ
TASK 'main' COMPLETED
โญโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎโ โ
WORKFLOW COMPLETED SUCCESSFULLY โโฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏ