# Publish with bricks.yaml

`bricks.yaml` provides a slimmer, more maintainable alternative to `bricks.json` for defining blueprints. You only specify what you need to change; everything else is auto-populated from the package definitions.

**Key advantages:**

* **Simplified syntax**: only specify what you need to change
* **Auto-populated fields**: props and outputs inherited from packages
* **Multi-document support**: publish multiple blueprints from one file
* **YAML features**: anchors, aliases, and merge keys for reusable configuration
* **Higher priority**: when both files exist, YAML takes precedence

## Basic format

### Minimal blueprint

```yaml
name: web_application
version: 1.0.0
packages:
  - name: terraform_aws_vpc
    version: 3.0.0
```

**Required fields** (for package-composition blueprints):

* `name`: blueprint name
* `version`: blueprint version (semver)
* `packages`: non-empty list of packages (at least one)

{% hint style="info" %}
All field names are lowercase. Blueprint-level fields include `name`, `version`, `description`, `tags`, `inputs`, `packages`, and `outputs`. Package-level fields include `name`, `version`, `id`, and `props`.
{% endhint %}

### Complete blueprint

```yaml
name: web_infrastructure
version: 1.0.0
description: Web application infrastructure on AWS
tags:
  - aws
  - production

inputs:
  region:
    type: string
    default: us-east-1
    description: AWS region
  vpc_cidr:
    type: string
    default: 10.0.0.0/16

packages:
  - id: network
    name: terraform_aws_vpc
    version: 3.0.0
    props:
      cidr_block: inputs.vpc_cidr
      region: inputs.region

  - id: database
    name: terraform_aws_rds
    version: 2.1.0
    props:
      vpc_id: data.network.vpc_id
      subnet_ids: data.network.private_subnet_ids

outputs:
  vpc_id:
    value: data.network.vpc_id
    description: VPC identifier
  db_endpoint:
    value: data.database.endpoint
    description: Database endpoint
```

## Package configuration

### Auto-populated props

Props you don't specify are automatically wired to blueprint-level inputs, inheriting their type, description, and default value from the package definition.

```yaml
packages:
  - name: terraform_aws_s3
    version: 2.5.0
    props:
      region: inputs.region
      # All other props (bucket_name, encryption, etc.)
      # are auto-wired to blueprint inputs from the package definition
```

**When to specify props:**

* Override default values
* Connect to other packages via data references
* Use blueprint inputs
* Set hardcoded values

### Explicit package IDs

Specify the `id` field when using the same package multiple times, referencing package outputs in other packages, or ensuring predictable output references.

```yaml
packages:
  - id: api_lambda
    name: terraform_aws_lambda
    version: 1.4.0
    props:
      function_name: api-handler

  - id: worker_lambda
    name: terraform_aws_lambda
    version: 1.4.0
    props:
      function_name: worker-handler
```

Without an explicit `id`, the package name is used as the ID. IDs must start with a letter or underscore and contain only letters, numbers, and underscores (`^[a-zA-Z_][a-zA-Z0-9_]*$`).

### Auto-populated outputs

Package outputs are automatically included. You only need to specify outputs in the blueprint if you want to change output names or add additional outputs not in the package.

```yaml
outputs:
  vpc_id:
    value: data.network.vpc_id
    description: VPC identifier
```

If you define an output with the same name as a package output, your definition takes priority for that name, and the original package output is included under `<packageId>_<outputName>`.

If you don't need to modify outputs, omit the `outputs` section entirely.

## Value references

### Data references

Reference outputs from other packages using `data.<package_id>.<output_key>`:

```yaml
packages:
  - id: vpc
    name: terraform_aws_vpc
    version: 3.0.0

  - id: subnet
    name: terraform_aws_subnet
    version: 2.0.0
    props:
      vpc_id: data.vpc.vpc_id
      availability_zone: data.vpc.availability_zones
```

{% hint style="warning" %}
Use lowercase `data`, not `Data`. The YAML format uses lowercase references (`data.*`, `inputs.*`) while the JSON format uses capitalized references (`Data.*`, `Props.*`).
{% endhint %}

Data references create implicit dependencies. Bluebricks builds a DAG from these references and executes packages in the correct order. For details, see [Parallel Execution](/docs/orchestration/runs/parallel-execution.md).

### Input references

Reference blueprint inputs using `inputs.<input_key>`:

```yaml
inputs:
  environment:
    type: string
    default: dev
  region:
    type: string
    default: us-east-1

packages:
  - name: terraform_aws_s3
    version: 2.5.0
    props:
      bucket_name: inputs.environment
      region: inputs.region
```

### String values

How values are interpreted:

**Simple references (no quotes needed):**

