Blueprint Composition Patterns

Learn common patterns for composing blueprints and managing package dependencies effectively.

Prerequisites

  • Understanding of blueprints and packages

  • Familiarity with Data.* references

  • Experience with package management

Composition Patterns

1. Layered Architecture

Pattern: Stack packages in layers (infrastructure → platform → application)

{
  "packages": [
    {
      "name": "@bluebricks/terraform_aws_vpc",
      "id": "infrastructure_vpc"
    },
    {
      "name": "@bluebricks/terraform_aws_subnet",
      "id": "infrastructure_subnet",
      "props": {
        "vpc_id": {
          "value": "Data.infrastructure_vpc.vpc_id"
        }
      }
    },
    {
      "name": "@bluebricks/helm_nginx",
      "id": "platform_nginx",
      "props": {
        "cluster_name": {
          "value": "Data.infrastructure_subnet.cluster_name"
        }
      }
    },
    {
      "name": "@bluebricks/helm_myapp",
      "id": "application_myapp",
      "props": {
        "nginx_endpoint": {
          "value": "Data.platform_nginx.endpoint"
        }
      }
    }
  ]
}

Benefits:

  • Clear separation of concerns

  • Predictable dependency flow

  • Easy to understand and maintain

2. Hub and Spoke

Pattern: Central package provides shared resources to multiple consumers

Benefits:

  • Shared infrastructure resources

  • Cost optimization

  • Centralized network management

3. Microservices Composition

Pattern: Each service is a separate package with shared dependencies

Benefits:

  • Service independence

  • Clear service boundaries

  • Scalable architecture

4. Environment-Specific Composition

Pattern: Same blueprint with different configurations per environment

Usage:

Benefits:

  • Single blueprint for multiple environments

  • Environment-specific configuration

  • Consistent architecture

Dependency Management Patterns

1. Explicit Dependencies

Pattern: Clearly define all package dependencies

2. Conditional Dependencies

Pattern: Use expressions for conditional package behavior

3. Version Pinning

Pattern: Pin specific package versions for stability

Output Management Patterns

1. Aggregated Outputs

Pattern: Combine outputs from multiple packages

2. Conditional Outputs

Pattern: Control execution based on configuration - Bluebricks only executes components whose outputs are actually needed

How it works:

  • If enable_monitoring is false, the monitoring component is NOT executed

  • This follows Bluebricks' output-driven execution model

  • Only components providing needed outputs are deployed

  • Props flow down, data flows up based on actual requirements

3. Structured Outputs

Pattern: Organize outputs into logical groups

Expression Language Patterns

Bluebricks uses the expr-langarrow-up-right expression language to enable dynamic configurations and advanced composition patterns.

1. Dynamic Resource Naming

Pattern: Generate unique resource names using expressions

Benefits:

  • Prevents naming conflicts

  • Includes timestamp for uniqueness

  • Environment-specific naming

2. Conditional Package Configuration

Pattern: Use ternary operators for environment-specific settings

3. Null Coalescing for Fallbacks

Pattern: Provide fallback values using the ?? operator

4. String Manipulation and Concatenation

Pattern: Build complex strings from multiple sources

5. Array and Object Access

Pattern: Access nested properties and array elements

6. Mathematical Operations

Pattern: Perform calculations for resource sizing

7. Complex Conditional Logic

Pattern: Use multiple conditions for sophisticated logic

8. Output Aggregation with Expressions

Pattern: Combine multiple outputs using expressions

Best Practices

Package Selection

  • Choose packages that complement each other

  • Verify package compatibility

  • Use stable, well-maintained packages

  • Consider package performance impact

Dependency Design

  • Minimize dependencies

  • Avoid circular references

  • Use clear naming conventions

  • Document dependency reasons

Configuration Management

  • Provide sensible defaults

  • Use descriptive property names

  • Validate property values

  • Document configuration options

Expression Language Best Practices

  • Use expressions for dynamic values, not static ones

  • Keep expressions readable and well-documented

  • Test complex expressions thoroughly

  • Use null coalescing (??) for safe fallbacks

  • Leverage built-in functions for string manipulation

  • Avoid overly complex nested expressions

Testing Strategy

  • Test blueprint composition locally

  • Verify all package interactions

  • Check output references

  • Validate property flow

  • Test expression evaluation with different inputs

Anti-Patterns to Avoid

1. Circular Dependencies

2. Over-Complex Dependencies

3. Unclear Output References

See also

Last updated

Was this helpful?