Parallel Execution

How Bluebricks builds a dependency graph from your blueprint and executes packages in parallel.

When a run starts, Bluebricks evaluates every package in the blueprint and builds a directed acyclic graph (DAG) based on Data references between packages. Independent packages execute in parallel; dependent packages wait for their inputs.

Data references

Data references let one package consume the outputs of another:

Data.<packageId>.<outputKey>
  • Data. is the reserved prefix for cross-package references

  • <packageId> is the unique ID of the source package

  • <outputKey> is the name of the output

chevron-rightExample JSONhashtag
{
  "packages": [
    {
      "id": "vpc_module",
      "props": {
        "region": { "value": "Props.region" }
      }
    },
    {
      "id": "eks_cluster",
      "props": {
        "vpc_id": { "value": "Data.vpc_module.vpc_id" },
        "subnet_ids": { "value": "Data.vpc_module.private_subnet_ids" }
      }
    }
  ]
}

Here eks_cluster depends on vpc_module. Bluebricks executes vpc_module first, then passes its vpc_id and private_subnet_ids outputs to eks_cluster.

Data references in expressions

You can combine Data references with other values using expr expressions

chevron-rightExample JSONhashtag
{
  "props": {
    "bucket_name": {
      "value": "'my-app-' + Data.vpc_module.vpc_id + '-logs'"
    },
    "enable_logging": {
      "value": "Props.create_bucket || Data.s3_module.bucket_exists"
    }
  }
}

Expressions are evaluated at runtime after dependencies complete.

Plan vs apply

Data references behave differently in each phase:

  • Plan phase: Bluebricks identifies that a value will change but does not resolve the actual value yet

  • Apply phase: Actual values are resolved, passed to dependent packages, and used in expressions

The data flow model

Bluebricks uses a hierarchical data flow:

  • Properties flow down from parent to child packages, set at deployment time, referenced with Props.<key>

  • Data flows up from child packages to parent, calculated at runtime, referenced with Data.<packageId>.<key>

spinner

How the DAG determines execution order

Consider this blueprint:

chevron-rightExample JSONhashtag
spinner

Execution order:

  1. launch_template runs first (no dependencies)

  2. s3_bucket and monitoring run in parallel (both depend only on launch_template)

Data reference chains

Data references can form chains across nested blueprints.

chevron-rightExample JSONhashtag

Bluebricks resolves the full chain: vpc outputs vpc_id, subnet_module uses it to create subnets, subnet_blueprint exposes subnet_id, and instance receives it.

Designing for parallelism

Minimize Data references between packages to maximize parallel execution.

chevron-rightSequential (slow): each package depends on the previous onehashtag
chevron-rightParallel (fast): packages use properties instead of cross-package Data references where possiblehashtag

Best practices

  • Use Props for static configuration, Data for runtime values

  • Never create circular dependencies (A depends on B, B depends on A)

  • Reference only outputs that will definitely be available

  • Use descriptive output keys so Data references are self-documenting

  • Keep expressions readable; avoid deeply nested logic

See also

Last updated

Was this helpful?