```yaml
props:
  vpc_id: data.vpc.vpc_id          # Data reference
  region: inputs.region             # Input reference
  function_name: execute            # Plain string
```

You don't need to quote plain strings. Bluebricks automatically wraps literal values during publishing to prevent expression parsing issues. Quoting is only needed if a value looks like an expression but you intend it as a literal:

```yaml
props:
  function_name: execute-api         # Auto-quoted during publish
  bucket_name: my-app-logs           # Auto-quoted during publish
  literal_ref: 'data.not_a_ref'     # Force literal with quotes
```

Values containing `inputs.`, `data.`, or `secrets.` are treated as expressions and transformed. All other values are treated as string literals.

## YAML features

### Anchors and aliases

Define configuration once with anchors (`&name`) and reuse with aliases (`*name`):

```yaml
name: shared_configuration
version: 1.0.0

common_settings: &defaults
  region: us-east-1
  timeout: 300
  retries: 3

packages:
  - name: terraform_aws_s3
    version: 2.5.0
    props:
      <<: *defaults
      bucket_name: application-data

  - name: terraform_aws_dynamodb
    version: 1.8.0
    props:
      <<: *defaults
      table_name: application-state
```

### Merge keys

Combine multiple configurations with merge keys (`<<`):

```yaml
name: merged_settings
version: 1.0.0

base_config: &base
  timeout: 300
  retries: 3

monitoring_config: &monitoring
  logging_enabled: true
  metrics_enabled: true

packages:
  - name: terraform_aws_lambda
    version: 1.4.0
    props:
      <<: [*base, *monitoring]
      function_name: api-handler
```

### Anchors with package repetition

Use anchors when repeating the same package. When overriding `props` with anchors, you replace the entire `props` object. To merge props, use nested anchors:

```yaml
lambda_props: &common_props
  runtime: inputs.runtime
  timeout: 300

packages:
  - id: api_lambda
    name: terraform_aws_lambda
    version: 1.4.0
    props:
      <<: *common_props
      function_name: api-handler

  - id: worker_lambda
    name: terraform_aws_lambda
    version: 1.4.0
    props:
      <<: *common_props
      function_name: worker-handler
```

## Input configuration

### Input types

Define blueprint inputs with types, defaults, and constraints. Supported types: `string`, `number`, `bool`, `list`, `map`, `any`.

```yaml
inputs:
  environment:
    type: string
    default: dev
    description: Deployment environment
    allowed_values:
      - dev
      - staging
      - prod

  instance_count:
    type: number
    default: 2
    description: Number of instances

  enable_monitoring:
    type: bool
    default: true
    description: Enable CloudWatch monitoring

  region:
    type: string
    description: AWS region (required, no default)
```

Inputs without a default are required at deployment time. Inputs with a default are optional.

### Allowed values

Restrict input values to specific options:

```yaml
inputs:
  instance_type:
    type: string
    default: t3.micro
    allowed_values:
      - t3.micro
      - t3.small
      - t3.medium
      - t3.large
```

## Multi-document YAML

Publish multiple blueprints from a single file using document separators (`---`):

```yaml
name: vpc_blueprint
version: 1.0.0
packages:
  - name: terraform_aws_vpc
    version: 3.0.0
    props:
      cidr_block: inputs.vpc_cidr

---

name: database_blueprint
version: 2.0.0
packages:
  - name: terraform_aws_rds
    version: 2.1.0
    props:
      engine: postgres
      instance_class: inputs.db_instance_class

---

name: storage_blueprint
version: 1.5.0
packages:
  - name: terraform_aws_s3
    version: 2.5.0
    props:
      bucket_name: inputs.bucket_name
```

Each document is published as a separate blueprint.

## Publishing

Publish your blueprint using the standard command:

```bash
bricks blueprint publish
```

{% hint style="warning" %}
When both `bricks.yaml` and `bricks.json` exist, YAML takes precedence. The CLI will warn: `Both bricks.json and bricks.yaml found. Using bricks.yaml (higher priority).`
{% endhint %}

### Multi-document publishing

```bash
$ bricks blueprint publish

Publishing 3 blueprint(s) from bricks.yaml...

Blueprints to be published:
  - [1/3] vpc_blueprint@1.0.0
  - [2/3] database_blueprint@2.0.0
  - [3/3] storage_blueprint@1.5.0

[1/3] Published slim blueprint: vpc_blueprint@1.0.0
[2/3] Published slim blueprint: database_blueprint@2.0.0
[3/3] Published slim blueprint: storage_blueprint@1.5.0
```

### Validation during publish

The CLI and backend validate your blueprint during publish. This includes schema checks, output reference validation against child blueprints, and case-sensitivity enforcement.

