# 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:**

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

{% hint style="info" %}
All field names are lowercase: `name`, `version`, `packages`, `inputs`, `outputs`, `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

You only need to specify props you want to change or override. All other props from the package definition are automatically included.

```yaml
packages:
  - name: terraform_aws_s3
    version: 2.5.0
    props:
      region: inputs.region
      # All other props (bucket_name, encryption, etc.)
      # are automatically included from 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 explicit IDs, the CLI generates IDs automatically, making it harder to predict output references.

### Auto-populated outputs

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

```yaml
outputs:
  # Only specify if you need to override or add conditions
  vpc_id:
    value: data.network.vpc_id
    condition: inputs.create_vpc
```

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](https://bluebricks.co/docs/core-concepts/runs/parallel-execution).

### 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
```

**Strings with special characters (use quotes):**

```yaml
props:
  function_name: 'execute-api'      # Dash requires quotes
  bucket_name: 'my-app-logs'        # Dash requires quotes
```

**Detection order:**

1. `inputs.*` pattern: input reference
2. `data.*` pattern: data reference
3. Expression matching: expression
4. Fallback: string literal

## 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:

```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                                                   |
| `Could not find artifact helm_argo_cd version 1.0.1`                                             | Invalid package version                                                  |
| `output key 'endpoint' not found in package 'database'`                                          | Invalid output reference                                                 |
| `failed to parse bricks.yaml: 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 outputs must reference at least one package...`                                       | No output uses `Data.<packageId>.<outputName>`                           |
| `Blueprint validation failed... The following output references are invalid`                     | Referenced output does not exist in the child blueprint                  |
| `Blueprint 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 bp search -q "vpc"
bricks bp search -q "s3"
```

### Inspecting package details

Get package information before adding to your blueprint:

```bash
# Full package details including version, props, and outputs
bricks bp get 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 bp get` to construct your blueprint:

1. **Search and identify packages**: `bricks bp search -q "vpc"`
2. **Get package details**: `bricks bp get 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 bp 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 bp 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

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](https://bluebricks.co/docs/core-concepts/packages/blueprints-overview/creating-blueprints): step-by-step guide for the UI wizard and CLI
* [Blueprint Composition Patterns](https://bluebricks.co/docs/core-concepts/packages/blueprints-overview/blueprint-composition-patterns): architectural patterns and dependency strategies
* [Using expr](https://bluebricks.co/docs/core-concepts/packages/blueprints-overview/expr): expression language for dynamic configuration
