Parallel Execution
Understand how Runner executes packages in parallel using DAG-based dependency resolution and Data references.
Overview
Bluebricks Runner uses a DAG (Directed Acyclic Graph) to determine package execution order. Packages execute in parallel when possible, with dependencies resolved through Data references that link package outputs to inputs.
This approach enables:
Efficient execution - Independent packages run concurrently
Output-driven deployment - Only deploy what's needed downstream
Clear dependency tracking - Explicit relationships between packages
Automatic ordering - Runner determines optimal execution sequence
Data References
What Are Data References?
Data references allow packages to use outputs from other packages as inputs:
Data.<packageId>.<outputKey>Components:
Data.- Reserved prefix for cross-package references<packageId>- Unique ID of the source package<outputKey>- Name of the output from source package
Example:
In this example:
eks_clusterdepends onvpc_moduleRunner executes
vpc_modulefirstvpc_idandprivate_subnet_idsoutputs flow toeks_clusterinputs
Data References in Expressions
Data references can be used in expressions with other values:
Runner evaluates these expressions at runtime after dependencies complete.
Plan vs Apply Resolution
Data references behave differently during plan and apply:
During Plan:
Shows that value will change
Indicates value will be available after execution
Dependencies identified but values not yet calculated
During Apply:
Actual values resolved
Passed to dependent packages
Used in expressions and property resolution
DAG Structure
Dependency Graph
Runner builds a DAG (Directed Acyclic Graph) representing package relationships:
How it works:
Identifies all packages in blueprint
Analyzes Data references to find dependencies
Creates execution order that respects dependencies
Executes packages when their dependencies complete
Passes outputs to dependent packages
Example DAG
Consider this blueprint structure:
Resulting DAG:
Execution order:
launch_templateexecutes (no dependencies)s3_bucketandconditional_resourcesexecute in parallel (both depend only on launch_template)
Output-Driven Execution
Only Deploy What's Needed
Runner only executes packages whose outputs are required downstream:
Example:
Execution:
vpc_moduleEXECUTES (output referenced inouts)monitoring_moduleSKIPS (output not referenced anywhere)
This ensures:
Efficient execution - No unused resources deployed
Clear dependency tracking - DAG only includes what's needed
Proper resource management - Resources created only if used
Conditional Execution
Use expressions to conditionally execute packages:
If enable_logging is false:
Package may still execute (depends on internal logic)
But output can conditionally return different values
Data Flow Pattern
Props Flow Down, Data Flows Up
Bluebricks uses a hierarchical data flow model:
Props (Properties):
Flow DOWN from parent to child packages
Set at deployment time
Referenced with
Props.<key>
Data (Outputs):
Flow UP from child packages to parent
Calculated at runtime
Referenced with
Data.<packageId>.<key>
Example Flow
Data Reference Chains
Data references can form chains:
Data flow:
vpcoutputsvpc_idsubnet_modulereceivesvpc_idviaData.vpc.vpc_idsubnet_blueprintexposessubnet_idviaData.subnet_module.subnet_idinstancereceivessubnet_idviaData.subnet_blueprint.subnet_id
Parallel Execution Optimization
Maximizing Parallelism
Design blueprints to maximize parallel execution:
Avoid:
Execution: A → B → C (sequential)
Prefer:
Execution: A, B, C (all parallel if A has no dependents)
Dependency Minimization
Reduce cross-package dependencies:
Less efficient:
Both s3_logs and eks must wait for vpc.
More efficient:
s3_logs and eks can run in parallel if eks doesn't actually need log_bucket immediately.
Group Related Resources
Package related resources together to reduce dependencies:
Internal package dependencies don't block other stacks from executing in parallel.
Best Practices
Data Reference Design
DO:
Use Data references for runtime values only
Reference outputs that will definitely be available
Design packages with clear output contracts
Use descriptive output keys
DON'T:
Reference outputs from packages that may not execute
Create circular dependencies (A depends on B, B depends on A)
Use Data references for static configuration (use Props)
Dependency Management
DO:
Minimize cross-package dependencies
Design for parallel execution where possible
Use Props for configuration, Data for runtime values
Group related resources in packages
DON'T:
Create unnecessary dependencies
Design sequential execution when parallel would work
Mix Props and Data references unnecessarily
Expression Usage
DO:
Use expressions for dynamic value calculation
Combine Data references with strings and Props
Use conditional logic when appropriate
Keep expressions readable
DON'T:
Create complex nested expressions
Use expressions for simple value passing
Rely on side effects in expressions
Testing Parallel Execution
Test your blueprint's execution behavior:
See also
Creating Blueprints -- blueprint structure, inputs, outputs, and data references
expr-lang reference -- expression language used in blueprint values
Blueprint Composition Patterns -- common composition strategies
Last updated
Was this helpful?