| Error                                                                                                 | Cause                                                                                      |
| ----------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------ |
| `blueprint 1: missing 'version' property`                                                             | Missing required field                                                                     |
| `Couldn't resolve package <name>@<version>`                                                           | Package or version not found                                                               |
| `Output key "<key>" not found in package <name>@<version>`                                            | Invalid output reference                                                                   |
| `failed to parse bricks.yaml: failed to decode blueprint 1: yaml: line 15: did not find expected key` | Malformed YAML                                                                             |
| `Property "bricks_depnds" is not a recognized reserved property. Did you mean 'bricks_depends'?`      | Typo in reserved `bricks_` property                                                        |
| Blueprint has child packages not referenced in any output                                             | Every child package must appear in at least one output via `Data.<packageId>.<outputName>` |
| `Blueprint validation failed... The following output references are invalid`                          | Referenced output does not exist in the child blueprint                                    |
| Blueprint property/output contains invalid lowercase references                                       | Used `data.` or `props.` instead of `Data.` or `Props.` in `bricks.json`                   |

{% hint style="info" %}
Property names starting with `bricks_` are reserved. The only currently supported reserved property is `bricks_depends`. If you use an unrecognized `bricks_` property, publishing fails with an error and a suggestion for the closest valid name.
{% endhint %}

{% hint style="warning" %}
Bluebricks validates that every `Data.<packageId>.<outputName>` reference in your blueprint points to an output that exists in the child blueprint. If a child blueprint does not define the referenced output, publishing fails with a list of invalid references and the available outputs for each child.
{% endhint %}

## Development workflow

### Finding packages

Search for packages to add to your blueprint:

```bash
bricks blueprint search -q "vpc"
bricks blueprint search -q "s3"
```

### Inspecting package details

Get package information before adding to your blueprint:

```bash
# Full package details as JSON
bricks blueprint describe terraform_aws_vpc

# View all props with defaults
bricks blueprint get props terraform_aws_vpc@3.0.0

# View all outputs
bricks blueprint get outs terraform_aws_vpc@3.0.0
```

### Building your YAML

Use the information from `bricks blueprint describe` to construct your blueprint:

1. **Search and identify packages**: `bricks blueprint search -q "vpc"`
2. **Get package details**: `bricks blueprint describe terraform_aws_vpc`
3. **Create `bricks.yaml`** with only the props you need to override
4. **Verify references**: use `bricks blueprint get outs` to confirm output keys exist before referencing them

### Iterative development

Build your blueprint incrementally:

```bash
# 1. Start with minimal blueprint and publish
bricks blueprint publish

# 2. View the generated full blueprint
bricks blueprint describe test_blueprint > bricks.json

# 3. Add more packages, publish again
bricks blueprint publish
```

### Viewing generated blueprint

After publishing, view the full hydrated blueprint with all auto-populated props and outputs:

```bash
bricks blueprint describe my_blueprint > bricks.json
```

This shows all props (including defaults from packages), all outputs, generated IDs, and full resolution of inputs and data references.

## Migration from bricks.json

You don't need to migrate all blueprints at once:

1. **Keep existing** `bricks.json` files working
2. **Create new blueprints** with `bricks.yaml`
3. **Migrate gradually** as you update blueprints

{% hint style="info" %}
If you already have a published blueprint, export it as JSON to use as a reference when writing your YAML:

```bash
bricks blueprint describe my_blueprint > reference.json
```

This shows all props, outputs, and resolved references, so you know exactly which fields to include or override.
{% endhint %}

To convert an existing blueprint:

1. Create a new `bricks.yaml` file
2. Copy name, version, description, tags
3. Define inputs from props
4. List packages (only override props as needed)
5. Add outputs only if customizing
6. Test with `bricks blueprint publish`

```
my-blueprint/
├── bricks.json          # Keep for reference (ignored when bricks.yaml exists)
└── bricks.yaml          # Used by CLI (takes precedence)
```

`bricks.yaml` is converted to `bricks.json` server-side. View the generated result with:

```bash
bricks blueprint describe my_blueprint > blueprint.json
```

## See also

* [Creating Blueprints](/docs/orchestration/packages/blueprints-overview/creating-blueprints.md): step-by-step guide for the UI wizard and CLI
* [Blueprint Composition Patterns](/docs/orchestration/packages/blueprints-overview/blueprint-composition-patterns.md): architectural patterns and dependency strategies
* [Using expr](/docs/orchestration/packages/blueprints-overview/expr.md): expression language for dynamic configuration


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://bluebricks.co/docs/orchestration/packages/blueprints-overview/publish-with-bricks-yaml.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
