# Welcome to the Bluebricks Docs

Get an overview of Bluebricks' core concepts, tools, and how they work together

## Get started

<table data-card-size="large" data-view="cards"><thead><tr><th></th><th data-hidden data-card-cover data-type="image">Cover image</th><th data-hidden data-card-target data-type="content-ref"></th><th data-hidden data-type="image">Cover image (dark)</th><th data-hidden data-card-cover-dark data-type="image">Cover image (dark)</th></tr></thead><tbody><tr><td><strong>What is Bluebricks?</strong><br>Connect your cloud and code, and AI agents manage your infrastructure</td><td><a href="/files/JkOdUJWNMv9QhOj6XAlH">/files/JkOdUJWNMv9QhOj6XAlH</a></td><td><a href="/pages/uQ4ThrIXevNrGTnyFOtf">/pages/uQ4ThrIXevNrGTnyFOtf</a></td><td><a href="/files/ezBIKVCFYdnzOJpqfjEn">/files/ezBIKVCFYdnzOJpqfjEn</a></td><td><a href="/files/ezBIKVCFYdnzOJpqfjEn">/files/ezBIKVCFYdnzOJpqfjEn</a></td></tr><tr><td><strong>Quick Start</strong><br>Connect your cloud, connect your code, talk to the agents</td><td><a href="/files/Oii1eInKRp3Gm1sKdNiN">/files/Oii1eInKRp3Gm1sKdNiN</a></td><td><a href="/pages/fhySk0QfJ6JyM4apdFO3">/pages/fhySk0QfJ6JyM4apdFO3</a></td><td></td><td><a href="/files/VwgIsxRWHGnlKTVkG4jX">/files/VwgIsxRWHGnlKTVkG4jX</a></td></tr></tbody></table>

## Meet the agent

<table data-card-size="large" data-view="cards"><thead><tr><th></th><th data-hidden data-card-cover data-type="image">Cover image</th><th data-hidden data-card-cover-dark data-type="image">Cover image (dark)</th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>How the Agent Works</strong><br>Context layer, capabilities, and how the agent reasons about your infrastructure</td><td><a href="/files/LbNB9xcWR0CTuw1d4f9r">/files/LbNB9xcWR0CTuw1d4f9r</a></td><td><a href="/files/vV04DswhK48qTcnHhU3k">/files/vV04DswhK48qTcnHhU3k</a></td><td><a href="/pages/7KYjmGpkS1gNkCUG6int">/pages/7KYjmGpkS1gNkCUG6int</a></td></tr><tr><td><strong>Codifying Infrastructure</strong><br>Import existing cloud resources into code through the agent</td><td><a href="/files/X9VSLcwICG4QR02K6YIn">/files/X9VSLcwICG4QR02K6YIn</a></td><td><a href="/files/QQZY5LkcdbjYgbD90T4b">/files/QQZY5LkcdbjYgbD90T4b</a></td><td><a href="/pages/x3iM4t1mLZSJhnumzB2R">/pages/x3iM4t1mLZSJhnumzB2R</a></td></tr></tbody></table>

## Orchestration

<table data-view="cards"><thead><tr><th></th><th data-hidden data-card-cover data-type="image">Cover image</th><th data-hidden data-card-cover-dark data-type="image">Cover image (dark)</th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>Collections</strong><br>Group cloud accounts, teams, and stages into governed deployment targets</td><td><a href="/files/eY5MTcwAfTCvrW3m8Es8">/files/eY5MTcwAfTCvrW3m8Es8</a></td><td><a href="/files/GpWZt2AV8tYf9WPsxnKT">/files/GpWZt2AV8tYf9WPsxnKT</a></td><td><a href="/pages/qG3yaaK8VRr4iqJJcP8O">/pages/qG3yaaK8VRr4iqJJcP8O</a></td></tr><tr><td><strong>Packages</strong><br>Reusable, versioned building blocks for your infrastructure code</td><td><a href="/files/3JCUIocCFprTBesHxbqm">/files/3JCUIocCFprTBesHxbqm</a></td><td><a href="/files/FLXLavkvvfXXQVXOD2qG">/files/FLXLavkvvfXXQVXOD2qG</a></td><td><a href="/pages/RaVuz2bcyctXGY0ErjIj">/pages/RaVuz2bcyctXGY0ErjIj</a></td></tr><tr><td><strong>Environments</strong><br>Deploy blueprints into collections with governed plan/approve/apply workflows</td><td><a href="/files/GqKhkUbazM74ydFcYd01">/files/GqKhkUbazM74ydFcYd01</a></td><td><a href="/files/G2C3X2Mb9Cu9pHrluK80">/files/G2C3X2Mb9Cu9pHrluK80</a></td><td><a href="/pages/r726FnxiQB0aReq5Y3fY">/pages/r726FnxiQB0aReq5Y3fY</a></td></tr></tbody></table>

## Tools

<table data-view="cards"><thead><tr><th></th><th data-hidden data-card-cover data-type="image">Cover image</th><th data-hidden data-card-cover-dark data-type="image">Cover image (dark)</th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>Bricks CLI</strong><br>Run, plan, and ship infrastructure from the terminal</td><td><a href="/files/NUPnECfFlrg1xZjdCI03">/files/NUPnECfFlrg1xZjdCI03</a></td><td><a href="/files/4fBEsfewZTymxFS8lw4c">/files/4fBEsfewZTymxFS8lw4c</a></td><td><a href="/pages/dntQmowfGi50XVJh7dBJ">/pages/dntQmowfGi50XVJh7dBJ</a></td></tr><tr><td><strong>API Overview</strong><br>Automate Bluebricks at scale with the REST API</td><td><a href="/files/MjQujUdHvop6x9jzgaFs">/files/MjQujUdHvop6x9jzgaFs</a></td><td><a href="/files/ZjEsPHy6atTynIJahZmm">/files/ZjEsPHy6atTynIJahZmm</a></td><td><a href="/spaces/qHXqMr0KYQT5OUP6gSt0">/spaces/qHXqMr0KYQT5OUP6gSt0</a></td></tr><tr><td><strong>GitOps Environments</strong><br>Keep your cloud in sync with your code through Git-driven workflows</td><td><a href="/files/cphqxpLv9RDJgR3ULoeE">/files/cphqxpLv9RDJgR3ULoeE</a></td><td><a href="/files/pBhYzJ6oNGcrsqNvsEas">/files/pBhYzJ6oNGcrsqNvsEas</a></td><td><a href="/pages/dEO0qG5EiBiMxvwfKOPo">/pages/dEO0qG5EiBiMxvwfKOPo</a></td></tr></tbody></table>

## Integrations

<table data-view="cards"><thead><tr><th></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>GitHub</strong><br>Connect repositories, get plan check runs on PRs, and manage IaC from GitHub</td><td><a href="/pages/ZjFncA7RfSvqcjTpDfLr">/pages/ZjFncA7RfSvqcjTpDfLr</a></td></tr><tr><td><strong>GitLab</strong><br>Run Bricks CLI commands inside GitLab CI/CD pipelines</td><td><a href="/pages/NopIjRq6X4EauFLP9AO4">/pages/NopIjRq6X4EauFLP9AO4</a></td></tr><tr><td><strong>Slack</strong><br>Get notifications and interact with the Bluebricks agent in Slack</td><td><a href="/pages/BbLL8HAiAWS8pYAPUPSE">/pages/BbLL8HAiAWS8pYAPUPSE</a></td></tr><tr><td><strong>Backstage</strong><br>Provision environments and browse blueprints from your developer portal</td><td><a href="/pages/OXD6ZORIrhEb7L0B5v6S">/pages/OXD6ZORIrhEb7L0B5v6S</a></td></tr><tr><td><strong>GitHub Actions</strong><br>Run Bricks CLI commands in your GitHub Actions workflows</td><td><a href="/pages/nHDI12oeJrmpNRy2O7ZM">/pages/nHDI12oeJrmpNRy2O7ZM</a></td></tr><tr><td><strong>Azure DevOps</strong><br>Integrate Bluebricks into your Azure DevOps pipelines</td><td><a href="/pages/FA37rJc4k8vP4A6SbahG">/pages/FA37rJc4k8vP4A6SbahG</a></td></tr></tbody></table>


# What is Bluebricks?

Learn what Bluebricks is, how the context layer enables safe agentic infrastructure, and how orchestration fits in

Bluebricks is an infrastructure platform that enables agents to discover, reason about, and operate your cloud infrastructure safely.

It starts by building a **context layer**: a structured map of every resource, relationship, and dependency across your cloud accounts and infrastructure code. This shared context is what makes autonomous infrastructure operations possible, because agents can see the full picture before they act.

## Why this matters

AI tools for code are effective because code is self-contained. Infrastructure is not.

Infrastructure is fragmented across systems. Terraform manages declared resources, cloud providers reflect runtime state, and Git repositories store the source of truth. Each system operates independently, with no shared understanding of how they connect.

Without that connection:

* An agent that only sees your code cannot determine what is actually running
* An agent that only sees your cloud cannot determine what is managed or intended
* Changes are difficult to reason about, validate, and execute safely

Giving an agent access to your cloud account is not enough. It needs a structured, continuously updated model of how your infrastructure fits together. That is the context layer.

## The context layer

When you connect your cloud accounts and infrastructure code, Bluebricks builds a **context layer**: a structured map of your entire infrastructure environment. The context layer captures:

* **Every cloud resource** across connected AWS, Azure, and GCP accounts, whether managed by code or not
* **Live Kubernetes state** on managed clusters (EKS, GKE, AKS) discovered through those cloud connections; see [Kubernetes Integration](/docs/getting-started/connect-your-cloud/kubernetes-integration)
* **Relationships between resources**: networking dependencies, IAM bindings, service connections, cross-account references
* **Code-to-cloud mapping**: which resources are governed by infrastructure code, which modules manage them, and where the code lives
* **Drift detection**: differences between what your code declares and what is actually running

The context layer updates continuously. When you connect a new cloud account, Bluebricks runs discovery: a read-only scan that indexes every resource in that provider. Discovery refreshes periodically so the context layer reflects the current state of your infrastructure, not a stale snapshot.

This is the foundation that the rest of Bluebricks is built on. The [agent](/docs/agent/agents-overview) queries the context layer to answer questions, identify risks, and execute changes. The [orchestration platform](#orchestration) uses it to resolve dependencies and generate accurate plans.

## How agents operate safely

The context layer does not just give agents visibility. It constrains how they operate.

Because the agent sees the full dependency graph before acting, it can predict the impact of a change before proposing it. Every change the agent makes follows the same governed workflow as manual operations:

* **Plan before apply**: the agent generates a plan showing exactly what will change. Nothing executes until you approve
* **All changes go through IaC**: the agent does not make direct cloud API calls. Changes are codified in pull requests or environment runs, version-controlled, and auditable
* **RBAC and policies are enforced**: the agent respects your collection-level roles, permissions, and policies. If you cannot approve a deployment manually, the agent cannot do it for you
* **Organization-scoped**: all queries and actions are scoped to your organization at the database level. The agent cannot access resources outside your org

This is not a set of guardrails bolted onto a chat interface. The context layer and governance model are the same system, so safety is structural, not behavioral.

For a detailed look at how the agent uses the context layer to discover, remediate, and deploy, see [Agent Overview](/docs/agent/agents-overview).

## Orchestration

Alongside the agent, Bluebricks provides a full orchestration platform for governed, repeatable deployments. You define reusable building blocks, target them at specific cloud accounts, and run deployment pipelines with plan/approve/apply cycles.

The agent and the orchestration platform share the same context layer, governance rules, and approval workflows. Teams can use either interface, or both, depending on what fits their workflow.

Bluebricks organizes orchestration around three core concepts: **packages** define *what* you deploy, **collections** define *where* it goes, and **environments** define *how* it runs.

### Packages

A [package](/docs/orchestration/packages) is a reusable unit of Infrastructure as Code (IaC). Instead of managing raw Terraform modules, Helm charts, or CloudFormation templates directly, you wrap them into packages that expose clear inputs, outputs, and metadata.

<details>

<summary>More about packages</summary>

There are two types of packages:

* **Artifact**: a single IaC component (a Terraform module, a Helm chart, a Bicep template) with defined inputs, outputs, and metadata. Artifacts are building blocks you compose into blueprints
* **Blueprint**: a deployable template made of one or more packages. A blueprint wires artifacts together, sets defaults and constants, and exposes only the inputs the deployer needs to provide

For example, you might have a VPC artifact and a subnet artifact. A network blueprint composes the two, passes the VPC ID into the subnet, and exposes only `region` and `cidr_block` as inputs. The deployer never touches the underlying wiring.

Blueprints support Terraform/OpenTofu, Helm, CloudFormation, Bicep, and Generic artifact types, so you can mix IaC tools within a single blueprint.

Read more about [packages](/docs/orchestration/packages).

</details>

### Collections

A [collection](/docs/orchestration/collections) is the deployment target. It groups a cloud account, access rules, shared configuration, and governance policies into one place.

<details>

<summary>More about collections</summary>

Every collection can include:

* **Cloud account**: the AWS account, GCP project, Azure subscription, or on-premises target where resources are created
* **Properties and secrets**: collection-scoped values (like `region`, `project_id`, or database credentials) that are automatically inherited by every package deployed to the collection. This keeps packages reusable while adapting them to each target
* **RBAC**: member and owner roles that control who can create, approve, or execute environments in the collection
* **Policies**: guardrails like Owner Approval, Cost Limits, and Allowed Blueprints that govern what runs and under which conditions

Collections map to how your organization already works. For example, `dev-us-east-1`, `staging`, and `prod-eu-west-1`.

Read more about [collections](/docs/orchestration/collections).

</details>

### Environments

An [environment](/docs/orchestration/environments) is the workflow that deploys a package into a collection. It is where *what* (the package) meets *where* (the collection) and produces real infrastructure.

<details>

<summary>More about environments</summary>

When you deploy an environment, Bluebricks evaluates the package and all its dependencies to produce a **unified plan** of changes. You can preview the plan, approve it, and apply or destroy the resources when they are no longer needed.

Each execution creates a **run**. A run captures the plan, logs, state updates, and outputs in a single auditable record. Runs are fully versioned, so you can trace exactly how your infrastructure evolved and why.

Read more about [environments](/docs/orchestration/environments).

</details>


# Quick Start

Connect your cloud and code, then talk to the Bluebricks agent to discover and manage your infrastructure

This guide gets you from sign-up to your first conversation with the Bluebricks agent. By the end, you will have connected a cloud account and your code, and asked the agent a real question about your infrastructure.

For a broader overview of the platform before diving in, see [What is Bluebricks?](/docs/getting-started/building-blocks).

## What you need

* A Bluebricks account. Sign up at [app.bluebricks.co](https://app.bluebricks.co) if you have not already
* An AWS or Azure cloud account with permissions to create IAM roles or register applications
* A GitHub organization with infrastructure code repositories (optional; you can skip this step and connect code later)

The onboarding wizard walks you through the steps below.

## 1. Connect your cloud

The first step is to connect a cloud account so Bluebricks can discover what is running in your environment.

1. Name your cloud account and pick a color to identify it
2. Select your cloud provider: **AWS** or **Azure** (GCP coming soon)
3. Follow the provider-specific setup to grant Bluebricks read access to your account

{% tabs %}
{% tab title="AWS" %}
Bluebricks uses a CloudFormation stack to provision an IAM role in your AWS account.

1. Click **Launch CloudFormation stack** in the onboarding wizard. This opens the AWS CloudFormation console with the Bluebricks template, stack name, and your External ID prefilled
2. In AWS, acknowledge the IAM capabilities and click **Create stack**
3. Once the stack completes, copy the **Discovery Role ARN** from the stack's **Outputs** tab
4. Paste the Role ARN back into the Bluebricks wizard and click **Connect**

For the full walkthrough, see [Connecting to AWS](/docs/getting-started/connect-your-cloud/how-to-connect-aws).
{% endtab %}

{% tab title="Azure" %}
Bluebricks connects to Azure through a registered application with federated credentials.

1. Register a new application in the Azure portal
2. Enter the **Application ID**, **Tenant ID**, and **Client Secret** in the Bluebricks wizard
3. Assign the **Contributor** role to the application on your subscription
4. Enter your **Subscription ID** and click **Connect**

For the full walkthrough, see [Connecting to Azure](/docs/getting-started/connect-your-cloud/how-to-connect-azure).
{% endtab %}
{% endtabs %}

Once connected, Bluebricks begins ingesting your cloud resources into the context layer. This usually takes a few minutes depending on the size of your environment.

{% hint style="info" %}
**Already completed the onboarding wizard?** To connect additional cloud providers or accounts, see [Connect your Cloud](/docs/getting-started/connect-your-cloud).
{% endhint %}

## 2. Connect your code

Next, connect your GitHub repositories so the agent can read your infrastructure code and propose changes through pull requests.

1. Click **Authorize** to start the GitHub OAuth flow
2. Install the Bluebricks GitHub App on your organization
3. Select the repositories that contain your infrastructure code

{% hint style="info" %}
**Don't use GitHub, or not ready to connect code yet?** You can skip this step. The agent can still discover and analyze your cloud resources without code access. You can connect code later from [Connect your Code](/docs/getting-started/connect-your-code).
{% endhint %}

The GitHub integration is read-only. Bluebricks does not modify your code directly; all changes are proposed through pull requests.

## 3. Talk to the agent

After connecting your cloud and code, Bluebricks redirects you to the agent. You are ready to ask your first question.

Try something like:

```
Show me all cloud resources that aren't managed by code
```

The agent queries the context layer, cross-references your cloud resources with your IaC repositories, and returns a breakdown of managed versus unmanaged resources across your accounts.

From here, you can follow up naturally:

* "Which of those are in production?"
* "Are any of them publicly accessible?"
* "Open a PR to bring the unmanaged S3 buckets under Terraform"

The agent handles follow-up questions in the same conversation, building on the context of what you have already discussed.

{% hint style="info" %}
The agent operates in read-only mode by default. When you ask it to make a change, it opens a pull request for you to review and approve before anything is applied.
{% endhint %}

## What's next?

Now that you are connected, explore what the agent can do for your team:

* **Review your security posture**: "Which security groups allow inbound traffic from 0.0.0.0/0?"
* **Find cost savings**: "Which EC2 instances have been idle for over 30 days?"
* **Make infrastructure changes**: "Scale the EKS cluster in staging to 5 nodes"
* **Set up orchestration**: create reusable blueprints and governed deployment workflows. See the [Orchestration Quick Start](/docs/orchestration/orchestration-quick-start) to deploy your first environment

Want to invite your team? See [Account Settings](/docs/organization-and-security/account-settings) to add members.


# Connect your Cloud

Connect your cloud accounts so Bluebricks can discover your resources and build the context layer that powers the agent

## Overview

Connecting a cloud account is the first step to using Bluebricks. Once connected, Bluebricks ingests your cloud resources into the context layer, giving the agent visibility into what is running across your accounts and regions.

A **cloud provider** represents a top-level boundary for cloud resources (such as an AWS account or GCP project). You connect it by granting Bluebricks a delegated role with the permissions needed to read, and optionally manage, your resources.

<figure><picture><source srcset="/files/K9EPrxd67tab8SP8oYgt" media="(prefers-color-scheme: dark)"><img src="/files/8ir9ZNewN3UZ7MKCbrQR" alt=""></picture><figcaption></figcaption></figure>

## Supported cloud providers

* [Amazon Web Services (AWS)](/docs/getting-started/connect-your-cloud/how-to-connect-aws)
* [Google Cloud Platform (GCP)](/docs/getting-started/connect-your-cloud/how-to-connect-gcp)
* [Microsoft Azure](/docs/getting-started/connect-your-cloud/how-to-connect-azure)

## Kubernetes visibility

Managed Kubernetes clusters (EKS, GKE, AKS) use your existing cloud connections with discovery enabled, not a separate provider in the app. See [Kubernetes Integration](/docs/getting-started/connect-your-cloud/kubernetes-integration) for prerequisites, network access, and how live workload indexing works.

## Permissions

Bluebricks separates cloud provider permissions into two roles:

* **Discovery** permissions allow Bluebricks to read and inventory resources. This is a read-only permission set that powers the context layer and the agent
* **Orchestration** permissions allow Bluebricks to create, modify, and destroy infrastructure. This is required for deploying blueprints through the orchestration platform

A cloud provider can have one or both permission types, depending on what you need:

<table><thead><tr><th width="233.38671875">Permission combination</th><th>What you can do</th></tr></thead><tbody><tr><td>Discovery only</td><td>Inventory and explore cloud resources via the agent. No deployments</td></tr><tr><td>Orchestration only</td><td>Deploy and manage blueprints. No resource discovery or import</td></tr><tr><td>Discovery + Orchestration</td><td>Full visibility plus deployment capabilities. Required for <a href="/pages/x3iM4t1mLZSJhnumzB2R">codifying infrastructure</a></td></tr></tbody></table>

{% hint style="info" %}
Both permission types are set at the cloud provider level and apply to all collections that use that account. **AWS** supports separate discovery and orchestration IAM roles. **GCP** uses one service account for both types; you grant different IAM roles on your project depending on whether you need discovery, orchestration, or both. See [Connecting to GCP](/docs/getting-started/connect-your-cloud/how-to-connect-gcp) for the required discovery roles.
{% endhint %}

## Orchestration: collections

When using the [orchestration platform](/docs/getting-started/building-blocks#orchestration), each cloud provider is linked to one or more [collections](/docs/orchestration/collections). A single cloud provider can be shared across multiple collections (for example, staging and production) to support isolated workflows while reusing the same cloud setup. For more on collections, see [Collections](/docs/orchestration/collections).

## Self-hosted runner

Connect a self-hosted orchestrator to allow Bluebricks to connect to your cluster in a secure, controlled way without sharing long-lived credentials. See [how to set up a self-hosted runner](/docs/organization-and-security/bluebricks-self-hosted-runner/what-is-a-self-hosted-cloud).


# Connecting to AWS

Step-by-step guide to connect an AWS account to Bluebricks using a CloudFormation stack

{% hint style="info" %}
**First time using Bluebricks?** The onboarding wizard walks you through connecting your cloud automatically. Follow the [Quick Start](/docs/getting-started/quick-start) instead.
{% endhint %}

## Prerequisites

1. A valid [AWS account](https://docs.aws.amazon.com/accounts/latest/reference/manage-acct-creating.html)
2. Permissions to create CloudFormation stacks and IAM roles in your AWS account

## How to connect in the Bluebricks app

{% stepper %}
{% step %}

### Create a collection and launch CloudFormation

1. Go to the **Collections** page
2. Click **Create Collection**
3. Name the collection (for example, `production` or `staging`)
4. Select **AWS** as the cloud provider
5. In the **Account Number** dropdown, click **New Account**
6. Click **Launch CloudFormation stack**

This opens the AWS CloudFormation console with the Bluebricks template, stack name, and your External ID prefilled.
{% endstep %}

{% step %}

### Create the stack in AWS

Review the prefilled stack details, scroll to the bottom, acknowledge the IAM capabilities checkbox, and click **Create stack**. Wait for the stack to reach **CREATE\_COMPLETE** status. This usually takes under a minute.
{% endstep %}

{% step %}

### Copy the Role ARN

Open the **Outputs** tab in the CloudFormation console. The stack provisions IAM roles that Bluebricks uses to access your AWS account. You need at least one Role ARN, but we recommend providing both for full visibility and deployment capabilities.

* **Discovery Role ARN**: grants read-only access for resource discovery, inventory, and the [context layer](/docs/getting-started/building-blocks#the-context-layer). Required for the agent to see what is running in your account
* **Orchestration Role ARN**: grants read/write access for deploying and managing infrastructure through [blueprints](/docs/orchestration/packages/blueprints-overview). Required for making changes through the orchestration platform

Copy the **Discovery Role ARN** and, if available, the **Orchestration Role ARN**. See [Connect your Cloud](/docs/getting-started/connect-your-cloud) for more details on permission types.
{% endstep %}

{% step %}

### Connect in Bluebricks

Back in the Bluebricks wizard, paste the Role ARN(s) and click **Connect & Create**. Bluebricks verifies the connection and begins ingesting your cloud resources into the context layer.
{% endstep %}
{% endstepper %}

## How to connect via the API

Use the [Cloud Accounts API](https://bluebricks.co/docs/api/reference/cloud-accounts) to create a cloud account. Pass the Stack ID as `cloudFormationStackId` and the Role ARN as `roleArnId`.

## Next steps

* [Connect your Cloud](/docs/getting-started/connect-your-cloud): overview of all supported providers
* [Kubernetes Integration](/docs/getting-started/connect-your-cloud/kubernetes-integration): live cluster indexing through discovery
* [Connect your Code](/docs/getting-started/connect-your-code): give the agent access to your infrastructure repositories


# Connecting to Azure

Connecting an **Azure Account** to a **Bluebricks Environment** takes up to **5 minutes**.

### Prerequisites

1. Ensure you have a valid subscription id in [Azure](https://portal.azure.com/#home).

### Step 1: Create an environment with an Azure cloud

1. Go to the Collections page
2. Click **"Create collection"** and give it a name
3. Select **Azure** as the **Cloud Provider**
4. Choose "**New subscription ID**" or an existing subscription ID.

<figure><img src="/files/iakW1FysIYsMZQmDMwju" alt=""><figcaption></figcaption></figure>

4. If creating a **New Subscription**, keep the page open and go to Azure Portal.

### Step 2: Create an Azure Service Principal with OIDC

1. Navigate to "App Registration" and select "New Registration"
   1. Give a Name
   2. Choose "Accounts in this organizational directory only (Single Tenant)"
   3. Select "Web" as the Redirect URI Platform and leave the value blank
   4. Register the app

<figure><img src="/files/EC7XYrLNscmGUI6frAdY" alt=""><figcaption></figcaption></figure>

2. Click the app you just create and go to to "Certificates & Secrets" under "Manage"

<figure><img src="/files/6E1mjVEKlFzLmvulKPYP" alt=""><figcaption></figcaption></figure>

3. Go to the "Federated Credentials" tab select "Add credential"

   1. Select "Other Issuer" as the Federated credential scenario
   2. Copy the "Issuer" URL from the open environment page in Step 1 as the "Issuer"
   3. Choose "Explicit subject identifier"
   4. Copy the "Value" from the open environment page in Step 1 as the "Value"
   5. Give the Credential a name
   6. Copy the "Audience" from the open environment page in Step 1 as the "Audience"
   7. Add the Credential

   <figure><img src="/files/o11RuxuJq8rDvc3ZtqeG" alt=""><figcaption><p>Bluebricks Environment Page</p></figcaption></figure>

   <figure><img src="/files/pd7l2QqV238h1yIj50zH" alt=""><figcaption><p>Azure Federated Credential page</p></figcaption></figure>
4. Go to the "Overview" section of the App and copy following into environment page on Bluebricks:

   1. Application (client) ID
   2. Directory (tenant) ID

   <figure><img src="/files/QCDT5eC5wqxfXuIMIxBD" alt=""><figcaption><p>Azure Application Overview</p></figcaption></figure>

   <figure><img src="/files/N5X6izN0osci0qiRCW8K" alt=""><figcaption><p>Bluebricks Environment Page</p></figcaption></figure>

### Step 3: Create role assignment to the newly provisioned application

1. Navigate to "Subscriptions" and choose the subscription you want to connect to Bluebricks\\

   <figure><img src="/files/scV6LrBRaWqOzTADPzUM" alt=""><figcaption></figcaption></figure>
2. Choose "Access Control (IAM)"
3. Choose "Add" and then "Add [Role Assignment](https://learn.microsoft.com/en-us/azure/role-based-access-control/role-assignments-portal)"

   <figure><img src="/files/yuDjjGuZPIBOeCIzCKiW" alt=""><figcaption></figcaption></figure>
4. Choose the [appropriate Role](https://learn.microsoft.com/en-us/azure/role-based-access-control/built-in-roles/privileged#contributor) to allow Bluebricks to create Resources in Azure (We recommend `contributor` under "Privileged administrator roles")

   <figure><img src="/files/TNlLvpBD9CwDWIJOaHj0" alt=""><figcaption></figcaption></figure>
5. Go to Members and search and select the Name of the service principal created in Step 2.

   <figure><img src="/files/vHyHE4oabSBSXinJVkYB" alt=""><figcaption></figcaption></figure>
6. Press Review and Assign

   <figure><img src="/files/3FVdW2kbNDK5m48XyDId" alt=""><figcaption></figcaption></figure>

### Step 4: Save the Cloud Connection on Bluebricks

1. Navigate to the "Overview" page of the subscription and copy the "Subscription ID"

   <figure><img src="/files/YrX4QprUP5VeHr9MHCzQ" alt=""><figcaption></figcaption></figure>
2. Go back to the Environment page on Bluebricks and copy the subscription ID
3. Press Save

   <figure><img src="/files/ZsVMnSe9b4dJ6ojW4wq5" alt=""><figcaption></figcaption></figure>

You Finished connecting your Azure subscription to Bluebricks and you now can create resources on Azure suing Bluebricks.


# Connecting to GCP

Step-by-step guide to connect a Google Cloud project to a Bluebricks collection, grant discovery permissions, and start cloud resource ingestion

Connect a Google Cloud project to a Bluebricks [collection](/docs/orchestration/collections) so Bluebricks can inventory cloud resources into the [context layer](/docs/getting-started/building-blocks#the-context-layer). After you grant the required IAM roles to the Bluebricks service account, discovery ingests your project resources and powers the [agent](/docs/agent/agents-overview).

Unlike AWS and Azure, GCP connections do **not** start discovery automatically. You must grant IAM roles on your project first, then trigger ingestion.

## Prerequisites

1. A valid [Google Cloud project ID](https://cloud.google.com/resource-manager/docs/creating-managing-projects)
2. Permission to grant IAM roles on that project (`roles/resourcemanager.projectIamAdmin` or equivalent)
3. A [Bluebricks collection](/docs/orchestration/collections/create-an-environment)

{% hint style="info" %}
Bluebricks uses **service account impersonation** to connect to GCP: no static service account keys are required. Bluebricks creates a dedicated service account per project and authenticates through Google's identity federation.
{% endhint %}

## How to connect and enable discovery

{% stepper %}
{% step %}

### Connect GCP in Bluebricks

1. Click **Connect Cloud** on the collection you want to link to GCP

   <figure><img src="/files/MEtqrNNpvNIs1eMFEdaw" alt=""><figcaption></figcaption></figure>
2. Select **GCP** as the **Cloud Provider**

   <figure><img src="/files/OWOZcRuHX8BXbQkWkwtn" alt=""><figcaption></figcaption></figure>
3. Choose an existing **Project ID** or click **New Project**
4. If creating a **New Project**, enter the **Google Cloud Project ID**

   <figure><img src="/files/jRpZSTdgFJscDk0KEIv5" alt=""><figcaption></figcaption></figure>
5. Click **Connect & Create** to complete the setup
   {% endstep %}

{% step %}

### Copy the service account email

Bluebricks creates one service account per connected project. You grant IAM roles to this account on **your** project.

1. Choose **Edit** on the collection options

   <figure><img src="/files/9khR7LT2J5jEsggT5Qxz" alt=""><figcaption></figcaption></figure>
2. Copy the **Bluebricks Service Account** email (also available in the Cloud Accounts API response as `service_account_email`)

   <figure><img src="/files/pwngIGChpgjnT4ajEtRa" alt=""><figcaption></figcaption></figure>

{% hint style="warning" %}
Use a **unique service account email** per project. Do not reuse the same principal across unrelated projects.
{% endhint %}
{% endstep %}

{% step %}

### Grant discovery permissions

Discovery permissions are **required** for cloud resource ingestion, the context layer, and the agent. Without these roles, ingestion fails with IAM permission errors.

Grant the following roles to the Bluebricks service account on your Google Cloud project:

| Role                   | IAM role ID                  | Purpose                                                                                                        |
| ---------------------- | ---------------------------- | -------------------------------------------------------------------------------------------------------------- |
| **Cloud Asset Viewer** | `roles/cloudasset.viewer`    | Query [Cloud Asset Inventory](https://cloud.google.com/asset-inventory/docs) (required for resource discovery) |
| **Security Reviewer**  | `roles/iam.securityReviewer` | Read IAM policies and security configurations                                                                  |
| **Viewer**             | `roles/viewer`               | General read-only access to project resources                                                                  |

{% tabs %}
{% tab title="Google Cloud console" %}

1. Open the [Google Cloud console](https://console.cloud.google.com/) and select your project
2. Search for **IAM** and open **IAM & Admin**
3. Click **Grant access**
4. Paste the Bluebricks service account email in **New principals**
5. Assign each role from the table above (Cloud Asset Viewer, Security Reviewer, Viewer)
6. Click **Save**

   <figure><img src="/files/ugQxMGoBNmETPWR2OQV3" alt=""><figcaption></figcaption></figure>

   <figure><img src="/files/SgvNtJz0UEwIfv76m5di" alt=""><figcaption></figcaption></figure>

{% endtab %}

{% tab title="gcloud CLI" %}
Set `PROJECT_ID` to the Google Cloud project you connected in Bluebricks. Set `SA_EMAIL` to the Bluebricks service account email from the previous step (format: `name@PROJECT_ID.iam.gserviceaccount.com`).

```bash
PROJECT_ID="my-gcp-project-id"
SA_EMAIL="bluebricks-sa@my-gcp-project-id.iam.gserviceaccount.com"

for ROLE in \
  roles/cloudasset.viewer \
  roles/iam.securityReviewer \
  roles/viewer; do
  gcloud projects add-iam-policy-binding "$PROJECT_ID" \
    --member="serviceAccount:${SA_EMAIL}" \
    --role="$ROLE"
done
```

Prefer separate commands? Keep the same `PROJECT_ID` and `SA_EMAIL` lines above, then run each binding individually with `"$PROJECT_ID"` and `"serviceAccount:${SA_EMAIL}"`.
{% endtab %}
{% endtabs %}
{% endstep %}

{% step %}

### Grant GKE permissions

If this project runs [GKE](https://cloud.google.com/kubernetes-engine) workloads, grant one more role so Bluebricks can add **live cluster details** to your [context layer](/docs/getting-started/building-blocks#the-context-layer). The agent can then answer questions about what is running inside your clusters, not just that the clusters exist.

Discovery alone lists GKE clusters as cloud resources. This step indexes **in-cluster objects** such as Pods, Deployments, Jobs, and Ingresses. That gives the [agent](/docs/agent/agents-overview) a fuller picture of your environment.

| Role                         | IAM role ID              | Purpose                                             |
| ---------------------------- | ------------------------ | --------------------------------------------------- |
| **Kubernetes Engine Viewer** | `roles/container.viewer` | Read GKE clusters and connect to the Kubernetes API |

{% tabs %}
{% tab title="Google Cloud console" %}

1. Open **IAM & Admin** > **IAM** for your project
2. Find the Bluebricks service account, or use **Grant access** if it is not listed yet
3. Add the **Kubernetes Engine Viewer** role to the same principal
4. Click **Save**
   {% endtab %}

{% tab title="gcloud CLI" %}
If your shell session is still open from the **Grant discovery permissions** step, `PROJECT_ID` and `SA_EMAIL` are already set. Otherwise, edit and run the full block below:

```bash
# Skip these two lines if PROJECT_ID and SA_EMAIL are already set
PROJECT_ID="my-gcp-project-id"
SA_EMAIL="bluebricks-sa@my-gcp-project-id.iam.gserviceaccount.com"

gcloud projects add-iam-policy-binding "$PROJECT_ID" \
  --member="serviceAccount:${SA_EMAIL}" \
  --role="roles/container.viewer"
```

{% endtab %}
{% endtabs %}

Grant this role before you trigger discovery in the next steps so the first scan includes GKE workload data. No GKE in this project? Continue to the next step.

For more information, see [Kubernetes Integration](/docs/getting-started/connect-your-cloud/kubernetes-integration).
{% endstep %}

{% step %}

### Trigger discovery and verify ingestion

GCP connections do not start discovery automatically. After IAM roles propagate (usually within a few minutes), trigger ingestion:

1. Ask the [agent](/docs/agent/agents-overview) to refresh cloud resources for your collection, or trigger ingestion through the Cloud Accounts API
2. Wait for the ingestion job to complete (typically 2 to 5 minutes)
3. Verify by asking the agent a project-scoped question, for example: "List compute instances in my GCP project" or "What GKE clusters are running?"

{% hint style="warning" %}
If ingestion fails with a Cloud Asset Inventory or IAM permission error, confirm all three discovery roles from the **Grant discovery permissions** step are granted on the correct project. Failed jobs do not retry automatically after exhausting retries.
{% endhint %}
{% endstep %}

{% step %}

### Grant orchestration permissions (optional)

If you plan to deploy [blueprints](/docs/orchestration/packages/blueprints-overview) through Bluebricks, also grant the **Editor** role (`roles/editor`) to the same service account. This allows Bluebricks to create, modify, and destroy infrastructure in your project.

GCP uses the same service account for both discovery and orchestration. See [Connect your Cloud](/docs/getting-started/connect-your-cloud#permissions) for how permission types work across providers.

{% hint style="info" %}
Discovery-only setups do not need the Editor role. Complete the discovery and ingestion steps above without granting orchestration permissions.
{% endhint %}

{% tabs %}
{% tab title="Google Cloud console" %}

1. Open **IAM & Admin** > **IAM** for your project
2. Find the Bluebricks service account
3. Add the **Editor** role to the same principal
4. Click **Save**
   {% endtab %}

{% tab title="gcloud CLI" %}
If your shell session is still open from the **Grant discovery permissions** step, `PROJECT_ID` and `SA_EMAIL` are already set. Otherwise, edit and run the full block below:

```bash
# Skip these two lines if PROJECT_ID and SA_EMAIL are already set
PROJECT_ID="my-gcp-project-id"
SA_EMAIL="bluebricks-sa@my-gcp-project-id.iam.gserviceaccount.com"

gcloud projects add-iam-policy-binding "$PROJECT_ID" \
  --member="serviceAccount:${SA_EMAIL}" \
  --role="roles/editor"
```

{% endtab %}
{% endtabs %}
{% endstep %}
{% endstepper %}

## How to connect via the API

Use the [Cloud Accounts API](https://bluebricks.co/docs/api/reference/cloud-accounts) to create a cloud account. Pass the Google Cloud project ID as `accountId`. The response includes the Bluebricks service account email in `cloud_config`.

After connecting, grant the IAM roles and trigger discovery using the steps above.

## Troubleshooting

For ingestion failures, missing resources, and IAM permission errors, see [Cloud Connection Troubleshooting](https://bluebricks.co/docs/help/troubleshooting/cloud-connections) in the Help Center.

## Next steps

* [Connect your Cloud](/docs/getting-started/connect-your-cloud): overview of all cloud connection types and permission models
* [Kubernetes Integration](/docs/getting-started/connect-your-cloud/kubernetes-integration): live GKE workload indexing through discovery
* [Agent overview](/docs/agent/agents-overview): query your ingested cloud resources
* [CLI Reference: bricks clouds](/docs/bricks-cli/cli-reference/bricks_clouds)


# Kubernetes Integration

How Bluebricks discovers managed Kubernetes clusters through your cloud connections and indexes live cluster state for the agent and context layer.

Kubernetes integration extends the [context layer](/docs/getting-started/building-blocks#the-context-layer) beyond cloud APIs and static Helm chart templates. After you connect AWS, Azure, or GCP with discovery enabled, Bluebricks finds managed clusters in those accounts, polls their APIs, and indexes live workload state so the [agent](/docs/agent/agents-overview) can answer questions about what is actually running.

You do not connect Kubernetes as a separate cloud provider in the app today. Cluster visibility uses the same discovery [collection](/docs/orchestration/collections) and cloud account as your AWS, GCP, or Azure connection. For cloud connection basics, see [Connect your Cloud](/docs/getting-started/connect-your-cloud).

{% hint style="success" %}
**Ask the agent.** Query live cluster state through natural conversation after discovery completes. See [Agent overview](/docs/agent/agents-overview).
{% endhint %}

## What this integration includes

| Capability               | Description                                                                                                      |
| ------------------------ | ---------------------------------------------------------------------------------------------------------------- |
| **Cluster detection**    | Managed clusters (EKS, GKE, AKS) are discovered during cloud inventory scans                                     |
| **Live object indexing** | Workloads such as Deployments, Jobs, Pods, Services, Ingresses, and ConfigMaps are synced into the context layer |
| **Helm correlation**     | Live objects link to Helm releases and chart templates when standard Helm labels are present                     |
| **Cloud linkage**        | Objects connect to the underlying cluster and load balancers already modeled as cloud resources                  |

This is distinct from [Helm orchestration](/docs/orchestration/packages/artifacts-overview/helm) (deploying charts through environments) and from the [self-hosted runner](/docs/organization-and-security/bluebricks-self-hosted-runner/what-is-a-self-hosted-cloud) (running the Bluebricks Deployments Controller inside your cluster).

## How it works

```mermaid
flowchart LR
    A[Cloud connection with discovery] --> B[Cloud discovery scan]
    B --> C[Discover EKS, GKE, and AKS]
    C --> D[Sync live workload state]
    D --> E[Context layer]
    E --> F[Agent]
```

1. Connect a cloud account with **discovery** on a [collection](/docs/orchestration/collections), using [AWS](/docs/getting-started/connect-your-cloud/how-to-connect-aws), [GCP](/docs/getting-started/connect-your-cloud/how-to-connect-gcp), or [Azure](/docs/getting-started/connect-your-cloud/how-to-connect-azure).
2. Bluebricks runs a read-only cloud scan and discovers managed Kubernetes clusters in that account or project.
3. For each cluster, Bluebricks syncs live workload state from the Kubernetes API using credentials from your cloud connection. No agent pod runs inside your cluster.
4. Synced objects enter the [context layer](/docs/getting-started/building-blocks#the-context-layer) and link to Helm releases, infrastructure code, and related cloud resources. You query those relationships through the [agent](/docs/agent/agents-overview), not through the Cloud Graph canvas.

## Supported managed clusters

| Cloud provider | Supported clusters                                        |
| -------------- | --------------------------------------------------------- |
| **AWS**        | Amazon EKS                                                |
| **GCP**        | Google Kubernetes Engine (GKE)                            |
| **Azure**      | Azure Kubernetes Service (AKS) and Arc-connected clusters |

Clusters that never appear in cloud discovery for a connected account are outside this integration. That includes on-premises kubeconfig-only clusters and local development clusters not registered with EKS, GKE, or AKS. Use the [self-hosted runner](/docs/organization-and-security/bluebricks-self-hosted-runner/what-is-a-self-hosted-cloud) when you need orchestration against a cluster Bluebricks does not discover from a public cloud API.

## Chart intent vs live cluster state

The context layer has long reflected Kubernetes **intent** from Helm chart sources in your connected repositories. Kubernetes integration adds **live state**:

|                      | Helm templates in code             | Live Kubernetes objects                        |
| -------------------- | ---------------------------------- | ---------------------------------------------- |
| **Source**           | Chart files in connected Git repos | Kubernetes API on discovered clusters          |
| **Represents**       | What the chart declares            | What is running now (status, failures, labels) |
| **Example question** | "What does this chart deploy?"     | "Why did this Job fail in production?"         |

The agent can relate a failed Job to its Helm release, the blueprint or Terraform that owns the cluster, and cloud resources such as load balancers fronting an Ingress.

## Prerequisites

1. A [collection](/docs/orchestration/collections) linked to AWS, GCP, or Azure with **discovery** enabled on the cloud connection
2. At least one managed Kubernetes cluster in that account or project that cloud discovery can list
3. Discovery credentials that can authenticate to the cluster API through the cloud provider

For discovery vs orchestration permission types, see [Connect your Cloud](/docs/getting-started/connect-your-cloud#permissions).

## Required permissions

Kubernetes integration reuses **discovery** permissions on your cloud connection; it does not add a separate permission type in the app.

Your discovery role or service account must be able to:

* List and describe managed Kubernetes clusters in the cloud API (for example EKS, GKE, or AKS control planes)
* Obtain short-lived credentials to call the Kubernetes API for those clusters through the provider's supported mechanism

Provider-specific roles:

| Provider        | Additional role for live Kubernetes indexing                                          |
| --------------- | ------------------------------------------------------------------------------------- |
| **AWS (EKS)**   | EKS access entry with `AmazonEKSViewPolicy` on the discovery IAM role                 |
| **GCP (GKE)**   | `roles/container.viewer` (Kubernetes Engine Viewer) on the Bluebricks service account |
| **Azure (AKS)** | Azure Kubernetes Service RBAC Reader on the service principal                         |

For GCP, grant Kubernetes Engine Viewer in addition to the three base discovery roles documented in [Connecting to GCP](/docs/getting-started/connect-your-cloud/how-to-connect-gcp#grant-gke-permissions).

If cluster objects never appear after a successful cloud connection, verify discovery can see the cluster in the cloud console and that the discovery role has not been scoped down to exclude Kubernetes services.

## Network access and IP whitelisting

Kubernetes indexing calls your cluster API from the Bluebricks platform over HTTPS (port 443). Traffic is **outbound from Bluebricks to your API server endpoint**, not from a pod inside your cluster.

If the control plane is private or restricted by IP allowlists, allow the [Bluebricks egress IP ranges](/docs/organization-and-security/netwrok-access-requirements#ip-whitelist) on the cluster API before live object sync can succeed. Cloud discovery may still list the cluster even when API polling is blocked.

Apply those ranges using your provider's control plane access settings:

| Provider        | Typical control                                                                                                        |
| --------------- | ---------------------------------------------------------------------------------------------------------------------- |
| **AWS (EKS)**   | Public endpoint access and security groups or EKS public endpoint CIDR restrictions on the cluster API                 |
| **GCP (GKE)**   | [Authorized networks](https://cloud.google.com/kubernetes-engine/docs/how-to/authorized-networks) on the control plane |
| **Azure (AKS)** | [Authorized IP ranges](https://learn.microsoft.com/en-us/azure/aks/api-server-authorized-ip-ranges) on the API server  |

{% hint style="warning" %}
**Private-only API servers**\
If the Kubernetes API is reachable only inside a VPC or private link with no path from the public internet, Bluebricks cannot poll it with the current managed-cluster integration. You will still see the cluster in cloud inventory, but live workload indexing will not run until API access from the whitelisted Bluebricks IPs is possible. For private endpoints or other restricted topologies, [contact support](https://www.bluebricks.co/support) to discuss a custom connection.
{% endhint %}

## Verify integration is working

After discovery completes on the collection:

1. Open the [agent](/docs/agent/agents-overview) and ask a cluster-scoped question, for example: "List failed Jobs in the production EKS cluster" or "Which Ingress fronts this load balancer?"
2. Confirm the agent returns answers grounded in live status (pod phases, Job conditions, Ingress hostnames), not only chart YAML

That is the supported way to validate live workload indexing. Indexed Kubernetes objects feed the context layer behind the agent; there is no separate in-app graph for browsing Pods, Jobs, or Ingress relationships.

The [Cloud Graph](/docs/orchestration/cloud-graph) is a separate surface. It visualizes collections, environments, and **cloud** resources from discovery (managed vs. unmanaged, codification). You may see a managed cluster there as a cloud resource (for example an EKS cluster in inventory), but the Cloud Graph does not chart live Pods, Jobs, Ingresses, or Helm-to-workload relationships. Use the agent for that.

Indexing runs on a schedule with cloud discovery. New clusters may take until the next discovery cycle to appear.

## Limitations

These constraints match what [Connect your Cloud](/docs/getting-started/connect-your-cloud#supported-cloud-providers) supports today. They apply to **live workload indexing** for the agent and context layer, not to [Helm deployments](/docs/orchestration/packages/artifacts-overview/helm) or the [self-hosted runner](/docs/organization-and-security/bluebricks-self-hosted-runner/what-is-a-self-hosted-cloud).

| Limitation                                     | What this means for you                                                                                                                                                                                                                                                                           |
| ---------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **No Kubernetes-only cloud connection**        | The app connects **AWS**, **GCP**, or **Azure** accounts only. There is no separate flow to attach a cluster by kubeconfig or API URL alone. Enable discovery on one of those cloud connections first.                                                                                            |
| **Managed clusters from cloud inventory**      | Live indexing runs for **EKS**, **GKE**, and **AKS** (including Arc-connected clusters) that cloud discovery lists in your account or project. If the cluster does not show up in the provider console as a managed cluster resource, Bluebricks cannot index its workloads through this feature. |
| **No in-cluster discovery software**           | Bluebricks polls the Kubernetes API from its platform. You do not install a Bluebricks DaemonSet, operator, or agent in the cluster for this integration.                                                                                                                                         |
| **Built-in resource kinds only**               | Standard types such as Deployments, Jobs, Pods, Services, Ingresses, ConfigMaps, StatefulSets, and CronJobs are synced. **Custom resources (CRDs)** are not indexed.                                                                                                                              |
| **Agent, not Cloud Graph, for live workloads** | The [Cloud Graph](/docs/orchestration/cloud-graph) shows cloud inventory and orchestration structure, not an interactive graph of in-cluster objects. Live Kubernetes questions and cross-links (Job to Helm release, Ingress to load balancer) are available through the agent.                  |

## Related documentation

* [Connect your Cloud](/docs/getting-started/connect-your-cloud): cloud providers and discovery vs orchestration permissions
* [Connecting to AWS](/docs/getting-started/connect-your-cloud/how-to-connect-aws), [Connecting to GCP](/docs/getting-started/connect-your-cloud/how-to-connect-gcp), [Connecting to Azure](/docs/getting-started/connect-your-cloud/how-to-connect-azure)
* [Agent overview](/docs/agent/agents-overview)
* [Cloud Graph](/docs/orchestration/cloud-graph): cloud resource inventory and environments (not live in-cluster workload graph)
* [Helm artifacts](/docs/orchestration/packages/artifacts-overview/helm): deploying to connected clusters through orchestration
* [Network access requirements](/docs/organization-and-security/netwrok-access-requirements): domain and IP whitelist for Bluebricks services
* [Self-hosted runner](/docs/organization-and-security/bluebricks-self-hosted-runner/what-is-a-self-hosted-cloud): running deployments inside your own cluster


# Connect your Code

Connect your infrastructure code repositories so the Bluebricks agent can read your IaC, answer questions about it, and propose changes through pull requests

## Overview

Connecting your code repositories gives the Bluebricks agent access to your infrastructure code. Once connected, the agent can cross-reference your IaC with your cloud resources, answer questions about how your infrastructure is defined, and open pull requests when you ask them to make changes.

The agent currently supports **GitHub** repositories for code access.

## How to connect GitHub

1. Go to **Account Settings** > **Integrations** ([app.bluebricks.co/settings?tab=integrations](https://app.bluebricks.co/settings?tab=integrations))
2. Click the **GitHub** integration button
3. Click **Enable** and authorize the Bluebricks GitHub App
4. Select the organization you want to connect
5. Choose which repositories Bluebricks can access
6. Click **Save**

{% hint style="info" %}
The GitHub integration is read-only. Bluebricks does not push code or modify your repositories directly. All infrastructure changes proposed by the agent are submitted as pull requests for you to review.
{% endhint %}

## What happens after connecting

Once your repositories are connected, Bluebricks indexes your infrastructure code into the context layer. The agent can then:

* Answer questions about how resources are defined in code ("Where is the VPC for production defined?")
* Cross-reference cloud resources with their IaC definitions ("Which resources aren't managed by code?")
* Open pull requests to make infrastructure changes you request ("Add encryption at rest to all RDS instances")

Indexing typically completes within a few minutes. The agent will let you know if it needs access to additional repositories to answer a question.

## Managing connected repositories

To add or remove repositories from the integration:

1. Go to **Account Settings** > **Integrations**
2. Click **Configure** next to the GitHub integration
3. Update the repository selection in the GitHub App settings

Changes take effect immediately. Removing a repository removes the agent's access to that code.

## Using GitLab, Azure DevOps, or other providers

If your infrastructure code lives outside GitHub, you can still use Bluebricks through the orchestration platform. GitLab, Azure DevOps, and other Git providers are supported for deploying and managing infrastructure through [GitOps environments](/docs/orchestration/environments/gitops-environments).

* [**GitLab**](/docs/integrations/gitlab): run Bricks CLI commands inside GitLab CI/CD pipelines
* [**Azure DevOps**](/docs/integrations/azure-devops): integrate Bluebricks into your Azure DevOps pipelines
* [**GitHub Actions**](/docs/integrations/githubactions): run Bricks CLI commands in your GitHub Actions workflows

Agent-based code access (questions about your code, agent-opened PRs) is not yet available for these providers. The agent can still discover and analyze your cloud resources without code access.


# Agent Overview

How the Bluebricks agent uses the context layer to discover, secure, and manage your infrastructure

## Overview

The agent uses Bluebricks' [context layer](/docs/getting-started/building-blocks#the-context-layer) to discover, reason about, and take action across your infrastructure through natural conversation. It sees every resource, relationship, and dependency in your connected cloud accounts, whether managed by code or not.

You can reach the agent in the [Bluebricks app](https://app.bluebricks.co/agent), from [Slack](/docs/integrations/slack), or programmatically via the [Bluebricks MCP](/docs/integrations/bricks-mcp) server.

Alert and webhook sources can also open **integration threads**: shared conversations your whole team can work in. See [Integration threads](/docs/agent/integration-threads) for setup and how they differ from personal threads.

## Use cases

The agent handles workflows across three areas: security, infrastructure operations, and cost optimization. In each case, it can both discover the current state and take action to change it.

### Security

Identify configuration risks, compliance gaps, and remediate them through code.

The agent queries the context layer for security-relevant configuration across all connected accounts. When it finds an issue, it can open a pull request to fix it, so remediation follows the same governed, auditable workflow as any other change.

| What you can ask                                                         | What the agent does                                    |
| ------------------------------------------------------------------------ | ------------------------------------------------------ |
| "Which S3 buckets are publicly accessible?"                              | Queries the context layer for bucket ACLs and policies |
| "Are there any security groups allowing inbound traffic from 0.0.0.0/0?" | Scans security group rules across all VPCs             |
| "Which RDS instances don't have encryption at rest?"                     | Checks encryption configuration across accounts        |
| "Open a PR to enforce encryption at rest on all RDS instances"           | Generates Terraform changes and opens a pull request   |

You can also point the agent at findings from your existing security tools. Paste a finding or describe the issue, and the agent maps it to the affected resources in the context layer and proposes a fix.

### Infrastructure

Discover what is running, identify drift, and manage resources across accounts.

The agent can answer questions about resource inventory, ownership, and code coverage. It can also codify unmanaged resources, scale infrastructure, and deploy changes.

| What you can ask                                        | What the agent does                                                  |
| ------------------------------------------------------- | -------------------------------------------------------------------- |
| "Show me all EKS components across my AWS accounts"     | Cross-account resource discovery                                     |
| "List all databases tagged as 'legacy'"                 | Filtered resource search by tags                                     |
| "Which resources in production aren't managed by code?" | Identifies unmanaged resources (drift and coverage analysis)         |
| "What percentage of my infrastructure is codified?"     | Calculates managed vs. unmanaged ratio                               |
| "Codify the unmanaged S3 buckets in production"         | Generates Terraform code and opens a PR to bring resources under IaC |
| "Scale the EKS cluster in staging to 5 nodes"           | Modifies Terraform and opens a PR with the change                    |

To bring unmanaged resources under code control, see [Codifying Infrastructure](/docs/agent/codifying-infrastructure).

### FinOps

Find cost savings and act on them.

The agent analyzes resource configuration to surface optimization opportunities. It can identify orphaned resources, recommend rightsizing, and open PRs to implement the changes.

| What you can ask                                               | What the agent does                            |
| -------------------------------------------------------------- | ---------------------------------------------- |
| "Show me unattached EBS volumes across all accounts"           | Finds orphaned storage still incurring costs   |
| "Which Elastic IPs aren't associated with a running instance?" | Identifies unused IPs incurring charges        |
| "What would it save to downsize all gp2 volumes to gp3?"       | Estimates savings from a specific optimization |
| "Compare RDS instance counts between production and staging"   | Cross-account comparison for right-sizing      |

### Narrowing scope

The agent queries across all connected cloud providers by default. Add an account or provider name to narrow the results:

```
Show me all Lambda functions
```

```
Show me all Lambda functions in the staging account
```

{% hint style="info" %}
**Prefer a visual interface?** You can also explore your infrastructure through the [Cloud Graph](/docs/orchestration/cloud-graph), which shows resources, relationships, and managed vs. unmanaged status across all your collections.
{% endhint %}

## How it works

The agent has two classes of tools:

* **Read tools** query the context layer without modifying anything: resource discovery, environment listing, deployment outputs, and package inspection. You can ask questions freely without side effects
* **Write tools** create or modify infrastructure: opening pull requests, deploying environments, and approving or rejecting plans. Every write operation requires your explicit approval before it executes

Responses reflect what is actually running in your accounts, not what a language model was trained on. For details on how the context layer is built and why it matters, see [What is Bluebricks?](/docs/getting-started/building-blocks)

## Safety and governance

Infrastructure changes go through a plan-and-approve workflow. The agent always presents the plan and waits for your confirmation before applying.

* **Read-only by default**: inspection tools never modify your infrastructure. Write operations require you to take explicit action
* **All changes go through IaC**: the agent codifies changes in Terraform and routes them through pull requests, rather than making direct cloud API calls
* **Organization-scoped**: all queries are scoped to your organization. The agent cannot access resources outside your org
* **RBAC**: the agent respects your organization roles and permissions
* **Transparent execution**: the agent shows its reasoning step by step. Tool calls, query results, and logs are visible in the chat
* **Audit trail**: every message and action is logged and stored in your task history

For roles and permissions, see [Roles and Permissions](/docs/organization-and-security/roles-and-permissions).

## Agent and orchestration

If your team uses the Bluebricks [orchestration platform](/docs/orchestration/orchestration), the agent can manage blueprints, environments, and approval flows through conversation. The same governance policies, RBAC rules, and audit trails apply whether you work through the agent or the app.

```
Deploy the postgres blueprint to staging
```

```
Approve my latest staging environment
```

```
What went wrong with the last production deploy?
```

For details on how approval flows, collection policies, and permissions work in conversation, see [Agent Governance](/docs/agent/governance). For the orchestration concepts themselves, see [Collections](/docs/orchestration/collections), [Packages](/docs/orchestration/packages), and [Environments](/docs/orchestration/environments).

## The chat interface

From the agent page, click **New task** to open a fresh conversation. Type your question or request and press **Enter** to send. The agent begins working immediately, and your task auto-titles based on your first message.

Your recent tasks appear in the sidebar. Click any task to resume where you left off. To rename a task, click the title at the top of the conversation. To archive it, open the menu next to the title and select **Archive**.

### Resource graphs

When you ask about relationships or dependencies, the agent returns an interactive resource graph. Nodes represent cloud resources and edges show how they connect. You can pan, zoom, and click nodes for detail.

### Pull request blocks

When the agent opens a PR, the conversation shows a PR block with the title, branch names, and an expandable inline diff. You can review the proposed changes directly in the chat before navigating to GitHub.

For a full breakdown of PR structure, see [Reading a Bluebricks PR](/docs/agent/reading-a-bluebricks-pr).

### Agent reasoning and logs

While the agent works, an expandable **Working** block shows the reasoning process in real time. Once complete, the block collapses to **Worked** with the total duration.

Agent logs show the tools called and their results. These are useful for understanding how the agent arrived at an answer, especially when troubleshooting unexpected results.

## Programmatic access

Beyond the chat interface, you can interact with the agent from other tools:

<table data-view="cards"><thead><tr><th></th><th data-hidden data-card-cover data-type="image">Cover image</th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>Slack</strong><br>Mention @Bluebricks in any channel or send a direct message to talk to the agent where your team already works</td><td><a href="/files/E21i5dqLo9yWJjdtoLCw">/files/E21i5dqLo9yWJjdtoLCw</a></td><td><a href="/pages/BbLL8HAiAWS8pYAPUPSE">/pages/BbLL8HAiAWS8pYAPUPSE</a></td></tr><tr><td><strong>Bluebricks MCP</strong><br>Connect any MCP-compatible client (VS Code, Claude Desktop, Cursor) to plan, deploy, and approve infrastructure</td><td><a href="/files/B5g045FfRNXDmBjyJrb8">/files/B5g045FfRNXDmBjyJrb8</a></td><td><a href="/pages/lCqJ2UXQQOfXqaFbS3hf">/pages/lCqJ2UXQQOfXqaFbS3hf</a></td></tr><tr><td><strong>Claude Code Plugin</strong><br>Deploy blueprints, create packages, and manage environments directly from your terminal</td><td><a href="/files/pQBH7E3mRH42EVoC75Vg">/files/pQBH7E3mRH42EVoC75Vg</a></td><td><a href="/pages/LawfMBptIo5x6AUdNIyP">/pages/LawfMBptIo5x6AUdNIyP</a></td></tr></tbody></table>


# Integration threads

Shared agent conversations created from alerts and webhooks so your team can investigate incidents together.

When an external system sends an alert to Bluebricks, the platform can open an **integration thread**: a shared agent conversation that everyone in your organization can see and work in together.

Integration threads complement the conversations you start yourself in the app. They are built for incident response: alerts land in Bluebricks, the agent begins an investigation, and your team continues in the same thread without copying context into Slack or email.

## How integration threads differ from personal threads

|                            | Personal thread                                       | Integration thread                                |
| -------------------------- | ----------------------------------------------------- | ------------------------------------------------- |
| **Started by**             | You (in the app or through automation you run)        | An alert or webhook from a connected system       |
| **Who can see it**         | You, unless you share a link with someone in your org | Everyone in your organization who uses the agent  |
| **Who can reply**          | You; teammates with a shared link can **view only**   | Any teammate in your org who can use the agent    |
| **Updates in the sidebar** | Shown to you                                          | Shown to the whole organization                   |
| **Rename or archive**      | You                                                   | Managed by Bluebricks (not tied to a single user) |

```mermaid
flowchart LR
  Alert[External alert] --> Webhook[Webhook to Bluebricks]
  Webhook --> Thread[Integration thread]
  Thread --> Agent[Agent investigation]
  Agent --> Team[Team joins in app]
```

## Alert and webhook integrations

Connected monitoring and observability tools can send alerts to Bluebricks over HTTPS. Each accepted alert opens a new integration thread and starts an agent investigation. The exact webhook URL and setup steps depend on the integration; see the [API reference](https://bluebricks.co/docs/api) under **Inbound webhooks** for what is available in your environment.

Typical flow:

1. Your monitoring tool sends the alert payload to Bluebricks.
2. Bluebricks opens a new integration thread and starts an investigation from that data.
3. The agent works in the background and posts its findings into the thread.
4. Your team opens the thread in Bluebricks, reviews the results, and asks follow-up questions.

### Before you begin

1. The [agent](/docs/agent/agents-overview) is available for your organization.
2. The **source system is connected** in Bluebricks (where required) so the agent can use that context during the investigation. Configure integrations in the app or through the [API reference](https://bluebricks.co/docs/api).
3. You have a [long-lived API token](/docs/bricks-cli/authentication/authenticate-using-long-lived-tokens) for the inbound webhook, with permission to open agent threads.

{% hint style="warning" %}
**Security**\
Inbound webhook URLs are reachable from the internet, but only requests with a valid [long-lived API token](/docs/bricks-cli/authentication/authenticate-using-long-lived-tokens) are accepted. Create a dedicated token per integration, rotate it like other automation secrets, and grant only the permissions the webhook needs.
{% endhint %}

### What you see in the app

After Bluebricks accepts an alert:

* A new thread appears for your organization, usually with a default title from the integration (the title may update after the agent finishes its first pass).
* The conversation opens with the alert details and the agent’s investigation.
* Teammates see progress in the agent sidebar and on the threads list.

<figure><img src="/files/yq9mCbGIb36TWTuswhu4" alt="Agent app showing Public threads in the sidebar and a Coralogix integration thread with an IAM policy investigation"><figcaption><p>Integration threads appear under <strong>Public</strong> in the agent sidebar, labeled by source (for example Coralogix).</p></figcaption></figure>

If an investigation is already running on that thread, Bluebricks still saves the thread and records what happened so your team can continue or retry from the app.

### Example: Coralogix alerts

**Coralogix** is one supported source today. Setup has two parts: connecting Coralogix so the agent can look up live data during an investigation, and sending alerts into Bluebricks so each incident opens a thread.

#### Connect Coralogix for richer investigations (recommended)

The alert webhook only includes what Coralogix puts in the notification. For deeper analysis, connect **Coralogix’s MCP server** in Bluebricks. During an integration thread, the agent can then query Coralogix (for example logs, traces, and related context) instead of relying on the alert JSON alone.

Configure this in the app under integrations, or through the Coralogix MCP endpoints in the [API reference](https://bluebricks.co/docs/api) (`/api/v1/integrations/mcp/coralogix`). You need your Coralogix MCP server URL and auth token from Coralogix.

The webhook below can still open threads if you skip this step, but investigations work best when both the webhook and the Coralogix connection are in place.

#### Route alerts into Bluebricks

In Coralogix, add an outbound webhook that runs when an alert fires.

**Webhook URL**

```
POST https://api.bluebricks.co/api/v1/webhooks/coralogix/alerts
```

**Authentication**

Send your [long-lived API token](/docs/bricks-cli/authentication/authenticate-using-long-lived-tokens) as a Bearer token:

```bash
curl -X POST 'https://api.bluebricks.co/api/v1/webhooks/coralogix/alerts' \
  -H 'Authorization: Bearer {{API-KEY}}' \
  -H 'Content-Type: application/json' \
  -d '{
    "alert_id": "cx-123",
    "alert_name": "CPU high",
    "severity": "critical",
    "timestamp": "2026-05-04T12:00:00Z",
    "alert_message": "CPU over 95%",
    "application": "api",
    "subsystem": "fastify"
  }'
```

**Alert payload**

Use any JSON shape your Coralogix template provides. Bluebricks keeps the full payload on the thread and includes it in the first investigation message. You do not need to map fields to a fixed schema.

**Response**

A successful call returns **202 Accepted** with a thread identifier you can open in the app:

```json
{
  "thread_id": "550e8400-e29b-41d4-a716-446655440000",
  "message": "Investigation opened successfully"
}
```

New alert sources will follow the same pattern: connect the tool in Bluebricks, register its webhook URL, and open a shared thread for your organization when an event arrives.

## Working together as a team

Anyone in your organization who can use the agent can:

* Find integration threads in the agent sidebar and threads list, alongside their own personal threads.
* Read the full history, including the original alert in the opening messages.
* Ask the agent follow-up questions and drive the investigation forward.

That differs from a **personal** thread you did not start: teammates who open your link can read the conversation but cannot send messages or run the agent.

{% hint style="info" %}
**Collection access**\
If a thread is tied to specific collections, teammates still need access to those collections to open it. Alert-driven threads are not limited to a collection by default.
{% endhint %}

You can **copy a link** to the thread, **favorite** it for quick access, and use **unread** indicators on your own account even though the thread is visible to the whole org.

## Automating with the API

Scripts and CI jobs can list and open threads through the Agents API. Filter by thread type (personal vs integration) and by connected system when you need a subset of incidents.

See the [API reference](https://bluebricks.co/docs/api) for Agents endpoints and inbound webhooks (including Coralogix alerts).

Additional **alert** sources may be added over time using the integration-thread model described above.

## Slack

The [Slack integration](/docs/integrations/slack) can run the agent when someone @mentions Bluebricks or sends a direct message. Each Slack conversation maps to one **personal** agent thread in Bluebricks (owned by the teammate who started it), not an org-wide integration thread.

<figure><img src="/files/LLZujJ3io2p1bB13nsDj" alt="Slack channel with a Coralogix alert and a Bluebricks app reply analyzing load balancer target health"><figcaption><p>When alerts post to a Slack channel, mention @Bluebricks in that thread to investigate with prior Slack messages as context.</p></figcaption></figure>

**Slack thread context.** When you message the agent inside a Slack thread (a reply, not a new top-level message), Bluebricks pulls recent messages from that Slack thread and sends them with your prompt. The agent sees who said what in the conversation leading up to your request, not only the latest line. Bluebricks skips its own prior replies in that history so the context stays focused on the discussion.

**Continuity.** Follow-ups in the same Slack thread reuse the same agent thread in Bluebricks, so later turns also include earlier agent and user messages from that chat.

In the app, teammates who are not the owner can open that thread by link but are **view only**. Collaboration happens in Slack; the Bluebricks thread backs that chat. This is different from alert-driven integration threads, which are shared with everyone in your organization by default.

## Related documentation

* [Agent overview](/docs/agent/agents-overview)
* [Agent governance](/docs/agent/governance)
* [Reading a Bluebricks PR](/docs/agent/reading-a-bluebricks-pr)
* [Bluebricks MCP](/docs/integrations/bricks-mcp) — the Bluebricks MCP server for infrastructure workflows (separate from vendor MCP connections such as Coralogix)
* [Long-lived API tokens](/docs/bricks-cli/authentication/authenticate-using-long-lived-tokens) — tokens for webhooks and automation


# Codifying Infrastructure

Import unmanaged cloud resources into infrastructure code through the Bluebricks agent

## Overview

The agent can identify unmanaged resources across your connected cloud providers, recommend which ones to bring under management, and handle the entire import process: generating the code, validating it against your live environment, and opening a pull request. You can also ask it to import specific resources directly.

## How it works

Ask the agent to find unmanaged resources, or tell it what to import:

```
Codify the unmanaged S3 buckets in the production account
```

```
Which resources in my AWS account aren't managed by code?
```

The agent then:

1. **Identifies resources** in the [context layer](/docs/getting-started/building-blocks#the-context-layer) that match your request
2. **Generates infrastructure code** from the selected resources
3. **Validates the configuration** by running a plan and checking for errors
4. **Iterates** until the plan reaches a no-changes state, confirming the code matches your live infrastructure
5. **Opens a pull request** with the generated code for your review

Each step runs inline in the conversation. You see progress updates, generated code blocks, and a plan summary as the agent works. If it encounters an issue (for example, cross-resource dependencies it cannot resolve), it stops and explains what happened so you can adjust your request.

Once complete, the codified resources appear as managed in the context layer and a pull request is ready for your review on GitHub.

{% hint style="info" %}
Grouping unrelated resources in the same request may cause the import to fail due to dependency conflicts. Stick to resources that belong together.
{% endhint %}

## Reviewing the generated code

After a successful import, you can retrieve the full Terraform code locally using the [Bricks CLI](/docs/bricks-cli/cli-reference/bricks_blueprint/bricks_blueprint_fetch):

```
bricks blueprint fetch
```

Once fetched, you can review, modify, and push the code to your Git repositories.

## Importing from the Cloud Graph

You can also start an import from the [Cloud Graph](/docs/orchestration/cloud-graph) by selecting unmanaged resources visually instead of through conversation.

### Prerequisites

The collection must have both **discovery permissions** and **orchestration permissions** enabled. Without both, the agent cannot analyze existing resources or execute the generated code.

### How to import from the Cloud Graph

<figure><img src="/files/PiAjXcZkJgIYvAD4qwra" alt=""><figcaption></figcaption></figure>

1. Open the **Cloud Graph**
2. Select a **collection** with orchestration and discovery icons (**O**) (**D**)
3. In the explorer drawer, select one or more **unmanaged resources**
4. Add an **environment name**
5. Click **Import**

After the import begins:

* The drawer switches to the agent tab
* The agent codifies the selected resources, iterating until the code and state are synced
* The agent publishes the blueprint and creates the environment

When complete:

* The generated **blueprint** appears in the [blueprints](/docs/orchestration/packages/blueprints-overview) list
* The created **environment** appears in the [environments](/docs/orchestration/environments) list
* The Cloud Graph refreshes with the new managed nodes

### Best practices

* Import logically related resources together, for example resources that make up a single workload
* Use clear and descriptive environment names
* Review generated blueprints before applying further changes
* Create smaller, focused blueprints over large, monolithic ones

### Notes and limitations

* Some resources may require manual adjustments after import
* Import does not modify live infrastructure during the process


# Agent Governance

How approval flows, collection policies, and role-based access control work when managing infrastructure through the agent

## Overview

Every infrastructure change the agent makes goes through the same governance layer as the rest of Bluebricks. This page covers how approval flows, policies, and permissions work in conversation.

## The approval flow

When you ask the agent to make a change, the conversation follows a consistent cycle:

1. **You describe the change**: "Scale the EKS cluster in staging to 5 nodes"
2. **The agent runs a plan**: it generates the proposed changes and shows the plan output inline, including what will be created, updated, or destroyed
3. **You review**: read the plan directly in the conversation. For changes that open a pull request, see [Reading a Bluebricks PR](/docs/agent/reading-a-bluebricks-pr) for how to interpret the output
4. **You approve or reject**: tell the agent to proceed or cancel
5. **The agent applies or stops**: on approval, the changes are applied. On rejection, nothing happens

The agent never auto-approves. Even when no policies require explicit approval, the agent presents the plan and wait for your confirmation before applying.

## How collection policies surface

[Collections](/docs/orchestration/collections) and [blueprints](/docs/orchestration/packages/blueprints-overview) are part of the Bluebricks [orchestration](/docs/orchestration/orchestration) layer: collections group cloud providers with governance rules, and blueprints are the deployable units of infrastructure code. Collection owners and administrators can attach [policies](/docs/orchestration/collections/policies) to collections that control what can be deployed and under what conditions.

When the agent plans a change, these policies are evaluated automatically. If a policy blocks or pauses the run, the agent explains what happened directly in the conversation.

### Owner Approval

When a collection requires owner approval, the agent pauses after the plan and tells you that a collection owner must approve before the changes can be applied. If you are an owner, you can approve in the conversation. If not, the agent tells you who can.

### Cost Limit

If the projected cost of a change exceeds the collection's cost limit, the agent shows the estimated cost and explain that the limit was exceeded. The change can still proceed with owner approval.

### Allowed Blueprints

If you request a deployment using a blueprint or version that is not allowed in the target collection, the agent explains which constraints apply and which blueprints are available.

{% hint style="info" %}
For full details on configuring collection policies, see [Policies](/docs/orchestration/collections/policies).
{% endhint %}

## RBAC in conversation

The agent inherits your permissions. It cannot do anything you could not do yourself through the Bluebricks app or CLI.

* If you lack permission to approve a run, the agent tells you and identifies who can approve
* If you lack permission to deploy to a collection, the agent explains why the request was blocked
* The agent never escalates privileges or bypasses role restrictions

For details on roles and permission configuration, see [Roles and Permissions](/docs/organization-and-security/roles-and-permissions).

## Audit trail

Every approval, rejection, and action taken through the agent is recorded. The task history captures the full conversation, including the plan output, your decision, and the result. This complements the run-level audit trail in the orchestration platform, giving you a complete record across both interfaces.


# Reading a Bluebricks PR

Understand the structured PR format that the Bluebricks agent uses when opening pull requests for infrastructure changes

## Overview

When the Bluebricks agent makes infrastructure changes, it opens a pull request with a structured description designed for fast, confident reviews.

{% hint style="info" %}
**New to Bluebricks?** Bluebricks is an agentic infrastructure platform. The agent can discover cloud resources, generate infrastructure code, and open pull requests on your behalf. Learn more in [What is Bluebricks?](/docs/getting-started/building-blocks)
{% endhint %}

## How the agent opens PRs

A typical flow looks like this:

1. You ask the agent to make an infrastructure change (for example, codifying unmanaged cloud resources or modifying an existing configuration)
2. The agent generates or updates infrastructure code, validates it against the live environment, and iterates until the plan is stable
3. The agent opens a PR with a structured description so reviewers can evaluate the change quickly

The PR description is built around three questions a reviewer needs to answer:

* **Did the agent do what I asked?**
* **Did it touch only what it should?**
* **Is it safe to merge?**

Each section of the PR maps to one or more of these questions.

## PR sections

Every agent-generated PR includes some or all of the following sections. The agent only includes sections where it has concrete data; empty sections are omitted entirely.

<details>

<summary>Summary: what the agent changed</summary>

A one-line description of what the agent changed, written in past tense. For complex changes that span multiple resources, the summary includes bullets listing each modification.

Answers: *did the agent do what I asked?*

</details>

<details>

<summary>Blast radius: risk assessment and scope of impact</summary>

A risk assessment in exactly three lines:

* **Nature of change** (first word): describes what kind of change the diff contains

| Label            | Meaning                                                      |
| ---------------- | ------------------------------------------------------------ |
| **Additive**     | New resources only; nothing existing was modified or removed |
| **Modification** | Existing resources updated in place                          |
| **Destructive**  | Resources removed or recreated                               |

* **Downtime risk**: none, low, medium, or high, with an explanation of why
* **Confidence**: how well the agent understands the change and its impact

| Level      | Meaning                                                      |
| ---------- | ------------------------------------------------------------ |
| **High**   | The agent fully understands this change and its blast radius |
| **Medium** | The agent understands the change but not all side effects    |
| **Low**    | The agent is not confident about the impact                  |

Every label includes a justification. The agent is required to explain its reasoning so reviewers can audit the assessment.

Answers: *did it touch only what it should?* and *is it safe to merge?*

</details>

<details>

<summary>Materials: resources and files involved</summary>

A reference table listing the resources and files involved in the change:

| Field             | Description                                               |
| ----------------- | --------------------------------------------------------- |
| Terraform address | The resource address in code (e.g., `aws_s3_bucket.main`) |
| File              | The file containing the resource definition               |
| Resource ID       | The cloud resource identifier                             |
| Region            | Where the resource is deployed                            |
| Provider          | The cloud provider (aws, azure, gcp)                      |

For changes that span multiple files, a "Files changed" line appears below the table.

Answers: *did it touch only what it should?*

</details>

<details>

<summary>Inspection: how to verify the change</summary>

A set of concrete verification steps the reviewer can run to confirm the change works as expected. Each row in the table includes a check name, the command or action to run, and the expected result.

Answers: *is it safe to merge?*

</details>

<details>

<summary>References: related external documentation</summary>

An optional list of links to relevant external documentation (Terraform provider docs, cloud provider references, or Bluebricks docs). This section only appears when the agent can provide valid URLs; it is omitted rather than showing placeholders.

</details>

## Next steps

* Learn more about the platform: [What is Bluebricks?](/docs/getting-started/building-blocks)
* Learn how the agent works: [Agent Overview](/docs/agent/agents-overview)
* See how the agent codifies cloud resources: [Codifying Infrastructure](/docs/agent/codifying-infrastructure)


# Tips for Working with the Agent

How to write effective prompts for the Bluebricks agent

## Overview

The Bluebricks agent works from live infrastructure data and IaC state. Specific, well-structured prompts yield faster and more precise answers.

## Use resource identifiers

When you have a resource ID, ARN, environment slug, or collection name, use it. The agent pulls live infrastructure data, so an exact identifier means an instant, precise lookup. Descriptions lead to broader searches and sometimes ambiguous results.

> **Good:**
>
> "What manages `sg-0a1b2c3d4e5f`? Does anything else share it?"
>
> "Show me the current state of the `prod-payments` environment."

> **Instead of:**
>
> "What manages our main security group?"
>
> "What's going on with payments?"

{% hint style="success" %}
If you have raw IaC output or console logs, share the resource ID and let the agent pull live state directly. Live data is always more accurate than pasted text.
{% endhint %}

## Specify live state or IaC

The agent can answer from two angles: what is actually running in your cloud account, and what your IaC says should be running. These can differ, and that difference is drift. One word of context ("Terraform", "Helm", or "live") removes all ambiguity.

> **Good:**
>
> "What does Terraform think the instance type is for `i-0abc123`? What is it actually running as in AWS?"
>
> "Is our RDS cluster in `us-east-1` managed by IaC, or is it unmanaged?"

> **Instead of:**
>
> "What's the instance type of that RDS cluster?"

## Scope to a collection or environment

Infrastructure data in Bluebricks is organized by collection. When you include the collection or environment name, the agent skips the org-wide search and goes straight to the right scope.

> **Good:**
>
> "In the production collection, are there any EC2 instances not managed by Terraform?"
>
> "Show me all environments in the `platform-team` collection that are currently drifted."

> **Instead of:**
>
> "Are there any unmanaged EC2 instances?"

{% hint style="info" %}
Omitting the scope is fine when you want org-wide results. If you only care about one collection or environment, say so.
{% endhint %}

## Share what you expected

When something looks wrong, give the agent your baseline. The agent can show you what changed, but it pinpoints the relevant change faster when it knows what you think should be true.

> **Good:**
>
> "Our `prod-api` EKS cluster should be running version 1.29, but something looks off. Can you check what version is live and whether Terraform agrees?"
>
> "Security group `sg-0a1b2c3d` should only allow port 443 inbound. Has anything changed?"

> **Instead of:**
>
> "Something seems wrong with our EKS cluster."

## Ask for topology and blast radius

The agent can show relationships: what is in a VPC, what shares a security group, what sits in a subnet. A hint like "topology", "blast radius", or "what's connected" triggers the right query.

> **Good:**
>
> "Show me everything inside `vpc-0abc123`: subnets, instances, load balancers."
>
> "What's the blast radius if I change security group `sg-0a1b2c3d`? What resources reference it?"

> **Instead of:**
>
> "List EC2 instances."

## Read the deployment plan before approving

When you trigger a deployment, the agent generates a plan and presents it before applying anything. That plan is the right moment to ask questions: what does this resource do, is this change destructive, why is it being replaced? The agent never auto-approves.

> **Good:**
>
> After seeing the plan: "Why is the RDS instance being replaced rather than updated in-place? That's a stateful resource."
>
> "The plan modifies a security group. Show me the before and after for the inbound rules."

> **Instead of:**
>
> Approving a plan without reading it because it looked short.

{% hint style="warning" %}
A short plan can still contain a destructive change. One line like `aws_db_instance.main: must be replaced` can mean data loss. For production environments, review every resource change before approving.
{% endhint %}

## Separate reads from writes

The agent treats read operations (listing resources, showing configs, explaining topology) differently from write operations (deploying, planning, updating infrastructure). For writes, it always pauses for your explicit confirmation. Stating your intent upfront avoids unnecessary back-and-forth.

> **Good:**
>
> "Plan a deployment of `aws-rds-postgres` to the staging collection. Don't apply yet; I just want to see what it would do."
>
> "How many Lambda functions do we have in `eu-west-1`?"

> **Instead of:**
>
> "Deploy the RDS blueprint." (Which collection? Which version? Plan first or apply directly?)

## Quick reference

<table><thead><tr><th width="208.9453125">Practice</th><th>One-liner</th></tr></thead><tbody><tr><td>Use identifiers</td><td>A resource ID or slug beats a description every time</td></tr><tr><td>Specify state or IaC</td><td>Say which layer you care about: live cloud or Terraform</td></tr><tr><td>Scope to collection</td><td>Name the collection or environment to skip the broad search</td></tr><tr><td>Share your baseline</td><td>Tell the agent what you expected when something looks wrong</td></tr><tr><td>Ask for topology</td><td>"What's connected" and "blast radius" unlock relationship views</td></tr><tr><td>Read the plan</td><td>Read it, ask questions, then decide; never skip this step</td></tr><tr><td>Separate reads from writes</td><td>Make your intent clear; the agent pauses for confirmation on all writes</td></tr></tbody></table>


# Orchestration Overview

Manage infrastructure through the Bluebricks platform UI and CLI with governed deployment pipelines.

Bluebricks orchestration gives teams direct control over infrastructure workflows. You define reusable building blocks, target them at specific cloud accounts, and run governed deployment pipelines with plan/approve/apply cycles.

{% hint style="info" %}
**Looking for the conversational interface?** The Bluebricks agent can answer questions about your infrastructure, open PRs, and manage resources through natural conversation. See [Agent Overview](/docs/agent/agents-overview).
{% endhint %}

The orchestration platform and the agent share the same context layer, governance rules, and approval workflows. Teams can use either interface, or both, depending on what fits their workflow.

## How orchestration works

Bluebricks organizes orchestration around three core concepts: **packages** define *what* you deploy, **collections** define *where* it goes, and **environments** define *how* it runs.

### Packages

A package is a reusable unit of Infrastructure as Code (IaC). Instead of managing raw Terraform modules, Helm charts, or CloudFormation templates directly, you wrap them into packages that expose clear inputs, outputs, and metadata.

There are two types of packages:

* **Artifact**: a single IaC component (a Terraform module, a Helm chart, a Bicep template) with defined inputs, outputs, and metadata. Artifacts are building blocks you compose into blueprints
* **Blueprint**: a deployable template made of one or more packages. A blueprint wires artifacts together, sets defaults and constants, and exposes only the inputs the deployer needs to provide

Blueprints support Terraform/OpenTofu, Helm, CloudFormation, Bicep, and Generic artifact types, so you can mix IaC tools within a single blueprint.

[Learn more about packages](/docs/orchestration/packages)

### Collections

A collection is the deployment target. It groups a cloud account, access rules, shared configuration, and governance policies into one place.

Every collection can include:

* **Cloud account**: the AWS account, GCP project, Azure subscription, or on-premises target where resources are created
* **Properties and secrets**: collection-scoped values (like `region`, `project_id`, or database credentials) that are automatically inherited by every package deployed to the collection
* **RBAC**: member and owner roles that control who can create, approve, or execute environments in the collection
* **Policies**: guardrails like Owner Approval, Cost Limits, and Allowed Blueprints that govern what runs and under which conditions

Collections map to how your organization already works. For example, `dev-us-east-1`, `staging`, and `prod-eu-west-1`.

[Learn more about collections](/docs/orchestration/collections)

### Environments

An environment is the workflow that deploys a blueprint into a collection. It is where *what* (the blueprint) meets *where* (the collection) and produces real infrastructure.

When you deploy an environment, Bluebricks evaluates the blueprint and all its child packages to produce a **unified plan** of changes. You can preview the plan, approve it, and apply or destroy the resources when they are no longer needed.

Each execution creates a **run**. A run captures the plan, logs, state updates, and outputs in a single auditable record. Runs are fully versioned, so you can trace exactly how your infrastructure evolved and why.

[Learn more about environments](/docs/orchestration/environments)

## What else is in this section

* [**Orchestration Quick Start**](/docs/orchestration/orchestration-quick-start): Create your first collection, blueprint, and environment end to end
* [**Runs**](/docs/orchestration/runs): Monitor execution, manage state, promote environments, and handle parallel workflows
* [**Cloud Graph**](/docs/orchestration/cloud-graph): Visualize infrastructure across all collections, discover unmanaged resources, and codify them into blueprints
* [**Workflows**](/docs/orchestration/bluebricks-git-repository-guide): Git repository structure, Bricks Action CI/CD, and webhook integrations


# Orchestration Quick Start

Create your first collection, blueprint, and environment using the Bluebricks orchestration platform.

This guide walks you through the core Bluebricks orchestration workflow end to end. By the time you finish, you will have a live environment and a reusable blueprint that defines it.

{% hint style="info" %}
**New to Bluebricks?** Start with the [Quick Start](/docs/getting-started/quick-start) to connect your cloud and meet the agent. This guide is for teams setting up orchestration workflows.
{% endhint %}

## Before you start

Read the [Orchestration Overview](/docs/orchestration/orchestration) to understand how packages, collections, and environments fit together.

You will also need:

* A Bluebricks account with admin-level permissions (sign in at [app.bluebricks.co](https://app.bluebricks.co))
* Access to at least one cloud provider (AWS, GCP, or Azure)
* Infrastructure as Code in a Git repository

## 1. Create a collection and connect a cloud provider

A [collection](/docs/orchestration/collections) is the connecting layer between Bluebricks and your cloud provider. It represents a single cloud account, subscription or project that Bluebricks can discover, orchestrate, and manage.

You use collections to define *where* Bluebricks operates.

To create a collection:

{% stepper %}
{% step %}
**Create a collection**

1. Go to the [**Collections**](https://app.bluebricks.co/collections) page in the Bluebricks app
2. Click **Create collection**
3. Enter a name (for example, `dev-quickstart`)
   {% endstep %}

{% step %}
**Connect your cloud provider**

Continuing from the create collection dialog:

1. Select your cloud provider: **AWS**, **GCP**, **Azure**, or **Self-hosted**
2. In Account Number / ID dropdown, click **Create new**
3. Follow the setup steps to grant Bluebricks the necessary permissions
   1. For provider-specific instructions, see [Connect your Cloud](/docs/getting-started/connect-your-cloud)
4. Click **Connect & Create**
   {% endstep %}
   {% endstepper %}

## 2. Create an environment

An [environment](/docs/orchestration/environments) connects a [blueprint](/docs/orchestration/packages/blueprints-overview) to a collection and tracks the full lifecycle of your infrastructure: planning, applying, and tearing down resources.

From the [**Environments**](https://app.bluebricks.co/environments) page, click **Create environment** to get started.

The steps differ depending on your VCS provider. Pick the tab that matches your setup:

{% tabs %}
{% tab title="GitHub" %}
If your IaC code is in a GitHub repository, Bluebricks can connect directly to it. It creates the blueprint for you, and every push to the configured branch triggers a run. Bluebricks posts a plan to every pull request as a GitHub Check Run.

{% stepper %}
{% step %}
**Select a collection**

Choose the collection you created in step 1.
{% endstep %}

{% step %}
**Set source code**

1. Select your IaC technology (OpenTofu, Terraform, Helm, CloudFormation, or Bicep)
2. Choose how to connect your repository:
   * **From connected repo**: select your GitHub organization and repository from your connected integrations
   * **From remote URL**: enter a Git remote URL manually (for public repositories)
3. Set the branch and, optionally, a subdirectory path

{% hint style="info" %}
Private repositories require the [GitHub integration](/docs/integrations/github) (GitHub App). If no repositories appear, go to **Account Settings** > **Integrations** > **GitHub** to connect your organization.
{% endhint %}
{% endstep %}

{% step %}
**Name the environment**

Enter a descriptive slug (for example, `dev-quickstart`).
{% endstep %}

{% step %}
**Define a blueprint**

Bluebricks creates a blueprint from your source code as part of this flow. Give it a name and optional description. Other team members can reuse this blueprint to deploy the same infrastructure into other collections.
{% endstep %}

{% step %}
**Create the environment**

Click **Create**. Bluebricks generates the blueprint, creates the environment, and triggers the first run automatically.
{% endstep %}
{% endstepper %}

For a deeper walkthrough, see [Creating Environments > From code](/docs/orchestration/environments/creating-environments#how-to-create-from-code). To learn how auto-trigger and PR plans work, see [GitOps Environments](/docs/orchestration/environments/gitops-environments).
{% endtab %}

{% tab title="GitLab, Azure DevOps & other VCS" %}
If your code lives in GitLab, Azure DevOps, Bitbucket, or another provider, the flow has an extra step. You create a blueprint first, then deploy it into an environment. You can automate future runs by integrating Bluebricks into your CI/CD pipeline.

{% stepper %}
{% step %}
**Create a blueprint and add your code**

1. Go to the [**Packages**](https://app.bluebricks.co/packages) page and click **Create Blueprint**
2. Enter a descriptive name (for example, `application-service`)

Then add your IaC code as an artifact:

There are two ways to create an artifact depending on where your code is stored.

If you’ve connected [GitHub](/docs/integrations/github) (or are using a public repo), you can create artifacts directly in the Bluebricks app. If you’re working from a private Github repo or an alternative VCS, artifacts should be published using the CLI.

Choose how you want to create and publish your artifact:

<details>

<summary>Create an artifact directly from the Bluebricks app</summary>

Use this option if you’ve enabled the GitHub integration or are using a public GitHub repository and want your repo to serve as the artifact’s source of truth. Changes to the code will automatically trigger an update process.

To add a artifact:

1. In the packages field, click **+ Add** then click **Create artifact**
2. In the dialog, click **Use repository source**
3. Choose the **repository** and **directory** that contains your IaC code (for example, a Terraform root module)
4. Fill in the artifact details: name, description, and IaC type
5. Click **Create artifact**

</details>

<details>

<summary>Create an artifact with the bricks CLI</summary>

Use this option if your code is in a private repository without the GitHub integration or hosted in another VCS. Artifact updates must be published via your CI pipeline or manually using the CLI.

To add the package:

1. **Open your code’s root directory**\
   Use the folder you’d normally run directly (e.g. `terraform init/apply` or `helm install`).
2. **Publish with the CLI**\
   Run from that directory:

   ```bash
   bricks blueprint publish
   ```

   This generates `bricks.json` and publishes the artifact to the Bluebricks catalog.
3. **Verify in Bluebricks**\
   Go to the [Artifacts](https://app.bluebricks.co/packages?tab=artifact) page in the Bluebricks app to view your newly published artifact and continue to the next step.

</details>
{% endstep %}

{% step %}
**Configure inputs**

Review the inputs that your artifact exposes. For each one, decide whether it should be:

* **Required**: the deployer must provide a value at run time
* **Default**: pre-filled but overridable by the deployer
* **Allowed Values**: a list of permitted values the deployer must choose from

When you are happy with the configuration, save and publish the blueprint. For a deeper walkthrough, see [Creating Blueprints](/docs/orchestration/packages/blueprints-overview/creating-blueprints).
{% endstep %}

{% step %}
**Create an environment**

1. Go to the [**Environments**](https://app.bluebricks.co/environments) page and click **Create environment**
2. Choose **From blueprint**
3. Select the collection you created in step 1
4. Name the environment (for example, `dev-quickstart`)
5. Select the blueprint you just published
6. Click **Create** to trigger the first run
   {% endstep %}
   {% endstepper %}

To automate runs from your CI/CD pipeline, see [GitLab CI/CD](/docs/integrations/gitlab) or [Azure DevOps](/docs/integrations/azure-devops).
{% endtab %}
{% endtabs %}

## 3. Review the plan

After creating the environment, Bluebricks generates a **unified plan** showing every proposed change across all packages in the blueprint.

Review the plan, then **approve** to apply the changes and provision your infrastructure.

If you followed the GitHub tab above, your environment is now Git-connected. Future pull requests targeting the trigger branch automatically generate a plan. Bluebricks posts the results as a GitHub Check Run so reviewers can evaluate infrastructure impact without leaving the PR. See [GitOps Environments > Plan results on pull requests](/docs/orchestration/environments/gitops-environments#plan-results-on-pull-requests) for details.

<details>

<summary>Run failed?</summary>

If your run shows a **Failed** status, the review logs open automatically to help you understand what went wrong.

The logs highlight the exact step or package that caused the failure, making it easier to troubleshoot.

</details>

Once the run completes (it can take a few minutes), your resources are live in the target cloud account.

{% hint style="info" %}
**Need additional help?**

Check out our [**Help Center**](https://bluebricks.co/docs/help/) for guides, FAQs, and support resources.
{% endhint %}

## What's next?

Now that you have a running environment, explore these areas to get more out of Bluebricks:

<table data-view="cards"><thead><tr><th></th><th data-hidden data-card-cover data-type="image">Cover image</th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><p><strong>Properties</strong></p><p>Configure default properties</p></td><td><a href="/files/lHH1zDm65sUzrc052C79">/files/lHH1zDm65sUzrc052C79</a></td><td><a href="/pages/AgwX48yi9NZqdM9IIYyY">/pages/AgwX48yi9NZqdM9IIYyY</a></td></tr><tr><td><p><strong>Policies</strong></p><p>Add approval flows and cost controls</p></td><td><a href="/files/jeSalpFRNhGfcsnCyPwo">/files/jeSalpFRNhGfcsnCyPwo</a></td><td><a href="/pages/JCmPkQRxdAeqDtUKS00A">/pages/JCmPkQRxdAeqDtUKS00A</a></td></tr><tr><td><p><strong>Secrets</strong></p><p>Configure defaults and sensitive values</p></td><td><a href="/files/5ims0xhxke3Uy438Xy9R">/files/5ims0xhxke3Uy438Xy9R</a></td><td><a href="/pages/t8wzCLVozyvEjtnUbg61">/pages/t8wzCLVozyvEjtnUbg61</a></td></tr></tbody></table>

<table data-view="cards"><thead><tr><th></th><th data-hidden data-card-cover data-type="image">Cover image</th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><p><strong>Bricks CLI</strong></p><p>Manage collections, blueprints, and environments from the command line</p></td><td><a href="/files/5sAVDb84pN0l24HoS0ec">/files/5sAVDb84pN0l24HoS0ec</a></td><td><a href="/pages/dntQmowfGi50XVJh7dBJ">/pages/dntQmowfGi50XVJh7dBJ</a></td></tr><tr><td><p><strong>Drift detection</strong></p><p>Automatically detect when infrastructure drifts from the desired state</p></td><td><a href="/files/EJPLhT7sme2o48rhpql1">/files/EJPLhT7sme2o48rhpql1</a></td><td><a href="/pages/ktcChbC2kbe4xqRWGz2H">/pages/ktcChbC2kbe4xqRWGz2H</a></td></tr><tr><td><p><strong>MCP</strong></p><p>Let AI agents interact with Bluebricks through the Model Context Protocol</p></td><td><a href="/files/B5g045FfRNXDmBjyJrb8">/files/B5g045FfRNXDmBjyJrb8</a></td><td><a href="/pages/lCqJ2UXQQOfXqaFbS3hf">/pages/lCqJ2UXQQOfXqaFbS3hf</a></td></tr></tbody></table>


# Collections

A collection is a logical unit for provisioning cloud infrastructure

A Bluebricks **Collection** is a logical unit for provisioning and managing cloud infrastructure. A collection can be tied to a specific cloud provider account, region, or an on-premises target, and member access is controlled via RBAC so permissions remain clear and auditable. You can attach **properties** and **secrets** to a collection; those values are automatically inherited by any package deployed to that collection, keeping packages reusable while allowing them to adapt to their environment context.

{% hint style="success" %}
**Ask the agent.** Explore your collections and resources through natural conversation. See [Agent Overview](/docs/agent/agents-overview).
{% endhint %}

Collections organize infrastructure into clear units that map to how teams actually work: for example, projects, teams, or lifecycle stages such as `development`, `staging`, and `production`. Each collection serves as the foundation for environments by holding shared settings, credentials, and governance rules that determine *where* and *under which policies* blueprints are executed.

<figure><img src="/files/uVNQDHispfITa7w854Np" alt=""><figcaption></figcaption></figure>

{% hint style="info" icon="users" %}
For details on managing who can access a collection, see [Owners and Members](/docs/orchestration/collections/owners-and-members).
{% endhint %}

## What a collection contains

A Collection is more than a label: it bundles the practical pieces Bluebricks needs to operate safely and predictably:

* **Target configuration**: cloud account and any contextual identifiers that determine where resources are created.
* **Policy surface**: the set of Collection Policies (approvals, cost limits, allowed blueprints, etc.) that govern what runs and how.
* **Variables & secrets**: collection-scoped inputs, secret references, and parameter defaults that environments consume.
* **RBAC & access controls**: who may create, edit, approve, or execute environments in the collection.

This bundle ensures that every environment targeted at a Collection follows consistent operational rules and can be audited, repeated, and governed.

## The collection detail page

When you review a collection, the detail page organizes everything into five tabs: **Overview**, **Environments**, **Policies**, **Properties**, and **Secrets**.

<figure><picture><source srcset="/files/bj29TN1fj6zVPCE5o1ar" media="(prefers-color-scheme: dark)"><img src="/files/07k8rvsmJwz8QqjYBxxB" alt=""></picture><figcaption></figcaption></figure>

### Overview tab

The Overview tab is the default view. It shows general information about the collection and the team members assigned to it.

<details>

<summary><strong>General info</strong> displays at the top of the page</summary>

* **Name and color**: the collection display name and color badge
* **Slug**: the unique identifier used in CLI commands and API calls
* **Cloud account**: the connected cloud provider and account
* **Monthly cost**: the current cost against the configured [cost limit](#policies-tab) (visible when the Cost Limit policy is enabled or the current cost is above zero)

</details>

<details>

<summary><strong>Members</strong> lists all users assigned to the collection</summary>

Each row shows the user and their role (Owner or Member). From this table you can:

* Add new members to the collection
* Change a member's role
* Remove a member

</details>

For details on roles and access control, see [Owners and Members](/docs/orchestration/collections/owners-and-members).

### Environments tab

The Environments tab lists all live environments in the collection. Each row links to the [environment detail page](/docs/orchestration/environments) where you can review runs, manage state, and configure drift detection.

Click **Run** to create a new environment by deploying a blueprint to this collection.

{% hint style="info" %}
The **Run** button is disabled if the collection has no connected cloud account or is locked.
{% endhint %}

### Policies tab

The Policies tab lets you enable and configure rules that govern how environments run in this collection. Four built-in policies are available:

* **Owner Approval**: require an owner to approve each run before it executes
* **Cost Limit**: set a maximum cost threshold for infrastructure changes
* **Allowed Blueprints**: restrict which blueprints (and versions) can deploy to the collection
* **Allow Pre-Release Versions**: permit pre-release blueprint versions

For details on how each policy works and how enforcement is applied, see [Policies](/docs/orchestration/collections/policies).

### Properties tab

The Properties tab lets you create, edit, and delete key-value properties scoped to the collection. Properties automatically flow into every blueprint deployed here, supplying values like regions, naming conventions, or account-specific defaults. Properties marked as **enforced** cannot be overridden by environments.

For details on how properties are injected and how to use dynamic values, see [Properties](/docs/orchestration/collections/properties).

### Secrets tab

The Secrets tab lets you create and delete encrypted secrets scoped to the collection. Secrets store sensitive values like API keys, credentials, or tokens that are injected into blueprints at runtime. Secret values are write-once; they cannot be viewed or edited after creation.

{% hint style="info" %}
The **Add secret** button is disabled if the collection is locked or has no encryption key configured.
{% endhint %}

For details on how secrets are referenced in blueprints, see [Secrets](/docs/orchestration/collections/secrets).

## Best practices

* **Name and scope collections clearly** (e.g., `dev-us-east-1`, `staging`, `prod-eu`) so teams and automation can target them unambiguously.
* **Segment sensitive workloads** into dedicated collections or accounts to enforce strict security boundaries.
* **Use collection policies** to protect production and apply cost controls in shared collections.
* **Keep collection variables minimal and explicit**: treat them as the contract for environments.


# Creating Collections

Create collections from the Bluebricks app or CLI to organize infrastructure by team, project, or lifecycle stage

## Overview

Collections organize infrastructure into clear units that match how teams actually work. You can create separate collections for projects, teams, or lifecycle stages such as development, staging, and production. Each collection provides the foundation for environments by holding shared settings and rules.

<figure><img src="/files/bVLwXtpXN7P4y2L8VBVY" alt=""><figcaption><p>Example of creating a collection with AWS</p></figcaption></figure>

## How to create a collection via the Bluebricks app

1. Go to the [Collections](https://app.bluebricks.co/collections) page
2. Click **Create Collection**
3. Enter a **name** for the collection
4. Select the **cloud provider(s)** to connect
   1. Haven't connected your cloud accounts yet? [Learn how to connect your cloud](/docs/getting-started/connect-your-cloud)
5. Configure any required **settings, permissions, and secrets**
6. Click **Create** to finalize the setup

## How to create a collection via the CLI

You can create a new collection using the Bricks CLI (refer to [Bricks CLI Installation Guide](/docs/bricks-cli/bricks-cli) if you haven't installed it yet):

```bash
bricks collection create --name "Self-Hosted Orchestrator"
```

A successful creation displays a confirmation message with the new collection ID:

```
✓ `Self-Hosted Orchestrator` collection created successfully with ID: 42c9d5cf-cf9c-4783-ac1d-4d34140b9299
```

To set the new collection as the default target for commands that don't specify `--collection`:

```bash
bricks collection create --name "development" --default
```

### Naming conventions

* Use clear, descriptive names: `production`, `staging`, `development`
* Include team or project context when needed: `team-alpha-production`
* Follow a consistent pattern across your organization: `{project}-{stage}`

{% hint style="info" %}
After creating a collection, connect a cloud account before deploying. See [Connect your Cloud](/docs/getting-started/connect-your-cloud). To manage existing collections (list, enable, disable, delete), see [Managing Collections](/docs/orchestration/collections/managing-collections).
{% endhint %}


# Managing Collections

List, enable, disable, and delete collections using the Bluebricks app or the Bricks CLI

## Overview

Manage the lifecycle of your collections through the Bluebricks app or the `bricks collection` CLI commands. You can list all collections, check their status, and enable, disable, or delete them as your infrastructure needs change.

{% hint style="info" icon="book" %}
To create a new collection, see [Creating Collections](/docs/orchestration/collections/create-an-environment). For the conceptual overview, see [Collections](/docs/orchestration/collections).
{% endhint %}

## How to list collections

{% tabs %}
{% tab title="Bluebricks app" %}
Open the **Collections** page in the Bluebricks app. The table shows all active collections with their cloud provider, cloud account, and latest deployment status. Use the filters to narrow results by status or provider.
{% endtab %}

{% tab title="CLI" %}

```bash
# List active collections
bricks collection ls

# Include inactive and deleted collections
bricks collection ls --all
```

The command outputs a table with the following fields:

```
GUID                                NAME           CLOUD PROVIDER   CLOUD ACCOUNT   SLUG              STATUS
----------------------------------- -------------- ---------------- --------------- ----------------- -------------------------
env-uuid-123                        production    AWS              aws-prod        production        DEFAULT, web-app (running)
env-uuid-456                        development   AWS              aws-dev         development       api-service (completed)
env-uuid-789                        staging       GCP              gcp-staging     staging           INACTIVE
```

<table><thead><tr><th width="184.71875">Field</th><th>Description</th></tr></thead><tbody><tr><td><strong>GUID</strong></td><td>Unique identifier, used in API calls and some CLI commands (<code>--id</code>)</td></tr><tr><td><strong>NAME</strong></td><td>Display name set during creation</td></tr><tr><td><strong>CLOUD PROVIDER</strong></td><td>Connected provider (AWS, GCP, Azure). Shows <code>-</code> if no cloud account is connected</td></tr><tr><td><strong>CLOUD ACCOUNT</strong></td><td>Connected cloud account name. Shows <code>-</code> if none</td></tr><tr><td><strong>SLUG</strong></td><td>Short identifier used in CLI commands (<code>--slug</code>, <code>--collection</code>)</td></tr><tr><td><strong>STATUS</strong></td><td>Flags and latest deployment info (see below)</td></tr></tbody></table>
{% endtab %}
{% endtabs %}

### Status indicators

<table><thead><tr><th width="237.4921875">Indicator</th><th>Meaning</th></tr></thead><tbody><tr><td><strong>DEFAULT</strong></td><td>Collection is the default target when <code>--collection</code> is omitted</td></tr><tr><td><strong>INACTIVE</strong></td><td>Collection is disabled</td></tr><tr><td><em>deployment-name</em> <em>(stage)</em></td><td>Most recent deployment and its current stage (<code>running</code>, <code>completed</code>, <code>failed</code>)</td></tr><tr><td><code>-</code></td><td>No deployments in this collection</td></tr></tbody></table>

## Collection states

<table><thead><tr><th width="100.25">State</th><th>Description</th></tr></thead><tbody><tr><td>Active</td><td>Collection is enabled and ready for deployments</td></tr><tr><td>Inactive</td><td>Collection is disabled; enable it before deploying</td></tr><tr><td>Default</td><td>Collection is the default target for <code>bricks install</code> when no <code>--collection</code> flag is specified</td></tr></tbody></table>

## How to enable a collection

Reactivate a disabled (locked) collection so it can receive deployments again.

{% tabs %}
{% tab title="Bluebricks app" %}

1. Open the **Collections** page
2. Click the three-dot menu on the inactive collection
3. Click **Unlock**
4. Confirm in the dialog
   {% endtab %}

{% tab title="CLI" %}

```bash
# Enable by slug
bricks collection enable --slug "my-collection"

# Enable by ID
bricks collection enable --id "env-uuid-here"
```

{% endtab %}
{% endtabs %}

## How to disable a collection

Disable (lock) a collection to prevent new deployments. Existing infrastructure is not affected.

{% tabs %}
{% tab title="Bluebricks app" %}

* Open the **Collections** page
* Click the three-dot menu on the collection
* Click **Lock**
* Confirm in the dialog
  {% endtab %}

{% tab title="CLI" %}

```bash
# Disable (prompts for confirmation)
bricks collection disable --slug "my-collection"

# Skip the confirmation prompt
bricks collection disable --slug "my-collection" --y

# Disable by ID
bricks collection disable --id "env-uuid-here"
```

{% endtab %}
{% endtabs %}

{% hint style="warning" %}
Disabling a collection does not destroy deployed resources. It only prevents new deployments from targeting this collection.
{% endhint %}

## How to delete a collection

Before deleting, destroy or [archive](/docs/orchestration/environments/archiving-environments) all active environments in the collection. Bluebricks blocks deletion if any non-archived environments remain.

{% tabs %}
{% tab title="Bluebricks app" %}

1. Open the **Collections** page
2. Click the three-dot menu on the collection
3. Click **Delete**
4. Review the list of associated deployments and confirm
   {% endtab %}

{% tab title="CLI" %}

```bash
bricks collection delete --slug "my-collection"
```

{% endtab %}
{% endtabs %}

The cloud account is not affected by the deletion. It remains available in your organization and can be added to a new collection at any time.

{% hint style="danger" %}
Deleting a collection is irreversible. Archived environments in a deleted collection cannot be un-archived.
{% endhint %}

## How to set a default collection

The default collection is used when you run `bricks install` without specifying `--collection`.

{% tabs %}
{% tab title="Bluebricks app" %}

1. Open the **Collections** page
2. Click the three-dot menu on the collection
3. Click **Set as Default**
4. Confirm in the dialog
   {% endtab %}

{% tab title="CLI" %}
You can set a collection as the default during creation:

```bash
bricks collection create --name "development" --default
```

{% endtab %}
{% endtabs %}

## How to clone a collection

Duplicate an existing collection with its configuration.

### Using the app

1. Open the **Collections** page
2. Click the three-dot menu on the collection
3. Click **Clone**
4. Confirm in the dialog


# Owners and Members

Control who can access and govern your collections by assigning owners and members

## Overview

Every collection has two membership roles: **owner** and **member**. These roles control *who* can access a collection, while [account-level roles](/docs/organization-and-security/roles-and-permissions) control *what* they can do once inside it. Together, the two layers let you grant broad platform capabilities to a user while limiting where those capabilities apply.

<figure><picture><source srcset="/files/gMzRTwfQsV70BHMdyvdq" media="(prefers-color-scheme: dark)"><img src="/files/Xno3U2EbNItirNYaoAxA" alt=""></picture><figcaption></figcaption></figure>

## How account roles and collection membership work together

A user's effective permissions in a collection are the intersection of their account-level role and their collection membership. The account role defines the ceiling (create packages, run deployments, view resources), and membership opens the door to a specific collection.

For the full permissions matrix and recommended role mappings, see [Roles and Permissions](/docs/organization-and-security/roles-and-permissions).

{% hint style="info" %}
Admins bypass membership checks. They can manage any collection, even if they are not listed as an owner or member.
{% endhint %}

## Owners

Every collection must have at least one owner. The user who creates a collection is automatically assigned as its first owner.

Owners have full control over the collection, including:

* Managing member access and roles
* Editing collection properties, secrets, and cloud connections
* Approving runs when the [Owner Approval policy](/docs/orchestration/collections/policies) is active
* Transferring ownership to another user
* Deleting the collection

Owners provide the governance layer that keeps collections secure and aligned with organizational policies. When the Owner Approval policy is enabled on a collection, only owners of that collection can approve runs before they proceed. For details on configuring this policy, see [Policies](/docs/orchestration/collections/policies).

Admins, Builders, and Deployers can all be assigned as collection owners. A Deployer who is an owner can approve runs, but they still can't edit collection settings or create collections since those require a Builder or Admin account role. Viewers cannot be owners.

{% hint style="info" %}
A collection can have multiple owners. This is recommended for redundancy so that approvals and administrative actions are not blocked by a single person's availability.
{% endhint %}

## Members

Members are users who have been granted access to a collection. A member's effective permissions depend on their account-level role:

* A member with the **Builder** role can create and publish packages and run deployments in the collection
* A member with the **Deployer** role can initiate runs but cannot modify packages or collection settings
* A member with the **Viewer** role can browse environments and resources in the collection but cannot make changes

Members cannot manage collection settings (properties, secrets, cloud connections, policies, or membership). Those actions require owner or Admin access.

**Example:** a development team might be added as members with the Builder role in a `staging` collection so they can deploy freely, while only a platform lead is assigned as owner of the `production` collection to enforce tighter governance.

## How to manage owners and members

Owners and members are managed from the collection detail page in the Bluebricks app.

{% hint style="info" icon="user-key" %}
Only admins and collection owners can add, remove, or change membership roles.
{% endhint %}

{% hint style="info" %}
You can also invite new users directly from the collection page using **Invite teammates** in the **Assigned users** section. This opens the invite modal with the collection pre-selected. See [How to invite users](/docs/organization-and-security/roles-and-permissions#how-to-invite-users) for the full flow.
{% endhint %}

<details open>

<summary>Add a member</summary>

1. Open the **Collections** page and select your collection
2. Go to the **Overview** tab
3. In the **Assigned users** section, click **Edit**
4. Select the user you want to add and click **Save**

New users are added as members by default.

</details>

<details>

<summary>Change a user's collection role</summary>

1. Open the collection's **Overview** tab
2. In the **Assigned users** section, find the user
3. Click the **three-dot menu** next to their name
4. Click **Change to owner** or **Change to member**

</details>

<details>

<summary>Remove a user from a collection</summary>

1. Open the collection's **Overview** tab
2. In the **Assigned users** section, find the user
3. Click the **three-dot menu** next to their name and click **Remove**

</details>


# Properties

Adapt reusable blueprints to a specific collection with key-value properties

## Overview

Collection properties supply values like regions, naming conventions, or account-specific defaults that automatically flow into every [blueprint](https://github.com/bluebricks-dev/Bluebricks-Documentation/blob/main/orchestration/packages/creating-blueprints/README.md) deployed to the collection.

<figure><img src="/files/HxaZvybXLA5HVt54haZb" alt=""><figcaption></figcaption></figure>

## How collection properties work

When a blueprint property key matches a collection property name, the collection's value is injected automatically. You define values once at the collection level, and every environment inherits them.

* Collection properties override defaults defined in the blueprint, ensuring consistent values across environments
* If a property is marked as **enforced**, environments must use that exact value (e.g., forcing all resources into `eu-west-1`)
* Properties can reference dynamic values like `${{bricks.collection.slug}}_${{bricks.environment.id}}`

<figure><picture><source srcset="/files/nzvYH6Vm4Ksfocq65GEM" media="(prefers-color-scheme: dark)"><img src="/files/KZazpp1sqHi9H4x1Tk8w" alt=""></picture><figcaption></figcaption></figure>

{% hint style="info" %}
Enforced properties are hard-coded values. If not enforced, they act as defaults that environments can override.
{% endhint %}

## How to set properties

1. Navigate to the desired collection page
2. Select **Properties** from the left side menu
3. Click **Add property**
4. Enter the name (key) and value
5. (Optional) Toggle **Enforced** to lock the value
6. Click **Save**

To delete a property, click the three-dot menu on the property row and select **Delete**.


# Secrets

Store and manage sensitive values like API keys and credentials at the collection level

## Overview

Secrets let you store sensitive values like API keys, credentials, or tokens at the collection level so they can be securely injected into [blueprints](/docs/orchestration/packages/blueprints-overview) at runtime.

By managing secrets centrally, you make it easier to reuse blueprints securely while maintaining strict control over who can access sensitive values.

<figure><img src="/files/n8N2tBbyvaeZhK2lFoNY" alt=""><figcaption></figcaption></figure>

## How collection secrets work

* **Automatic injection**: when a blueprint references a secret key that exists in the collection, the value is injected at runtime
* **Scoped by collection**: each collection has its own isolated secret store; secrets never leak across collections
* **Hidden after save**: secret values are encrypted client-side before they leave your browser and cannot be viewed again after creation. To change a secret value in the UI, delete it and create a new one.
* **Access-controlled**: only users with the right permissions can create or delete secrets. Others can reference them but not view their values.

{% hint style="info" %}
Secret values are encrypted before they leave your browser and are never stored or displayed in plain text. They are only available at runtime within the secure execution context.
{% endhint %}

## How to use secrets in blueprints

### Creating a secret

1. Navigate to the desired collection page
2. Select **Secrets** from the left side menu
3. Click **+ Add secret**
4. Enter the secret name (key) and value
5. Click **Save**

Once saved, the value is encrypted and hidden. You cannot view it again.

{% hint style="warning" %}
Secret names cannot contain hyphens (`-`) when created through the UI. Use underscores or camelCase instead (e.g., `max_password_age`).
{% endhint %}

### Referencing secrets in bricks.json

In your blueprint's `bricks.json`, reference a secret using the `Secrets` keyword followed by the secret's key.

<details>

<summary>Example bricks.json referencing a secret</summary>

```json
{
  "name": "@bluebricks/aws_iam_policy",
  "version": "1.0.0",
  "packages": {
    "iam_password_policy": {
      "name": "terraform_aws_iam_account_policy",
      "version": "1.0.3",
      "props": {
        "max_password_age": {
          "value": "Secrets.max_password_age"
        },
        "minimum_password_length": {
          "value": 14
        }
      }
    }
  }
}
```

</details>

The `max_password_age` property pulls its value from the collection's `max_password_age` secret during runtime. The platform provides the collection's secrets to the runner at deployment time, and the runner resolves each `Secrets.<key>` reference and securely injects the values into the infrastructure execution.

### Referencing secrets in bricks.yaml

In `bricks.yaml`, use the lowercase `secrets` keyword:

```yaml
packages:
  - name: terraform_aws_iam_account_policy
    version: 1.0.3
    props:
      max_password_age: secrets.max_password_age
      minimum_password_length: 14
```

For the full syntax reference, see [Inputs and Outputs](/docs/orchestration/packages/inputs-and-outputs#syntax-quick-reference).

To delete a secret, click the three-dot menu on the secret row and select **Delete**.

## Managed encryption keys

Bluebricks supports two options for secrets encryption:

1. **Bluebricks Managed Key**: encryption key generated and managed by Bluebricks. Contact support to enable this option.
2. **Bring Your Own Key**: use your own cloud KMS key for encryption. Supported providers:
   * **AWS KMS**: `arn:aws:kms:<region>:<account>:key/<key-id>`
   * **Azure Key Vault**: `https://<vault-name>.vault.azure.net/keys/<key-name>`
   * **GCP Cloud KMS**: `projects/<project>/locations/<location>/keyRings/<ring>/cryptoKeys/<key>`


# Policies

Define approval workflows, cost limits, and allowed blueprints to govern how environments operate within a collection

## Overview

Collection policies let you set rules that control how environments run within a collection. They enforce approval workflows, budget limits, and blueprint restrictions so every deployment follows a consistent, auditable process.

<figure><img src="/files/HdnvUloTpn0nA5CsMqve" alt=""><figcaption></figcaption></figure>

## Types of collection policies

Bluebricks provides four built-in policies. Each policy is a toggle you enable per collection; some have additional configuration.

### Owner Approval

The Owner Approval policy requires [collection owners](/docs/orchestration/collections/owners-and-members) to approve a run before it executes. When enabled, the run pauses until an owner confirms the change.

Use this when you need a review gate for sensitive collections (e.g., staging or production).

### Cost Limit

The Cost Limit policy sets a maximum allowed cost for infrastructure changes in the collection. Bluebricks evaluates the projected cost of an IaC change and blocks it if it exceeds the threshold.

* The limit must be between $1 and $1,000,000
* The limit must be greater than the collection's current cost
* Changes that exceed the limit can still proceed with owner approval

### Allowed Blueprints

The Allowed Blueprints policy restricts which [blueprints](/docs/orchestration/packages/blueprints-overview) can be deployed to the collection. For each allowed blueprint, you can choose to permit any version or only specific versions.

* An empty version list means any version is allowed
* A populated version list restricts deployments to those specific versions
* Users can only see blueprints and versions based on their collection [membership](/docs/orchestration/collections/owners-and-members)

### Allow Pre-Release Versions

The Allow Pre-Release Versions policy controls whether pre-release blueprint versions can be deployed to the collection. This is a simple toggle with no additional configuration.

## How policy enforcement works

Whenever a run is triggered, Bluebricks evaluates all enabled policies before execution begins. If a policy is violated:

1. The run is paused or blocked
2. A clear explanation shows which policy failed and why
3. You can update inputs, request owner approval, or adjust the policy before retrying


# Packages

Packages are the reusable building blocks of Bluebricks

Packages are the reusable building blocks you use to create and deploy infrastructure in Bluebricks. They define exactly what should run in an [environment](/docs/orchestration/environments).

Packages help you take individual infrastructure components, whether built in Bluebricks or pulled from existing Infrastructure as Code (IaC), and turn them into modular, versioned, and repeatable deployments. In most cases, a package is simply a published version of an artifact.

## Package types

There are two types of packages:

**Artifact**: a single infrastructure building block. Artifacts define one component's code, inputs, outputs, and metadata. They are not deployed on their own, but they become powerful when reused inside blueprints.

**Blueprint**: a deployable template made of one or more packages. Blueprints connect artifacts together, set defaults, and expose only the inputs needed at deployment time.

<table><thead><tr><th width="202.02734375"></th><th width="262.7265625">Artifact</th><th width="281.21484375">Blueprint</th></tr></thead><tbody><tr><td><strong>What it represents</strong></td><td>A single IaC component (one Terraform module, one Helm chart, one CloudFormation template)</td><td>A composed stack of one or more packages</td></tr><tr><td><strong>Deployable directly?</strong></td><td>No, must be included in a blueprint</td><td>Yes, installed into an environment</td></tr><tr><td><strong>Defines relationships?</strong></td><td>No, it has inputs and outputs but no awareness of other packages</td><td>Yes, wires packages together through data references</td></tr><tr><td><strong>Versioned?</strong></td><td>Yes</td><td>Yes</td></tr><tr><td><strong>Contains other packages?</strong></td><td>No</td><td>Yes, artifacts, other blueprints, or both</td></tr></tbody></table>

The distinction mirrors a common pattern in software: artifacts are libraries, blueprints are applications. You build and test libraries independently, but you ship applications that compose them into something useful.

## The packages list page

<figure><picture><source srcset="/files/jPPFDoqwepgiQIsynmO7" media="(prefers-color-scheme: dark)"><img src="/files/P8UV0p1cuGcwWLkxCnDI" alt=""></picture><figcaption></figcaption></figure>

When you go to the Packages page, the list organizes packages into two tabs: **Blueprints** and **Artifacts**.

### Blueprints tab

The Blueprints tab is the default view. It lists every published blueprint in your organization.

<details>

<summary><strong>Table columns</strong></summary>

Each row shows:

* **Name**: the blueprint name, with an expand icon to reveal child packages
* **Version**: the latest published version
* **Technology**: IaC type badges for the underlying packages (Terraform, OpenTofu, Helm, CloudFormation, Bicep, Generic)
* **Description**: the blueprint description
* **Tags**: tags inherited from the blueprint's packages
* **Published by**: the user who published the blueprint
* **Repository**: the linked source repository

</details>

<details>

<summary><strong>Search and filters</strong></summary>

Use the controls above the table to narrow results:

* **Search**: find blueprints by name or description
* **Artifact**: filter blueprints that contain a specific artifact
* **Technology**: filter by IaC type (Terraform, OpenTofu, Helm, CloudFormation, Bicep, Generic)
* **Tags**: filter by package tags

</details>

Expand a blueprint row to see its child packages, their versions, and IaC types inline.

### Artifacts tab

The Artifacts tab lists every published artifact. It uses the same table columns and filters as the Blueprints tab, except the **Artifact** filter is not available (since you are already viewing artifacts).

## Viewing a blueprint

Select a blueprint row to open its detail page. The blueprint detail page uses a two-panel layout:

* **Left panel**: shows the blueprint name, version, publisher, repository, description, the list of packages it contains, and tags.
* **Right panel**: shows three collapsible sections for **Inputs**, **Outputs**, and **Packages Configuration**, where you can inspect how packages are wired together.

For a full explanation of how blueprints work, including composition, data references, and versioning, see [Blueprints](/docs/orchestration/packages/blueprints-overview).

## Where to start

If you are getting started with packages, begin by creating an artifact, then build up from there:

1. **Create an artifact**: define a reusable infrastructure building block with clear inputs and outputs. [Learn how to create an artifact](/docs/orchestration/packages/artifacts-overview/creating-artifacts)
2. **Create a blueprint**: compose one or more artifacts and define how they connect. [Learn how to create a blueprint](/docs/orchestration/packages/blueprints-overview/creating-blueprints)
3. **Deploy the blueprint into an environment**: Bluebricks orchestrates the environment and runs the underlying infrastructure code for you. [Learn more about environments](/docs/orchestration/environments)


# Blueprints

Blueprints are reusable templates that compose infrastructure stacks

Most infrastructure stacks are made up of multiple components: a VPC, a database, a compute cluster, a load balancer. Each might live in its own Terraform module or Helm chart. A blueprint wires these components together into a cohesive unit that others can deploy reliably, again and again.

{% hint style="success" %}
**Ask the agent.** Import existing cloud resources into blueprints through conversation. See [Codifying Infrastructure](/docs/agent/codifying-infrastructure).
{% endhint %}

> Think of it like a Docker Compose file for infrastructure. Compose defines how containers connect through networks and volumes; a blueprint defines how IaC components connect through data references and shared properties.

## Blueprint as a composition layer

A blueprint wraps one or more [packages](/docs/orchestration/packages) (each representing a distinct infrastructure component) and defines how they connect.

Bluebricks maps the relationships between package inputs and outputs and builds a directed acyclic graph (DAG) to determine execution order. Packages run in parallel where possible and sequentially where one depends on another's output.

This means you can build small, focused artifacts and assemble them into larger stacks without duplicating code or managing execution order manually.

<details>

<summary>Complete Example: bricks.yaml</summary>

```yaml
name: my_app_stack # (Required) Unique blueprint name
version: 1.0.0 # (Required) Semantic version (MAJOR.MINOR.PATCH)
description: Deploys a VPC, database, and app server with secure secret handling  # (Optional)
tag: [app, vpc, database, server] # (Optional)
inputs:
  region:
    type: string
    allowed_values:
      - us-east-1
      - us-west-2

packages:
  - name: vpc # Reference to an artifact or blueprint
    version: 1.0.0
    props:
      region: inputs.region # Reference to a global input
      cidr_block: 10.0.0.0/16 # Hardcoded value

  - name: database
    version: 1.0.0
    props:
      region: inputs.region # Reference to a global input
      db_user: admin # Hardcoded value
      db_password: secrets.db_password # Secret reference
      vpc_id: data.vpc.vpc_id # Data reference to an output of another package

  - name: app_server
    version: 1.0.0
    props:
      db_host: data.database.endpoint # Data reference to an output of another package
      db_user: admin # Hardcoded value
      db_password: secrets.db_password # Secret reference
      
outputs:
  app_server_ip:
    description: Public IP address of the app server
    value: data.app_server.public_ip # Data reference to an output of a package
```

</details>

### Conceptual diagram

{% @mermaid/diagram content="flowchart TB
subgraph BP\["Blueprint v2.1.0"]
direction LR
VPC\[Artifact: aws\_vpc] -->|data ref| Subnet\[Artifact: aws\_subnet]
Subnet -->|data ref| SG\[Artifact: aws\_sg]
end
BP -->|installed into| Env\[Environment: prod-us]
Env -->|targets| Col\[Collection: AWS prod]" %}

In the diagram, three [artifacts](/docs/orchestration/packages/artifacts-overview) compose into a blueprint. Data references between them define the execution order (the DAG). An environment binds the blueprint to a collection, which supplies credentials, properties, and secrets.

## Blueprint as an interface

A blueprint acts as a contract between the person who builds it and the person who deploys it.

**What the builder defines:**

* **Properties (inputs)**: the values a deployer can or must provide at deployment time. Each property can be marked as required, given a default, or constrained to a set of allowed values.
* **Outputs**: values that the blueprint surfaces after execution, such as endpoint URLs, resource IDs, or connection strings. Other blueprints or downstream systems can consume these.
* **Internal wiring:** data references and hardcoded values that stay hidden from the deployer.

**What the deployer sees:**

* A list of required and optional properties to fill in
* A description of what the blueprint provisions
* The outputs it will produce

This separation is intentional. The deployer doesn't need to know that the blueprint internally connects three Terraform modules and a Helm chart. They see a clean interface: "provide a region, an instance size, and a cluster name, and you get a running Kubernetes cluster with a load balancer endpoint."

## Blueprint as a versioned contract

Every published blueprint is immutable and follows semantic versioning (MAJOR.MINOR.PATCH).

This model gives teams reproducibility and trust. When you deploy version `2.1.0` of a network blueprint today and again three months later, you get the same behavior. No one can silently change a published version. If the blueprint needs to evolve, a new version is published.

Immutability also supports auditability. Every environment tracks which blueprint version it ran, making it straightforward to trace what changed and when.

## Blueprint in the deployment lifecycle

A blueprint on its own is a template. It doesn't provision anything until it's bound to an [environment](/docs/orchestration/environments) targeting a specific [collection](/docs/orchestration/collections).

The lifecycle works like this:

1. **Build:** a builder creates and publishes a blueprint with defined packages, properties, and outputs.
2. **Install:** a deployer installs the blueprint into an environment, selecting a target collection and providing property values.
3. **Plan:** Bluebricks evaluates the DAG, resolves data references and secrets from the collection, and produces a unified plan across all packages.
4. **Apply:** the plan executes, provisioning or updating resources in the correct dependency order.
5. **Iterate:** subsequent runs re-evaluate the same blueprint version against the current state, enabling incremental updates, drift correction, or teardown.

The collection provides the runtime context: cloud account credentials, properties, and secrets. The blueprint provides the structural definition. This separation means you can deploy the same blueprint across development, staging, and production collections without modification.


# Creating Blueprints

Combine multiple packages into a reusable, deployable infrastructure blueprint

## Overview

Blueprints define the baseline for your environments in Bluebricks. They allow you to combine multiple infrastructure artifacts (such as Terraform modules, Helm charts, OpenTofu projects, or other code repositories) into a single, versioned template that runs together as one unit. Instead of deploying each piece separately, you define how they connect inside a blueprint. When you deploy, Bluebricks orchestrates all included packages and provisions an environment that is an instance of that blueprint version.

### Blueprint structure

At a high level, a blueprint contains:

* **Metadata**: Name, version, description
* **Inputs**: Configuration exposed to deployers
* **Outputs**: Values exposed to environments
* **Packages**: Artifacts, nested blueprints, or source-based packages

<figure><img src="/files/MLHyAkgxkusqBt8M4Rd2" alt=""><figcaption></figcaption></figure>

## How to create a blueprint

#### **Prerequisites**:

To create a blueprint, you need at least one [package](/docs/orchestration/packages).

{% hint style="info" %}
If you are using a [GitOps environment](/docs/orchestration/environments/gitops-environments), Bluebricks publishes blueprints automatically from your source code on every push. You only need to create blueprints manually when working outside of a GitOps workflow.
{% endhint %}

{% stepper %}
{% step %}
**Open the blueprint creation wizard**

1. Go to the [Packages](https://app.bluebricks.co/packages) page in Bluebricks
2. Click **Create blueprint**
   {% endstep %}

{% step %}
**Enter metadata**

Fill out the fields:

* **Name**: Unique within your organization
  * Names must be lowercase and can contain letters, numbers, hyphens, dots, and underscores
* **Version**: Semantic version (e.g., 1.0.0)
* **Description**: Optionally write how this blueprint will be used
  {% endstep %}

{% step %}
**Add packages**

Choose from published artifacts or blueprints; or create a new artifact:

There are two ways to create an artifact depending on where your code is stored.

If you’ve connected [GitHub](/docs/integrations/github) (or are using a public repo), you can create artifacts directly in the Bluebricks app. If you’re working from a private Github repo or an alternative VCS, artifacts should be published using the CLI.

Choose how you want to create and publish your artifact:

<details>

<summary>Create an artifact directly from the Bluebricks app</summary>

Use this option if you’ve enabled the GitHub integration or are using a public GitHub repository and want your repo to serve as the artifact’s source of truth. Changes to the code will automatically trigger an update process.

To add a artifact:

1. In the packages field, click **+ Add** then click **Create artifact**
2. In the dialog, click **Use repository source**
3. Choose the **repository** and **directory** that contains your IaC code (for example, a Terraform root module)
4. Fill in the artifact details: name, description, and IaC type
5. Click **Create artifact**

</details>

<details>

<summary>Create an artifact with the bricks CLI</summary>

Use this option if your code is in a private repository without the GitHub integration or hosted in another VCS. Artifact updates must be published via your CI pipeline or manually using the CLI.

To add the package:

1. **Open your code’s root directory**\
   Use the folder you’d normally run directly (e.g. `terraform init/apply` or `helm install`).
2. **Publish with the CLI**\
   Run from that directory:

   ```bash
   bricks blueprint publish
   ```

   This generates `bricks.json` and publishes the artifact to the Bluebricks catalog.
3. **Verify in Bluebricks**\
   Go to the [Artifacts](https://app.bluebricks.co/packages?tab=artifact) page in the Bluebricks app to view your newly published artifact and continue to the next step.

</details>

Each added package receives an auto-generated ID, `[package_name]_[short_hash]`, which you can edit if deterministic references are required.
{% endstep %}

{% step %}
**Configure properties and references**

After a package is added, it will appear as a card in the list on the right side of the wizard and display the following:

* **Properties (props)**: Required configuration inputs
* **Outputs**: Values produced after execution

Properties accept pointer references only:

* `inputs.`
* `data.`
* `secrets.`

**Data references**

Use outputs from other packages:

```yaml
vpc_id: data.vpc.vpc_id
```

You can paste full `data.` references directly.

**Secret references**

Reference secrets from your secret manager:

```yaml
db_password: secrets.db_password
```

{% endstep %}

{% step %}
**Define inputs**

Inputs define the global variables of your blueprint. They are declared once at the root level of the blueprint and can be reused across multiple packages.

Inputs appear in the right-side configuration panel and form the deployer interface.

To define an input:

1. Click **+ Inputs**
2. Choose from the inputs associated with the selected packages
   1. You can also create new input fields by clicking Create new input
3. Configure the input field type and value for each input

<figure><img src="/files/Yd3cYki9TyzUDAO7wKyo" alt=""><figcaption></figcaption></figure>

**Input fields type**

You can change the input field type by selecting **the type icon** (e.g., ![](/files/vyPeR3fCyjAmSzeOAA2X)) in the input field and choosing from the following types:

<table><thead><tr><th width="176.6875">Type and icon</th><th>Description</th></tr></thead><tbody><tr><td><img src="/files/gTNMqGqczbR3XZZ3Uhaz" alt="" data-size="line"> Default</td><td>A pre-filled value used if the deployer does not provide one.</td></tr><tr><td><img src="/files/oAiKcIcHf8awSanrF3kq" alt="" data-size="line"> Allowed values</td><td>A list of permitted values. Deployers must choose from this list.</td></tr><tr><td><img src="/files/bDS9rg2skhZC9YoTd1Jr" alt="" data-size="line"> Required</td><td>Indicates whether the input must be provided. If not set, the input is optional unless no <code>default</code> is defined.</td></tr></tbody></table>

**Input example**:

```yaml
inputs:
  region:
    type: string
    description: AWS region
    allowed_values:
      - us-east-1
      - us-west-2
```

{% hint style="info" %}
All defined inputs are reflected under the `inputs` object in the generated JSON.
{% endhint %}
{% endstep %}

{% step %}
**Define outputs**

Outputs expose values from your blueprint to environments.

```yaml
outputs:
  app_server_ip:
    description: Public IP of the app server
    value: data.app_server.public_ip
```

{% hint style="warning" %}
Only expose outputs that environments or external systems need.
{% endhint %}
{% endstep %}

{% step %}
**Create and publish**

When the blueprint is ready, click **Create and publish**.

{% hint style="info" %}
Blueprints are immutable once published. Any change requires creating a new version.
{% endhint %}

When publishing a new version:

* The version becomes selectable in the version switcher
* The latest published version is tagged as **Latest**
* Outdated child package versions are visually indicated
  {% endstep %}
  {% endstepper %}

## Create a blueprint via CLI

You can also create and publish blueprints entirely from the command line using Bricks CLI.

### Prerequisites

* Bricks CLI [installed](/docs/bricks-cli/bricks-cli) and [authenticated](/docs/bricks-cli/authentication) (`bricks login`)
* At least one published [package](/docs/orchestration/packages) to compose

{% stepper %}
{% step %}
**Initialize a blueprint**

```bash
bricks blueprint init
```

The CLI walks you through creating a `bricks.json` with a name, version, and description.
{% endstep %}

{% step %}
**Add packages**

```bash
bricks blueprint add @bluebricks/terraform_aws_vpc
bricks blueprint add @bluebricks/terraform_aws_subnet
```

To pin a specific version, append it to the package name:

```bash
bricks blueprint add @bluebricks/terraform_aws_vpc@1.2.0
```

To remove a package:

```bash
bricks blueprint remove @bluebricks/terraform_aws_vpc
```

{% endstep %}

{% step %}
**Configure dependencies**

Edit `bricks.json` and use `Data.*` references to wire package outputs to inputs. Bluebricks resolves these references to build a directed acyclic graph (DAG) and determines execution order automatically. Packages run in parallel where possible.

For details on DAG execution, see [Parallel Execution](/docs/orchestration/runs/parallel-execution).
{% endstep %}

{% step %}
**Publish the blueprint**

```bash
bricks blueprint publish
```

{% endstep %}
{% endstepper %}

### Updating and versioning

After publishing, you can bump the version and update nested packages:

```bash
bricks blueprint bump --patch
bricks blueprint update --all
bricks blueprint publish
```

To update a specific package only:

```bash
bricks blueprint update @bluebricks/terraform_aws_vpc
```

{% hint style="info" %}
You can also define blueprints using `bricks.yaml` for a slimmer syntax with auto-populated props and outputs. See [Publish with bricks.yaml](/docs/orchestration/packages/blueprints-overview/publish-with-bricks-yaml).
{% endhint %}

## Example blueprint

This example blueprint shows how a simple application stack is defined in YAML. It includes basic metadata, a required `region` input, and three packages that provision a VPC, database, and app server. Values are passed between components using inputs, secrets, and shared data references, and the blueprint finishes by exposing the app server’s public IP as an output.

```yaml
name: my_app_stack
version: 1.0.0
description: Deploys a VPC, database, and app server
tags: [app, vpc, database, server]

inputs:
  region:
    type: string
    allowed_values:
      - us-east-1
      - us-west-2

packages:
  - name: vpc
    version: 1.0.0
    props:
      region: inputs.region
      cidr_block: 10.0.0.0/16

  - name: database
    version: 1.0.0
    props:
      region: inputs.region
      db_user: admin
      db_password: secrets.db_password
      vpc_id: data.vpc.vpc_id

  - name: app_server
    version: 1.0.0
    props:
      db_host: data.database.endpoint
      db_user: admin
      db_password: secrets.db_password

outputs:
  app_server_ip:
    description: Public IP of the app server
    value: data.app_server.public_ip
```

## Source-based packages (Git)

Blueprints can reference packages directly from Git repositories instead of the Bluebricks registry. This supports Git-first workflows and private infrastructure modules.

#### Required fields

```yaml
packages:
  - name: s3
    source: git::https://github.com/org/repo.git?ref=v1.0.0
    native:
      type: terraform
      path: examples/account-public-access
```

#### Native fields

<table><thead><tr><th width="122.82421875">Field</th><th width="607.8046875">Description</th></tr></thead><tbody><tr><td>type</td><td>terraform, opentofu, helm, bicep, generic, cloudformation</td></tr><tr><td>path</td><td>Root execution path inside the repository</td></tr></tbody></table>

#### Supported URL formats

Public HTTPS:

```
git::https://github.com/org/repo.git
git::https://github.com/org/repo.git//subdir?ref=branch
```

Private SSH (CLI only):

```
git::ssh://git@github.com/org/repo.git
git::ssh://git@github.com/org/repo.git//subdir?ref=branch
```

## Advanced publishing options

The sections above cover the standard workflow. The Bricks CLI also provides flags for more control over how blueprints are prepared, bumped, and updated.

### Preparing a blueprint from existing IaC

Use `bricks blueprint prepare` to generate a `bricks.json` from existing infrastructure code. This is useful when you have an IaC project and want to turn it into a Bluebricks artifact without restructuring your code manually.

```bash
bricks blueprint prepare
```

**Key flags:**

* `--iac-type`: set the IaC type explicitly instead of choosing interactively (`terraform`, `opentofu`, `helm`, `cloudformation`, `bicep`). Useful in CI/CD where interactive prompts are unavailable
* `--refactor`: refactor the existing IaC code in place to match the Bluebricks artifact structure

```bash
# Prepare a Terraform project (skip the interactive prompt)
bricks blueprint prepare --iac-type terraform

# Prepare and restructure code in place
bricks blueprint prepare --refactor
```

{% hint style="info" %}
If you publish without a `bricks.json`, the CLI auto-detects `.tf` files as OpenTofu. Run `prepare` with `--iac-type terraform` first if you need Terraform specifically.
{% endhint %}

### Recursive bumping

When a blueprint contains nested packages, use `--recursive` (`-r`) to bump all nested packages to their latest published versions in one step:

```bash
bricks blueprint bump --patch --recursive
```

Without `--recursive`, only the blueprint's own version is bumped.

### Advanced update options

`bricks blueprint update` supports additional flags for fine-grained control:

* `--no-bump`: update package content without bumping the parent blueprint version
* `--overwrite`: overwrite the blueprint's `bricks.json` props and outputs from a recently updated artifact
* `--major` / `--minor` / `--patch`: control which segment of the parent version is bumped
* `--yes` (`-y`): skip interactive approval

```bash
# Update a package without bumping the blueprint version
bricks blueprint update @bluebricks/terraform_aws_vpc --no-bump

# Update and overwrite props/outputs from the updated artifact
bricks blueprint update @bluebricks/terraform_aws_vpc --overwrite

# Update all packages with a minor version bump, skip confirmation
bricks blueprint update --all --minor --yes
```

{% hint style="info" %}
All flags are documented in the [CLI Reference](/docs/bricks-cli/cli-reference/bricks_blueprint). The examples above cover when and why to use each option.
{% endhint %}

## See also

* [Publish with bricks.yaml](/docs/orchestration/packages/blueprints-overview/publish-with-bricks-yaml): simplified YAML-based publishing with auto-populated props
* [Blueprint Composition Patterns](/docs/orchestration/packages/blueprints-overview/blueprint-composition-patterns): architectural patterns, dependency management, and output strategies
* [Using expr](/docs/orchestration/packages/blueprints-overview/expr): expression language for dynamic configuration in `bricks.json`
* [Parallel Execution](/docs/orchestration/runs/parallel-execution): how Bluebricks resolves the DAG and runs packages in parallel


# From Code to Blueprint

Turn existing Infrastructure as Code into a reusable Bluebricks blueprint you can deploy, version, and share across teams

Bluebricks lets you take Infrastructure as Code (IaC), such as Terraform, OpenTofu, Helm, CloudFormation, or Bicep, and publish it as a [blueprint](/docs/orchestration/packages/blueprints-overview): a versioned, reusable package that anyone on your team can deploy. You deploy blueprints into [collections](/docs/orchestration/collections), which represent your target cloud accounts and their configuration.

This guide walks you through publishing a blueprint. You can do this two ways:

* **CLI**: publish a blueprint from your terminal, then create an environment separately to deploy it. Works with any Git host or local directory.
* **Bluebricks app**: create a blueprint and an environment in one step, with automatic runs on every push. Works with GitHub repositories or any public Git URL.

## Prerequisites

* The [Bricks CLI](/docs/bricks-cli/bricks-cli) installed and authenticated (`bricks login`)
* A [collection](/docs/orchestration/collections) with at least one connected cloud account
* Infrastructure as Code in a Git repository or local directory

## How to publish a blueprint from the CLI

The fastest way to turn code into a blueprint is to publish directly from your terminal. This works with any Git host (GitHub, GitLab, Azure DevOps) or a local directory.

### Single module

If you have a Terraform or OpenTofu module with `main.tf`, `variables.tf`, and `outputs.tf`, you can publish it as a blueprint in two steps:

```bash
cd path/to/your/terraform-module
bricks blueprint publish
```

If no `bricks.yaml` or `bricks.json` exists in the directory, the CLI auto-detects your IaC type, generates a `bricks.json` with the correct metadata, packages your code, and uploads the blueprint to Bluebricks. If a config file already exists, the CLI uses it as-is. Your blueprint is now available in your organization and ready to deploy (see [Deploy after publishing](#deploy-after-publishing) below).

{% hint style="warning" %}
The CLI classifies all `.tf` files as OpenTofu. If you are using Terraform, the behavior is the same, but the IaC type in the blueprint metadata will show as `opentofu`.
{% endhint %}

{% hint style="info" %}
If both `bricks.yaml` and `bricks.json` exist in the same directory, the CLI uses `bricks.yaml` and ignores `bricks.json`.
{% endhint %}

If your code lives in a subdirectory rather than the repository root, use the `--src` flag:

```bash
bricks blueprint publish --src ./infra/compute
```

### Multiple packages

If your infrastructure needs more than one module (for example, a VPC and a compute layer), you can compose multiple packages into a single blueprint using `bricks blueprint init`, `add`, and `publish`. For the full walkthrough, including wiring inputs and data references between packages, see [Creating Blueprints](/docs/orchestration/packages/blueprints-overview/creating-blueprints).

### Deploy after publishing

Once published, deploy the blueprint by creating an environment:

{% tabs %}
{% tab title="Bluebricks app" %}
Go to **Environments** > **Create environment** > **From blueprint**, then select your blueprint.
{% endtab %}

{% tab title="CLI" %}

```bash
bricks install
```

The CLI prompts you to select a blueprint and a target collection.
{% endtab %}
{% endtabs %}

For the full walkthrough, see [Creating Environments](/docs/orchestration/environments/creating-environments).

## How to update a blueprint

When you change your IaC code and want to publish a new version, bump the version and republish.

### Bump the version

```bash
bricks blueprint bump --minor
```

This increments the version in your `bricks.json` (for example, from 1.0.0 to 1.1.0). You can also use `--major` or `--patch` depending on the scope of the change. If you omit the flag, the CLI defaults to a minor bump.

### Update nested packages

If your blueprint composes other packages and you want to pull in their latest published versions:

```bash
bricks blueprint update --all
```

To update a specific package:

```bash
bricks blueprint update terraform_aws_vpc
```

### Republish

After bumping and updating, publish the new version:

```bash
bricks blueprint publish
```

Environments pinned to the latest version of this blueprint will pick up the new version on their next run. Environments pinned to a specific version are not affected until you update their configuration.

## How to publish from the Bluebricks app

You can also create a blueprint through the **From code** flow in the Bluebricks app. This connects your repository, creates the blueprint and environment, and auto-triggers runs on every push. Go to **Environments** > **Create environment** > **From code** to get started.

For the full walkthrough, see [Creating Environments](/docs/orchestration/environments/creating-environments). For auto-trigger behavior on push and PR, see [GitOps Environments](/docs/orchestration/environments/gitops-environments).

## Structuring your repository

Bluebricks is flexible about repository layout, whether your code is at the root, in a subdirectory, or spread across a mono-repo with multiple blueprints. For recommended patterns and folder structures, see [Git Repository Folder Structure](/docs/orchestration/bluebricks-git-repository-guide/git-repository-folder-structure).

## What's next?

<table data-view="cards"><thead><tr><th></th><th data-hidden data-card-cover data-type="image">Cover image</th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>Creating environments</strong><br>Deploy your blueprint into a collection</td><td><a href="/files/mbJmfgO5H6vqqqvo0l8E">/files/mbJmfgO5H6vqqqvo0l8E</a></td><td><a href="/pages/wmrjXfTYHjDOou8bKtw7">/pages/wmrjXfTYHjDOou8bKtw7</a></td></tr><tr><td><strong>GitOps Environments</strong><br>Set up automatic plan and apply on every push</td><td><a href="/files/SwjNpAvcBB7iFIXkvPqX">/files/SwjNpAvcBB7iFIXkvPqX</a></td><td><a href="/pages/dEO0qG5EiBiMxvwfKOPo">/pages/dEO0qG5EiBiMxvwfKOPo</a></td></tr><tr><td><strong>Day 2 Operations</strong><br>Scale, update, and manage deployed infrastructure</td><td><a href="/files/YUtDiVulGDfnpbNXFMJB">/files/YUtDiVulGDfnpbNXFMJB</a></td><td><a href="/pages/8nGEvmy9vBAjR8w4oyvl">/pages/8nGEvmy9vBAjR8w4oyvl</a></td></tr></tbody></table>

<table data-view="cards"><thead><tr><th></th><th data-hidden data-card-cover data-type="image">Cover image</th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>Packages</strong><br>Create reusable building blocks used to deploy infrastructure</td><td><a href="/files/kJjU1J5en9mTArv4ytat">/files/kJjU1J5en9mTArv4ytat</a></td><td><a href="/pages/RaVuz2bcyctXGY0ErjIj">/pages/RaVuz2bcyctXGY0ErjIj</a></td></tr><tr><td><strong>Composition Patterns</strong><br>Wire multiple packages together</td><td><a href="/files/TRTAlCljrj8pzEJxdATW">/files/TRTAlCljrj8pzEJxdATW</a></td><td><a href="/pages/MSfXwjSeTcxWsrbAF4AQ">/pages/MSfXwjSeTcxWsrbAF4AQ</a></td></tr><tr><td><strong>Inputs and Outputs</strong><br>Expose the right configuration to deployers</td><td><a href="/files/S9u8WSHE0JQebYN6iXb1">/files/S9u8WSHE0JQebYN6iXb1</a></td><td><a href="/pages/7krvs94XFpdBRktHXu4D">/pages/7krvs94XFpdBRktHXu4D</a></td></tr></tbody></table>


# Using expr

Use the expr expression language in bricks.json for dynamic configuration, conditional logic, string operations, and runtime property references

Bluebricks leverages the [expr](https://expr-lang.org/) expression language to enable dynamic configurations within your `bricks.json` files. This allows for powerful manipulations, conditional logic, and more.

## What is expr?

[expr](https://expr-lang.org/) is a lightweight, high-performance expression language for Go, designed for dynamic evaluation of expressions. In Bluebricks, it lets you:

* Perform arithmetic and string operations
* Use conditional logic (if/else, ternary)
* Access built-in functions for manipulating strings, lists, maps, etc.
* Reference properties, data, and secrets dynamically

## Common Use Cases

* **Basic arithmetic and string operations**: Concatenation, addition, subtraction, etc.
* **Conditional expressions**: Ternary operators or if/else logic.
* **Functions**: Built-in functions for manipulating strings, lists, maps, etc.

## Examples

### 1. Concatenating strings and using current time

```json
{
  "packages": [
    {
      "name": "my_s3_bucket",
      "version": "1.0.0",
      "props": {
        "bucket_name": {
            "value": "now().Format('02012006030405')+'_sample_bucket'+(Props.vpc_id ?? Data.vpc1.vpc_id)"
        }
      }
    }
  ]
}
```

* `now().Format('02012006030405')` generates a timestamp string.
* `'_sample_bucket'` is a static string.
* `(Props.vpc_id ?? Data.vpc1.vpc_id)` uses the null coalescing operator: it will use `Props.vpc_id` if defined, otherwise `Data.vpc1.vpc_id`.

### 2. Conditional Logic (Ternary Operator)

```json
{
  "props": {
    "environment": {
      "type": "string",
      "default": "dev"
    }
  },
  "packages": [
    {
      "name": "my_instance",
      "version": "1.0.0",
      "props": {
        "instance_type": {
            "value": "Props.environment == 'prod' ? 'm5.xlarge' : 't3.medium'"
      }
    }
  ]
}
```

This sets `instance_type` to `m5.xlarge` if `Props.environment` is `prod`, otherwise `t3.medium`.

### 3. Accessing nested properties and list elements

```json
{
  "props": {
    "network_config": {
      "type": "object",
      "default": {
        "subnets": ["subnet-abc", "subnet-def"],
        "security_groups": ["sg-123"]
      }
    }
  },
  "packages": [
    {
      "name": "my_service",
      "version": "1.0.0",
      "props": {
        "subnet_id": { "value": "Props.network_config.subnets[0]" },
        "security_group_id": { "value": "Props.network_config.security_groups[0]" }
      }
    }
  ]
}
```

### 4. Null coalescing for fallbacks

Use the `??` operator to provide fallback values:

```json
{
  "packages": [
    {
      "name": "@bluebricks/terraform_aws_subnet",
      "id": "web_subnet",
      "props": {
        "vpc_id": {
          "value": "Props.vpc_id ?? Data.shared_vpc.vpc_id"
        },
        "availability_zone": {
          "value": "Props.az ?? 'us-west-2a'"
        }
      }
    }
  ]
}
```

`Props.vpc_id ?? Data.shared_vpc.vpc_id` uses `Props.vpc_id` if defined, otherwise falls back to `Data.shared_vpc.vpc_id`.

### 5. String concatenation

Build complex strings from multiple sources:

```json
{
  "packages": [
    {
      "name": "@bluebricks/terraform_aws_route53",
      "id": "dns_record",
      "props": {
        "domain_name": {
          "value": "Props.service_name + '.' + Props.environment + '.' + Props.base_domain"
        }
      }
    }
  ]
}
```

### 6. Mathematical operations

Perform calculations for resource sizing:

```json
{
  "packages": [
    {
      "name": "@bluebricks/terraform_aws_instance",
      "id": "web_servers",
      "props": {
        "count": {
          "value": "Props.environment == 'prod' ? Props.base_instance_count * 2 : Props.base_instance_count"
        }
      }
    }
  ]
}
```

### 7. Complex conditional logic

Combine multiple conditions:

```json
{
  "packages": [
    {
      "name": "@bluebricks/terraform_aws_alb",
      "id": "load_balancer",
      "props": {
        "ssl_certificate_arn": {
          "value": "Props.enable_ssl && Props.environment == 'prod' ? Secrets.prod_ssl_cert : (Props.enable_ssl ? Secrets.dev_ssl_cert : '')"
        }
      }
    }
  ]
}
```

### 8. Output aggregation with expressions

Combine outputs from multiple packages:

```json
{
  "outs": {
    "all_endpoints": {
      "value": "Data.web_server.endpoint + ',' + Data.api_server.endpoint + ',' + Data.admin_server.endpoint",
      "type": "string",
      "description": "All service endpoints"
    },
    "monitoring_dashboard": {
      "value": "Props.enable_monitoring ? Data.monitoring.dashboard_url : 'Monitoring disabled'",
      "type": "string",
      "description": "Monitoring dashboard URL or status"
    }
  }
}
```

## Best practices

* Use expressions for dynamic values, not static ones
* Keep expressions readable; avoid deeply nested ternaries
* Use null coalescing (`??`) for safe fallbacks
* Test complex expressions with different input combinations

## Further reading

* [expr language documentation](https://expr-lang.org/docs/language-definition#operators)
* [expr playground](https://expr-lang.org/playground)
* [Blueprint Composition Patterns](/docs/orchestration/packages/blueprints-overview/blueprint-composition-patterns): architectural patterns that use expressions in context


# Blueprint Composition Patterns

Common patterns for composing blueprints, managing package dependencies, and structuring outputs effectively

Blueprints compose multiple packages into deployable infrastructure stacks. This page covers proven patterns for structuring those compositions, managing dependencies between packages, and controlling outputs.

For the basics of creating blueprints, see [Creating Blueprints](/docs/orchestration/packages/blueprints-overview/creating-blueprints). For dynamic expressions within blueprints, see [Using expr](/docs/orchestration/packages/blueprints-overview/expr).

## Composition patterns

### Layered architecture

Stack packages in layers: infrastructure, platform, then application. Each layer depends on the one below it.

```yaml
packages:
  - name: terraform_aws_vpc
    id: infrastructure_vpc
    version: 1.0.0

  - name: terraform_aws_subnet
    id: infrastructure_subnet
    version: 1.0.0
    props:
      vpc_id: !expr data.infrastructure_vpc.vpc_id

  - name: helm_nginx
    id: platform_nginx
    version: 1.0.0
    props:
      cluster_name: !expr data.infrastructure_subnet.cluster_name

  - name: helm_myapp
    id: application_myapp
    version: 1.0.0
    props:
      nginx_endpoint: !expr data.platform_nginx.endpoint
```

This gives you clear separation of concerns, predictable dependency flow, and easy maintenance.

### Hub and spoke

A central package provides shared resources to multiple consumers.

```yaml
packages:
  - name: terraform_aws_vpc
    id: hub_vpc
    version: 1.0.0

  - name: terraform_aws_subnet
    id: spoke_web
    version: 1.0.0
    props:
      vpc_id: !expr data.hub_vpc.vpc_id

  - name: terraform_aws_subnet
    id: spoke_db
    version: 1.0.0
    props:
      vpc_id: !expr data.hub_vpc.vpc_id

  - name: terraform_aws_subnet
    id: spoke_cache
    version: 1.0.0
    props:
      vpc_id: !expr data.hub_vpc.vpc_id
```

Spoke packages run in parallel since they share the same dependency. This pattern works well for shared networking, centralized databases, or common security groups.

### Microservices composition

Each service is a separate package with shared infrastructure dependencies.

```yaml
packages:
  - name: terraform_aws_vpc
    id: shared_vpc
    version: 1.0.0

  - name: helm_user_service
    id: user_service
    version: 1.0.0
    props:
      vpc_id: !expr data.shared_vpc.vpc_id

  - name: helm_order_service
    id: order_service
    version: 1.0.0
    props:
      vpc_id: !expr data.shared_vpc.vpc_id
      user_service_url: !expr data.user_service.endpoint

  - name: helm_payment_service
    id: payment_service
    version: 1.0.0
    props:
      vpc_id: !expr data.shared_vpc.vpc_id
      order_service_url: !expr data.order_service.endpoint
```

Services with no cross-dependency run in parallel. Services that consume another service's output run after their dependency completes.

### Environment-specific composition

Use blueprint inputs to configure the same blueprint differently per collection.

```yaml
name: my_blueprint
version: 1.0.0

inputs:
  environment:
    type: string
    description: Environment name
  instance_count:
    type: number
    description: Number of instances

packages:
  - name: terraform_aws_instance
    id: web_instances
    version: 1.0.0
    props:
      count: !expr inputs.instance_count
      environment: !expr inputs.environment
```

Install the same blueprint into different collections with different values:

```bash
# Development collection
bricks install my_blueprint --collection dev --props-file props-dev.yaml

# Production collection
bricks install my_blueprint --collection prod --props-file props-prod.yaml
```

## Dependency management patterns

### Explicit dependencies with version pinning

Pin specific package versions for stability and reproducibility.

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

  - name: terraform_aws_subnet
    id: subnet
    version: 1.1.0
    props:
      vpc_id: !expr data.vpc.vpc_id
```

### Conditional dependencies

Use expressions to control package behavior based on configuration. For a full reference on expression syntax, see [Using expr](/docs/orchestration/packages/blueprints-overview/expr).

```yaml
name: my_blueprint
version: 1.0.0

inputs:
  enable_monitoring:
    type: bool
    default: true

packages:
  - name: terraform_aws_instance
    id: web_server
    version: 1.0.0

  - name: helm_prometheus
    id: monitoring
    version: 1.0.0
    props:
      target_instance: !expr data.web_server.private_ip
      enabled: !expr inputs.enable_monitoring
```

## Output management patterns

### Aggregated outputs

Combine outputs from multiple packages into a single blueprint output.

```yaml
outputs:
  web_endpoints:
    value: !expr "data.web_server.endpoint + ',' + data.api_server.endpoint"
    description: All web endpoints
  database_info:
    value: !expr data.database.connection_string
    description: Database connection
```

### Conditional outputs

Bluebricks only executes components whose outputs are actually needed. Use conditional outputs to control which packages run.

```yaml
outputs:
  monitoring_url:
    value: !expr "inputs.enable_monitoring ? data.monitoring.url : 'Monitoring disabled'"
    description: Monitoring dashboard URL
```

If `enable_monitoring` is `false`, the monitoring component is not executed. This follows Bluebricks' output-driven execution model: inputs flow down, data flows up based on actual requirements.

### Structured outputs

Organize outputs into logical groups for clarity.

```yaml
outputs:
  infrastructure:
    value: !expr data.vpc.vpc_id
    description: VPC ID
  application:
    value: !expr data.web_app.url
    description: Application URL
  monitoring:
    value: !expr data.monitoring.dashboard_url
    description: Monitoring dashboard
```

## Best practices

* Choose packages that complement each other and verify compatibility
* Minimize dependencies and avoid circular references
* Use clear, descriptive naming conventions for package IDs
* Provide sensible defaults for blueprint inputs
* Test blueprint composition locally before publishing
* Pin package versions for production blueprints

## Anti-patterns to avoid

### Circular dependencies

```yaml
# DON'T: Circular dependency
packages:
  - name: package_a
    version: 1.0.0
    props:
      value: !expr data.package_b.output

  - name: package_b
    version: 1.0.0
    props:
      value: !expr data.package_a.output
```

### Deep dependency chains

```yaml
# DON'T: Long sequential chain prevents parallelism
packages:
  - name: pkg1
    id: pkg1
    version: 1.0.0
  - name: pkg2
    id: pkg2
    version: 1.0.0
    props:
      dep: !expr data.pkg1.out
  - name: pkg3
    id: pkg3
    version: 1.0.0
    props:
      dep: !expr data.pkg2.out
  - name: pkg4
    id: pkg4
    version: 1.0.0
    props:
      dep: !expr data.pkg3.out
  - name: pkg5
    id: pkg5
    version: 1.0.0
    props:
      dep: !expr data.pkg4.out
```

Prefer hub-and-spoke or layered patterns to maximize parallel execution.

### Unclear output references

```yaml
# DON'T: Ambiguous reference
outputs:
  result:
    value: !expr data.pkg.out
    description: Result
```

Use descriptive output names that indicate what the value represents.

## See also

* [Creating Blueprints](/docs/orchestration/packages/blueprints-overview/creating-blueprints): step-by-step guide for the UI wizard and CLI
* [Using expr](/docs/orchestration/packages/blueprints-overview/expr): expression language for dynamic configuration
* [Parallel Execution](/docs/orchestration/runs/parallel-execution): how Bluebricks resolves the DAG and runs packages in parallel


# Local Development

Test and iterate on blueprints locally using bricks run before deploying to cloud environments

Use `bricks run` to test a published blueprint locally before deploying to a cloud environment. This lets you validate configuration, inspect execution plans, and iterate without affecting live infrastructure.

## How it works

Run a published blueprint directly from the registry:

```bash
bricks run @namespace/blueprint-name@version [flags]
```

You can also point at a local directory after fetching a blueprint (see below):

```bash
bricks run ./my-blueprint [flags]
```

For the full flag reference, see [`bricks run`](/docs/bricks-cli/cli-reference/bricks_run).

## Fetching a blueprint locally

Use `bricks blueprint fetch` to download a blueprint from the registry to your local machine:

```bash
bricks blueprint fetch @namespace/blueprint-name@version --output ./my-blueprint
```

If the blueprint contains child packages, include them with `--include-children`:

```bash
bricks blueprint fetch @namespace/blueprint-name@version --output ./my-blueprint --include-children
```

To inspect the expected inputs before running, use `bricks blueprint get props`:

```bash
bricks blueprint get props @namespace/blueprint-name@version
```

Then prepare a JSON properties file and run locally:

```bash
bricks run ./my-blueprint --props-file props.json
```

For the full flag reference, see [`bricks blueprint fetch`](/docs/bricks-cli/cli-reference/bricks_blueprint/bricks_blueprint_fetch).

{% hint style="warning" %}
The `--props-file` and `--secrets-file` flags accept **JSON only**. YAML is not supported. Passing a YAML file will cause a parsing error.
{% endhint %}

## Development workflow

{% stepper %}
{% step %}
**Choose a blueprint**

Pick a published blueprint from the Bluebricks registry.
{% endstep %}

{% step %}
**Fetch and inspect**

Download the blueprint and review its expected inputs:

```bash
bricks blueprint fetch @namespace/blueprint-name@version --output ./my-blueprint
bricks blueprint get props @namespace/blueprint-name@version
```

{% endstep %}

{% step %}
**Prepare properties**

Create a JSON file with the required properties:

```json
{
  "region": "us-east-1",
  "instance_type": "t3.medium"
}
```

{% endstep %}

{% step %}
**Plan locally**

Preview the execution plan without applying changes:

```bash
bricks run @namespace/blueprint-name@version --dry --props-file props.json
```

{% endstep %}

{% step %}
**Apply locally**

Execute the blueprint on your machine:

```bash
bricks run @namespace/blueprint-name@version --props-file props.json
```

{% endstep %}

{% step %}
**Iterate**

Review outputs, fix issues, adjust configuration, and repeat. Use `--verbose` to see detailed execution steps:

```bash
bricks run @namespace/blueprint-name@version --dry --verbose --props-file props.json
```

{% endstep %}
{% endstepper %}

## Common flags

<table><thead><tr><th width="212.59375">Flag</th><th>Purpose</th></tr></thead><tbody><tr><td><code>--dry</code></td><td>Generate plan without applying</td></tr><tr><td><code>--apply</code></td><td>Apply the plan instead of running in plan-only mode</td></tr><tr><td><code>--destroy</code></td><td>Generate destroy plan</td></tr><tr><td><code>--verbose</code></td><td>Print detailed execution steps</td></tr><tr><td><code>--props-file FILE</code></td><td>Load properties from a JSON file</td></tr><tr><td><code>--props JSON</code></td><td>Pass properties as an inline JSON string</td></tr><tr><td><code>--secrets-file FILE</code></td><td>Load secrets from a JSON file</td></tr><tr><td><code>--secrets JSON</code></td><td>Pass secrets as an inline JSON string</td></tr><tr><td><code>--output DIR</code></td><td>Set output directory for plan, state, and artifacts</td></tr></tbody></table>

## Local state

When you run a blueprint locally, state is stored in the output directory:

```
./packages/
├── <package-id>/
│   ├── state.json
│   ├── plan.json
│   └── outputs.json
```

Local state is not uploaded to Bluebricks. It persists across local runs and can be cleared manually with `rm -rf ./packages/`.

## Local vs cloud execution

<table data-header-hidden><thead><tr><th width="176.74609375"></th><th></th><th></th></tr></thead><tbody><tr><td></td><td>Local (<code>bricks run</code>)</td><td>Cloud (<code>bricks install</code>)</td></tr><tr><td>Cloud resources</td><td>Plans generated, no API calls</td><td>Full cloud provisioning</td></tr><tr><td>State</td><td>Local filesystem</td><td>Centralized in Bluebricks</td></tr><tr><td>Tracking</td><td>Not tracked</td><td>Full history in Bluebricks</td></tr><tr><td>Team visibility</td><td>Local only</td><td>Shared across team</td></tr><tr><td>Authentication</td><td>Local cloud credentials required</td><td>Collection-managed credentials</td></tr></tbody></table>

## Transitioning to cloud

After local validation, deploy to a cloud environment:

```bash
bricks install @namespace/blueprint-name@version --collection development
```

Property files you used locally work with cloud deployments too:

```bash
bricks install @namespace/blueprint-name@version --collection production --props-file props.json
```

{% hint style="info" %}
For Terraform/OpenTofu artifacts, you can also develop against remote state using `bricks bp state-config`. See [Develop Terraform Locally](https://bluebricks.co/docs/help/guides/develop-terraform-locally) for that workflow.
{% endhint %}

## See also

* [`bricks run` reference](/docs/bricks-cli/cli-reference/bricks_run)
* [`bricks blueprint fetch` reference](/docs/bricks-cli/cli-reference/bricks_blueprint/bricks_blueprint_fetch)
* [Develop Terraform Locally](https://bluebricks.co/docs/help/guides/develop-terraform-locally)
* [Inputs & Outputs](/docs/orchestration/packages/inputs-and-outputs)


# Publish with bricks.yaml

Publish blueprints using bricks.yaml for simplified syntax, auto-populated fields, multi-document support, and YAML-native features

`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).

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


# Artifacts

Artifacts wrap your existing IaC code into versioned, reusable building blocks

You already have infrastructure code: Terraform modules, Helm charts, CloudFormation templates. Artifacts are how that code becomes standardized, versioned building blocks that others can discover and reuse without needing to read the source.

Artifacts wrap a single IaC component with a thin metadata layer (`bricks.json`) that declares the component's inputs, outputs, and native tooling. Your code stays untouched. Bluebricks reads the metadata, catalogs the artifact, and makes it available for composition into [blueprints](/docs/orchestration/packages/blueprints-overview).

## What an artifact contains

Every artifact has two parts: the IaC code you already wrote, and a `bricks.json` file that describes it.

The metadata defines:

* **Name and version**: a unique identifier and a semantic version (MAJOR.MINOR.PATCH). Every published version is immutable.
* **Inputs (props)**: the variables your component accepts. These become the interface that blueprint builders wire values into.
* **Outputs (outs)**: the values your component produces after execution, such as resource IDs, endpoints, or connection strings. Blueprints can pass these as inputs to other packages.
* **Native technology**: which IaC tool runs the code (Terraform, Helm, CloudFormation, Bicep, or Generic).

The artifact itself doesn't change how your code works. If you can run `terraform plan` or `helm install` against it today, it will work the same way inside Bluebricks.

<details>

<summary>Example: bricks.json for a Terraform artifact</summary>

```jsonc
{
  "name": "aws_vpc",                       // Unique artifact name (underscores, not hyphens)
  "description": "Creates a VPC with public and private subnets",
  "version": "1.2.0",                      // Semantic version (immutable once published)
  "native": {
    "type": "terraform",                   // IaC tool: terraform | opentofu | helm | cloudformation | bicep | generic
    "path": "."                            // Path to the IaC code relative to bricks.json
  }
  // Inputs (props) and outputs (outs) are auto-detected from variables.tf and outputs.tf
  // for Terraform/OpenTofu artifacts. Other types declare them explicitly.
}
```

A typical artifact repository:

```
aws_vpc/
├── bricks.json          # Artifact metadata
├── main.tf              # Infrastructure definitions
├── variables.tf         # Input variables → become artifact props
├── outputs.tf           # Output values → become artifact outs
└── versions.tf          # Provider versions
```

</details>

## Supported IaC types

Artifacts support six IaC technologies:

* **Terraform / OpenTofu**: root modules with standard `variables.tf` and `outputs.tf` files
* **Helm**: Helm charts with `values.yaml` inputs
* **CloudFormation**: templates with parameters and outputs
* **Bicep**: Bicep files with parameters
* **Generic**: container-based execution for anything that doesn't fit the above categories

Each type maps its native input/output conventions to the artifact's props and outs, so blueprint builders get a consistent interface regardless of the underlying tool.

## How artifacts fit into blueprints

An artifact is not directly deployable. It represents a single component, not a complete stack.

To deploy infrastructure, you compose one or more artifacts into a [blueprint](/docs/orchestration/packages/blueprints-overview). The blueprint wires their inputs and outputs together, sets defaults, and exposes only the properties a deployer needs to provide. Bluebricks resolves the dependency order and runs each artifact's native tool in sequence.

This separation keeps artifacts focused and reusable. A single `aws_vpc` artifact can appear in a networking blueprint, a full-stack application blueprint, and a sandbox blueprint, each wiring it differently without duplicating code.


# Creating Artifacts via CLI

Create reusable Infrastructure as Code artifacts in Bluebricks to standardize infrastructure and enable consistent deployments across environments

## Overview

This guide covers publishing artifacts using the [bricks CLI](/docs/bricks-cli/bricks-cli). Use this approach when Bluebricks cannot access your repository directly, for example with private repos without the [GitHub integration](/docs/integrations/github), or non-GitHub version control systems.

{% hint style="success" icon="box-open-full" %}
If you've connected GitHub or are using a public repo, you can create artifacts directly in the Bluebricks app during blueprint creation. [See Creating Blueprints to learn how](/docs/orchestration/packages/blueprints-overview/creating-blueprints)
{% endhint %}

## Supported IaC types

Bluebricks supports multiple IaC technologies:

* Terraform
* OpenTofu
* Helm
* CloudFormation
* Bicep
* Generic (container-based execution)

{% hint style="info" %}
Don't have code that defines your resources yet? Let the [cloud import agent](/docs/agent/codifying-infrastructure) codify them for you.
{% endhint %}

## How to publish artifacts via CLI

An artifact is automatically generated through a single CLI command from the code's directory.

**Prerequisites**

* Installed [bricks command line](https://bluebricks.co/docs/bricks-cli/bricks-cli)

{% stepper %}
{% step %}
**Navigate to your code's root folder**

For example:

```
my_s3_module/
├── main.tf              # Infrastructure definitions
├── variables.tf         # Input variables
├── outputs.tf           # Output values
└── versions.tf          # Provider versions
```

{% hint style="info" %}
Your code must be self-contained and executable with its native tool, such as terraform init/plan/apply or helm install. *For Terraform or OpenTofu, this means the **root module** you would normally navigate into and run directly.*
{% endhint %}
{% endstep %}

{% step %}
**Publish with the CLI**

Publish it from the artifact directory:

```bash
bricks blueprint publish
```

This command generates a slim metadata file (bricks.json) and publishes it into the Bluebricks catalog.
{% endstep %}

{% step %}
**View your artifacts**

Go to the [Artifacts page](https://app.bluebricks.co/packages) in Bluebricks to see your new artifact.
{% endstep %}
{% endstepper %}

## How to update your artifacts with CLI

Following any change to the underlying IaC you should update your artifact and re-publish it.

{% stepper %}
{% step %}
**Navigate to your code's root folder**
{% endstep %}

{% step %}
**Change the artifacts version**

Run the following command to update the semantic version

```bash
bricks blueprint bump
```

You can also manually open the bricks.json file of the artifact, change the version and save it.
{% endstep %}

{% step %}
**Publish the new version**

Publish the new version using

```bash
bricks blueprint publish
```

{% endstep %}
{% endstepper %}

## Artifact example

Every artifact is defined by a `bricks.json` file at its root.

This file describes:

* The artifact name
* Semantic version
* Inputs (`props`)
* Outputs (`outs`)
* The native IaC implementation (`native`)

**Example:**

```jsonc
{
  "name": "aws_vpc",
  "description": "Creates a VPC with public and private subnets",
  "version": "1.2.0",
  "native": {
    "type": "terraform",
    "path": "./terraform"
  }
}
```

A standard artifact repository:

```
my_s3_artifact/
├── bricks.json          # Artifact definition
├── main.tf              # Infrastructure definitions
├── variables.tf         # Input variables
├── outputs.tf           # Output values
└── versions.tf          # Provider versions
├── README.md            # Documentation
└── examples/            # Usage examples
    └── basic/
        ├── main.tf
```

## Publishing options

The `bricks blueprint publish` command accepts publish-specific flags:

| Flag                | Description                                                                |
| ------------------- | -------------------------------------------------------------------------- |
| `--src <path>`      | Publish from a specific directory instead of the current working directory |
| `--state`           | Include a `.tfstate` file in the published artifact for migration purposes |
| `--resolve-modules` | Resolve and include external Terraform module references (default: `true`) |

**Examples:**

```bash
# Publish from a different directory
bricks blueprint publish --src ./my_artifact

# Include state file for migration
bricks blueprint publish --state

# Disable external module resolution
bricks blueprint publish --resolve-modules=false
```

{% hint style="info" %}
Global CLI flags such as `--api-key` and `--non-interactive` are also available on this command. See the [CLI Reference](/docs/bricks-cli/cli-reference/bricks_blueprint/bricks_blueprint_publish) for the full list, and [CLI Authentication](/docs/bricks-cli/authentication) for details on API key usage.
{% endhint %}

## Publishing flow

When you run `bricks blueprint publish`, the CLI performs these steps:

{% stepper %}
{% step %}
**Validation**

The CLI validates your `bricks.json` configuration and checks that all required fields are present.
{% endstep %}

{% step %}
**Source preparation**

The artifact source code is packaged into a zip archive. External Terraform module references are resolved unless `--resolve-modules=false` is set.
{% endstep %}

{% step %}
**Upload**

The packaged artifact and `bricks.json` are uploaded to the Bluebricks platform as a single multipart request.
{% endstep %}

{% step %}
**Registration**

The artifact is registered in your organization's catalog with the version specified in `bricks.json`.
{% endstep %}

{% step %}
**Confirmation**

The CLI returns a success confirmation with the published artifact details.
{% endstep %}
{% endstepper %}

## Authentication for CI/CD

For automated pipelines, authenticate with an API key instead of interactive login:

```bash
# Environment variable (recommended)
export BRICKS_API_KEY="bbx_your_api_key_here"
bricks blueprint publish

# CLI flag
bricks blueprint publish --api-key "bbx_your_api_key_here"
```

For full details on API key creation and authentication methods, see [CLI Authentication](/docs/bricks-cli/authentication).

{% hint style="info" %}
For GitHub Actions workflows, use the [Bricks Action](/docs/integrations/githubactions) instead of running CLI commands directly.
{% endhint %}


# Terraform/OpenTofu

Terraform and OpenTofu: understand managed state, input/output, and versioned rollouts

## Overview

Terraform and OpenTofu artifacts let you define, plan, and provision infrastructure resources declaratively using standard Terraform or OpenTofu configurations, while leveraging Bluebricks' orchestration engine for consistent, auditable execution across collections.

By encapsulating your IaC module as an artifact, you can integrate infrastructure changes directly into environment pipelines, apply collection-specific inputs, and ensure controlled, versioned rollouts.

<table><thead><tr><th width="242.71875">Feature</th><th>Details</th></tr></thead><tbody><tr><td><strong>Dual-engine support</strong></td><td>Select HashiCorp Terraform CLI or OpenTofu CLI per artifact</td></tr><tr><td><strong>Automatic state backend</strong></td><td>Bluebricks hosts and locks state (no S3 buckets or DynamoDB tables required)</td></tr><tr><td><strong>Input auto-wiring</strong></td><td>All props and secrets are passed in <code>0_bbx_props.auto.tfvars</code> at runtime</td></tr><tr><td><strong>Plan review</strong></td><td>Plans show resource actions and "known after apply" outputs</td></tr><tr><td><strong>Outputs capture</strong></td><td><code>terraform output -json</code> is parsed into artifact outputs after apply</td></tr><tr><td><strong>Version pinning</strong></td><td>The <code>version</code> field locks the CLI binary (defaults: Terraform 1.5.7, OpenTofu 1.8.7). See <a href="#version-pinning">version pinning</a> for limits and examples</td></tr><tr><td><strong>State import</strong></td><td>Optionally import an existing <code>.tfstate</code> file into managed state</td></tr></tbody></table>

For a complete guide to how inputs and outputs work across all IaC tools, see [Inputs & Outputs](/docs/orchestration/packages/inputs-and-outputs).

## Required files and directory structure

A Terraform/OpenTofu artifact requires standard `.tf` files in the directory specified by `native.path`:

```
my-terraform-artifact/
├── bricks.json             # Artifact manifest
└── iac/                    # native.path points here
    ├── main.tf             # Resource definitions
    ├── variables.tf        # Input variable declarations
    ├── outputs.tf          # Output declarations
    └── versions.tf         # Provider and Terraform version constraints
```

The `native.path` field in `bricks.json` must point to the directory containing your `.tf` files. Subdirectories, modules, and additional files (e.g., `terraform.tfvars`, `.tfvars` files) are supported.

## bricks.json reference

<table><thead><tr><th width="148.72265625">Field</th><th width="121.96875">Required</th><th>Description</th></tr></thead><tbody><tr><td><strong><code>type</code></strong></td><td>Yes</td><td><code>"terraform"</code> or <code>"opentofu"</code> (alias <code>"tofu"</code>)</td></tr><tr><td><strong><code>path</code></strong></td><td>Yes</td><td>Directory containing <code>main.tf</code>, modules, etc.</td></tr><tr><td><strong><code>version</code></strong></td><td>No</td><td>Locks the CLI binary for deterministic output</td></tr><tr><td><strong><code>state</code></strong></td><td>No</td><td><code>"managed"</code> (default) = Bluebricks backend</td></tr><tr><td><strong><code>state_path</code></strong></td><td>No</td><td>Relative <code>.tfstate</code> file to import on first run</td></tr></tbody></table>

### Version pinning

Pin a specific CLI version with the `native.version` field in `bricks.json`. Supported ranges:

| Tool      | Min version | Max version | Default |
| --------- | ----------- | ----------- | ------- |
| Terraform | 1.0.0       | 1.5.7       | 1.5.7   |
| OpenTofu  | 1.0.0       | Latest      | 1.8.7   |

Terraform is capped at 1.5.7 because later versions use the BSL license. OpenTofu tracks the latest open-source release.

<details>

<summary>Terraform example</summary>

```json
{
  "native": {
    "type": "terraform",
    "path": "./src/terraform",
    "version": "1.5.7"
  }
}
```

</details>

<details>

<summary>OpenTofu example</summary>

```json
{
  "native": {
    "type": "opentofu",
    "path": "./src/terraform",
    "version": "1.9.0"
  }
}
```

</details>

Verify your version configuration with a dry run:

```bash
bricks run . --dry --props-file properties.json
```

## Terraform vs OpenTofu

| Feature              | Terraform               | OpenTofu              |
| -------------------- | ----------------------- | --------------------- |
| **License**          | BSL 1.5.8+ (restricted) | MPL 2.0 (open source) |
| **Latest supported** | 1.5.7                   | Latest                |
| **Syntax**           | Identical               | Identical             |
| **Provider support** | Full                    | Full                  |

Terraform 1.5.7 and earlier use the MPL 2.0 license. Versions 1.5.8+ switched to the Business Source License (BSL), so Bluebricks caps Terraform at 1.5.7. OpenTofu is always MPL 2.0 with no restrictions.

**Migrating from Terraform to OpenTofu:** change `native.type` in your `bricks.json` from `"terraform"` to `"opentofu"`. No code changes required since the syntax is identical.

## How to create this artifact

The only requirement is a directory where you can run `terraform plan` (or `tofu plan`). If your root module works locally, Bluebricks can use it as-is. Bluebricks auto-discovers your variables and outputs, manages state, and wires everything into blueprints.

You can create a Terraform/OpenTofu artifact in two ways:

* **In the Bluebricks app** during [blueprint creation](/docs/orchestration/packages/blueprints-overview/creating-blueprints): select your repository and directory containing the root module, and Bluebricks generates the artifact automatically
* **Via CLI**: run `bricks blueprint publish` from your root module directory. See [Creating Artifacts](/docs/orchestration/packages/artifacts-overview/creating-artifacts) for the full workflow, or [Publish a Terraform Module](/docs/orchestration/packages/artifacts-overview/terraform-open-tofu/publish-terraform-module) for the detailed step-by-step CLI guide

> The sections below explain how Bluebricks maps your code to inputs, outputs, and operations under the hood. Everything here is optional reading. To get started, head to [Creating Blueprints](/docs/orchestration/packages/blueprints-overview/creating-blueprints).

## Inputs

### What becomes an input

Terraform/OpenTofu `variable` blocks are auto-discovered and mapped to `props` in `bricks.json`:

```hcl
variable "region" {
  type    = string
  default = "us-east-1"
}

variable "vpc_cidr" {
  type = string
}
```

### How inputs are delivered at runtime

Bluebricks writes all props and secrets to a single auto-vars file:

| Runtime file                  | Contents                                                                                               |
| ----------------------------- | ------------------------------------------------------------------------------------------------------ |
| **`0_bbx_props.auto.tfvars`** | All props and secrets. Mark secret variables `sensitive = true` in HCL to keep them out of CLI output. |

Secrets never appear in logs and Bluebricks wipes them from the runner after completion.

## Outputs

### What becomes an output

Terraform/OpenTofu `output` blocks are auto-discovered and mapped to `outs` in `bricks.json`:

```hcl
output "vpc_id" {
  value     = aws_vpc.main.id
  sensitive = false
}
```

### How outputs are captured

After a successful apply, Bluebricks runs `terraform output -json` to capture all output values. During planning, output keys appear as "known after apply" placeholders.

### Referencing outputs downstream

In a blueprint, reference a Terraform output from another package using `Data.network_stack.vpc_id`.

## Supported operations

| Operation         | What it does                                                                                  |
| ----------------- | --------------------------------------------------------------------------------------------- |
| **Plan**          | Initializes providers, generates a plan showing resource actions and placeholder outputs      |
| **Apply**         | Executes the plan, captures real outputs, and uploads the final state                         |
| **Plan Destroy**  | Generates a plan showing everything that will be removed                                      |
| **Apply Destroy** | Executes the destroy plan and deletes the remote state. The environment is marked *Destroyed* |

## Managed state

Bluebricks manages the Terraform backend automatically. State is locked during applies (only one apply at a time), encrypted at rest and in transit, and compared against live resources on every plan to surface drift in the UI. If `state_path` is set in `bricks.json`, the file is imported on the first apply and then removed.

## Best practices

* Mark secrets as `sensitive = true` in variables to suppress them in CLI output, logs, and state
* Run `terraform validate` locally before pushing an artifact
* Pin provider versions in `required_providers` to avoid unexpected upgrades

## See also

* [Publish a Terraform Module](/docs/orchestration/packages/artifacts-overview/terraform-open-tofu/publish-terraform-module): step-by-step CLI publishing workflow
* [Develop Terraform Locally](https://bluebricks.co/docs/help/guides/develop-terraform-locally): work with remote state locally (Help Center)
* [Migrate Terraform State to Bluebricks](https://bluebricks.co/docs/help/guides/migrate-terraform-state): import existing state (Help Center)


# Publish a Terraform Module

Convert an existing Terraform module into a Bluebricks package using the prepare and publish CLI workflow

## Overview

Convert your existing Terraform module into a Bluebricks package in two steps: prepare locally, then publish to your organization.

## Prerequisites

* Bricks CLI installed and authenticated (`bricks login`)
* Existing Terraform module with `.tf` files

## How to publish a Terraform module

{% stepper %}
{% step %}
**Prepare your module**

Navigate to your Terraform directory and run:

```bash
cd /path/to/your-terraform-module
bricks blueprint prepare --source . --iac-type terraform
```

This creates a `bricks.json` with auto-detected variables and outputs. Your original `.tf` files remain in place.
{% endstep %}

{% step %}
**Publish to your organization**

```bash
bricks blueprint publish
```

Your module is now available to your organization.
{% endstep %}
{% endstepper %}

## What each command does

**`bricks blueprint prepare`** generates a `bricks.json` in your current directory. No files are moved or copied, and no API calls are made. Your `.tf` files stay exactly where they are.

**`bricks blueprint publish`** uploads your package to Bluebricks. Variables and outputs are auto-discovered from your `.tf` files, external module references are resolved (if `--resolve-modules` is enabled), and the package is made available to your organization.

## Working with existing modules

### Local module references

If your Terraform uses local modules:

```hcl
module "vpc" {
  source = "../networking/vpc"
}

module "subnets" {
  source = "../networking/subnets"
}
```

**Bluebricks automatically handles this** with `--resolve-modules` (enabled by default):

```bash
bricks blueprint publish --resolve-modules
```

What happens:

1. Finds all modules referenced with `../`
2. Copies them to `bricks_modules/` directory
3. Updates references to point to `./bricks_modules/`
4. Includes everything in the published package

Your module becomes self-contained and portable.

### Disable module resolution

If you **don't** want to include external modules:

```bash
bricks blueprint publish --resolve-modules=false
```

Bluebricks warns you about external references but won't include them.

## Terraform version

**Default version:** 1.5.7

Specify a different version in `bricks.json`:

```json
{
  "native": {
    "type": "terraform",
    "path": ".",
    "version": "1.6.5"
  }
}
```

For the full version limits table and examples, see [version pinning](/docs/orchestration/packages/artifacts-overview/terraform-open-tofu#version-pinning).

## State management

Bluebricks automatically manages state using its built-in HTTP backend. Do not include `backend.tf` or backend configuration blocks in your Terraform code.

For details on managed state, locking, and encryption, see [Terraform/OpenTofu](/docs/orchestration/packages/artifacts-overview/terraform-open-tofu#managed-state-details).

To work locally with remote state for debugging or development, see [Develop Terraform Locally](https://bluebricks.co/docs/help/guides/develop-terraform-locally).

### Publishing with existing state

If you're migrating existing Terraform infrastructure, include your state file:

```bash
bricks blueprint publish --state
```

Requirements:

* Place `terraform.tfstate` in your Terraform directory
* Bluebricks packages it with your module
* State is stored securely in Bluebricks

## Variables and outputs mapping

Variables and outputs are auto-discovered during publish. Bluebricks parses your `variables.tf` and `outputs.tf`, then converts them to `props` and `outs` in `bricks.json`. See [Terraform/OpenTofu inputs and outputs](/docs/orchestration/packages/artifacts-overview/terraform-open-tofu#inputs) for the full mapping details and examples.

## Examples

<details>

<summary>Publishing a VPC module</summary>

```
vpc_module/
├── main.tf
├── variables.tf
├── outputs.tf
└── versions.tf
```

```bash
cd vpc_module
bricks blueprint prepare --source . --iac-type terraform
bricks blueprint publish
```

</details>

<details>

<summary>Publishing with local modules</summary>

```
my-infrastructure/
├── main.tf              # References ../common/networking
├── variables.tf
└── outputs.tf

../common/networking/
├── vpc.tf
├── subnets.tf
└── outputs.tf
```

```bash
cd my-infrastructure
bricks blueprint prepare --source . --iac-type terraform
bricks blueprint publish
```

Bluebricks automatically detects `../common/networking`, copies it to `bricks_modules/common/networking/`, updates your references, and packages everything together. Your published module is now self-contained.

</details>

<details>

<summary>Migrating existing infrastructure</summary>

```bash
cd production-vpc
terraform show  # Verify state exists

# Publish with state
bricks blueprint prepare --source . --iac-type terraform
bricks blueprint publish --state
```

Bluebricks stores your state securely, enables locking to prevent conflicts, and provides a full audit trail.

</details>

## Common options

<details>

<summary>Prepare options</summary>

```bash
bricks blueprint prepare \
  --source ./terraform \
  --iac-type terraform \
  --output ./my-package \
  --package-name my-vpc
```

* `--source`: Path to Terraform directory
* `--iac-type`: Must be `terraform`
* `--output`: Where to create package (default: current directory)
* `--package-name`: Custom package name (default: directory name)
* `--refactor`: Create `bricks.json` without moving files

</details>

<details>

<summary>Publish options</summary>

```bash
bricks blueprint publish \
  --src ./my-package \
  --resolve-modules=true \
  --state
```

* `--src`: Package directory (default: current directory)
* `--resolve-modules`: Include external modules (default: `true`)
* `--state`: Include terraform.tfstate file

</details>

## Generated package structure

<details>

<summary>After prepare</summary>

```
my-package/
├── bricks.json          # Package metadata
└── src/
    └── terraform/       # Your .tf files
        ├── main.tf
        ├── variables.tf
        ├── outputs.tf
        └── versions.tf
```

</details>

<details>

<summary>After publish with --resolve-modules</summary>

```
my-package/
├── bricks.json
└── src/
    └── terraform/
        ├── main.tf
        ├── variables.tf
        ├── outputs.tf
        ├── versions.tf
        └── bricks_modules/     # External modules copied here
            └── common/
                └── networking/
                    ├── vpc.tf
                    └── outputs.tf
```

</details>

## Best practices

* Test locally before publishing
* Use `--resolve-modules` for portability
* Include state with `--state` when migrating existing infrastructure
* Version your packages with semantic versioning

## See also

* [Develop Terraform Locally](https://bluebricks.co/docs/help/guides/develop-terraform-locally): download state config for local debugging
* [Terraform/OpenTofu](/docs/orchestration/packages/artifacts-overview/terraform-open-tofu): artifact reference and features overview
* [Creating Blueprints](/docs/orchestration/packages/blueprints-overview/creating-blueprints): compose artifacts into blueprints
* [Packages](/docs/orchestration/packages): artifact types and packaging concepts


# Helm

Helm reference: chart lifecycle, Kubernetes authentication, release tracking, and input/output

## Overview

Helm artifacts let you deploy and manage Kubernetes applications using standard Helm charts while leveraging Bluebricks' orchestration and environment automation. By packaging your Helm chart as an artifact, you can centralize configuration, apply collection-specific values, and streamline release operations across clusters.

<table><thead><tr><th width="219.7265625">Feature</th><th>Details</th></tr></thead><tbody><tr><td><strong>Kubernetes integration</strong></td><td>Deploy to any connected EKS, GKE, AKS, or on-prem cluster</td></tr><tr><td><strong>Chart management</strong></td><td>Support for local charts and remote/OCI chart dependencies</td></tr><tr><td><strong>Release lifecycle</strong></td><td>Install, upgrade, and uninstall operations with <code>--wait</code></td></tr><tr><td><strong>Values injection</strong></td><td>Props and secrets are merged into Helm values at runtime</td></tr></tbody></table>

For a complete guide to how inputs and outputs work across all IaC tools, see [Inputs & Outputs](/docs/orchestration/packages/inputs-and-outputs).

## Required files and directory structure

A Helm artifact requires a standard Helm chart structure in the directory specified by `native.path`:

```
my-helm-artifact/
├── bricks.json              # Artifact manifest
└── chart/                   # native.path points here
    ├── Chart.yaml           # Chart metadata (required)
    ├── values.yaml          # Default values
    ├── templates/           # Kubernetes manifest templates
    │   ├── deployment.yaml
    │   ├── service.yaml
    │   └── _helpers.tpl
    └── charts/              # Sub-chart dependencies (optional)
```

The `native.path` field in `bricks.json` must point to the directory containing `Chart.yaml`.

## bricks.json reference

<table><thead><tr><th width="92.49609375">Field</th><th width="112.31640625">Required</th><th>Description</th></tr></thead><tbody><tr><td><strong><code>type</code></strong></td><td>Yes</td><td><code>"helm"</code></td></tr><tr><td><strong><code>path</code></strong></td><td>Yes</td><td>Directory containing <code>Chart.yaml</code> and templates</td></tr></tbody></table>

## How to create this artifact

The only requirement is a directory with a valid Helm chart (`Chart.yaml`). If you can run `helm install` from it, Bluebricks can use it as-is. Bluebricks handles values injection, release management, and cluster authentication for you.

You can create a Helm artifact in two ways:

* **In the Bluebricks app** during [blueprint creation](/docs/orchestration/packages/blueprints-overview/creating-blueprints): select your repository and the directory containing `Chart.yaml`, and Bluebricks generates the artifact automatically
* **Via CLI**: use the `bricks blueprint prepare` workflow described below

{% hint style="info" %}
If you use umbrella charts (sub-chart dependencies), run `helm dependency build` before publishing via CLI.
{% endhint %}

### Create a Helm artifact via CLI

**Prerequisites:**

* Bluebricks CLI installed and authenticated (`bricks login`)
* An existing Helm chart with `Chart.yaml` and `values.yaml`

**Steps:**

1. **Navigate to your chart directory:**

   ```bash
   cd ~/my-helm-chart
   ```
2. **Run blueprint prepare:**

   ```bash
   # Option 1: In-place (keeps original files)
   bricks blueprint prepare --source . --iac-type helm

   # Option 2: With output directory (copies files to src/helm/)
   bricks blueprint prepare --source . --output ./dist --iac-type helm
   ```
3. **Publish the package:**

   ```bash
   bricks blueprint publish
   ```

**Example directory structure:**

Before:

```
my-helm-chart/
├── Chart.yaml
├── values.yaml
└── templates/
    ├── deployment.yaml
    └── service.yaml
```

After (with output directory):

```
my-helm-chart/
├── bricks.json          # Generated metadata
└── src/
    └── helm/            # Your files (copied)
        ├── Chart.yaml
        ├── values.yaml
        └── templates/
```

After (in-place, no output directory):

```
my-helm-chart/
├── bricks.json          # Generated metadata
├── Chart.yaml           # Original files remain
├── values.yaml
└── templates/
```

### Test locally

Verify your Helm package works correctly before publishing:

```bash
# Dry run (plan only)
bricks run . --dry

# With custom properties
bricks run . --dry --props-file properties.json
```

The dry run shows you exactly what Helm will deploy without making any changes to your cluster.

***

> The sections below explain how Bluebricks maps your code to inputs, outputs, and operations under the hood. Everything here is optional reading. To get started, head to [Creating Blueprints](/docs/orchestration/packages/blueprints-overview/creating-blueprints).

## Inputs

### What becomes an input

Keys defined in `values.yaml` and any additional configuration your chart needs become props in `bricks.json`. Unlike Terraform, Helm props are not auto-discovered from `values.yaml`; you declare them explicitly in `bricks.json`.

### How inputs are delivered at runtime

All props become Helm values; secrets are merged separately and never shown in diffs.

**Example mapping:**

For example, given props `replicas`, `image_tag`, and `nodeSelector`, the resulting Helm values are:

```yaml
replicas: 3
image:
  tag: v1.2.3
nodeSelector:
  tier: frontend
```

## Outputs

### What becomes an output

Helm artifacts do not auto-generate outputs from chart execution. You must define outputs manually in `bricks.json`.

{% hint style="info" %}
Auto-generated Helm outputs are coming soon.
{% endhint %}

### Referencing outputs downstream

If you define outputs in `bricks.json`, reference them in a blueprint the same way as any other package using `Data.helm_bdc.release_name`.

## Supported operations

<table><thead><tr><th width="149.66015625">Operation</th><th>What happens</th><th>Notes</th></tr></thead><tbody><tr><td><strong>Plan</strong></td><td>Dry-run, diffs rendered manifests against the live cluster, lists resources to create/update/delete</td><td>Orphaned live resources not yet surfaced in diff</td></tr><tr><td><strong>Apply</strong></td><td>Installs or upgrades the chart using <code>--wait</code></td><td>Waits for resources to be ready</td></tr><tr><td><strong>Plan Destroy</strong></td><td>Dry-run uninstall to preview all managed resources</td><td></td></tr><tr><td><strong>Apply Destroy</strong></td><td>Uninstalls the release and deletes all managed resources</td><td></td></tr></tbody></table>

## Release management

### Release naming

<table><thead><tr><th width="157.3125">Field</th><th width="198.74609375">Default</th><th>Override</th></tr></thead><tbody><tr><td><strong>Release name</strong></td><td><code>Chart.yaml</code> → <code>name</code></td><td><code>native.releaseName</code></td></tr><tr><td><strong>Namespace</strong></td><td><code>default</code></td><td><code>native.namespace</code> (created if absent)</td></tr></tbody></table>

{% hint style="info" %}
If multiple artifacts reuse the same chart, set a custom `releaseName` to avoid collisions.
{% endhint %}

### Plan caveats

* Orphaned resources (objects removed from the chart but still present in the cluster) **do not appear** in the diff yet; they will still be deleted on apply
* CRDs in the `crds/` directory are pre-installed before chart deployment. They appear in the plan diff. See [CRD Management](/docs/orchestration/packages/artifacts-overview/helm/helm-crd-management) for details

## Cluster integration

Bluebricks leverages cloud provider CLIs for Kubernetes authentication:

<table><thead><tr><th width="117.86328125">Provider</th><th>CLI Command</th></tr></thead><tbody><tr><td><strong>EKS</strong></td><td><code>aws eks update-kubeconfig --region region-code --name my-cluster</code></td></tr><tr><td><strong>GKE</strong></td><td><code>gcloud container clusters get-credentials CLUSTER_NAME --location=LOCATION</code></td></tr><tr><td><strong>AKS</strong></td><td><code>az aks get-credentials --resource-group RESOURCE_GROUP --name CLUSTER_NAME</code></td></tr><tr><td><strong>On-prem</strong></td><td>Service-account token in kubeconfig (if exists)</td></tr></tbody></table>

No kubeconfig needs to live inside the artifact.

## Umbrella charts

Manage sub-charts in `Chart.yaml`:

```yaml
dependencies:
  - name: postgresql
    version: "12.1.2"
    repository: "https://charts.bitnami.com/bitnami"
    condition: postgresql.enabled
  - name: redis
    version: "17.3.7"
    repository: "https://charts.bitnami.com/bitnami"
    condition: redis.enabled
```

Run `helm dependency build` before publishing when using umbrella charts.

## Best practices

* Parameterize every environment-specific setting
* Provide `values.schema.json` for validation
* Add liveness and readiness probes and resource limits
* Use consistent labels and annotations for observability
* Avoid hard-coding namespaces; rely on `Release.Namespace`

## See also

* [CRD Management](/docs/orchestration/packages/artifacts-overview/helm/helm-crd-management): automatic CRD handling for Helm charts
* [Creating Artifacts](/docs/orchestration/packages/artifacts-overview/creating-artifacts): general CLI publishing workflow
* [Creating Blueprints](/docs/orchestration/packages/blueprints-overview/creating-blueprints): compose artifacts into blueprints


# CRD Management

How Bluebricks automatically handles Custom Resource Definitions (CRDs) in Helm charts using server-side apply for reliable, consistent deployments

Bluebricks uses server-side apply to manage CRD installation automatically. This ensures CRDs are installed before your chart deploys, preventing common deployment failures and version conflicts.

## CRD support

**Automatic installation:**

* CRDs are automatically installed before chart deployment
* Uses server-side apply for reliable CRD management
* Handles CRD updates and versioning

**CRD sources:**

* `crds/` directory in your chart
* Chart dependencies with CRDs
* External CRD definitions

## CRD directory structure

```
my-helm-chart/
├── Chart.yaml
├── values.yaml
├── templates/
└── crds/                    # CRD definitions
    ├── custom-resource.yaml
    └── another-crd.yaml
```

## How CRD installation works

Bluebricks follows a safe, sequential process to handle CRDs:

1. **Pre-deployment:** Installs CRDs first to make them available
2. **Validation:** Validates CRD syntax and compatibility before proceeding
3. **Chart deployment:** Deploys your chart templates that reference the CRDs
4. **Post-deployment:** Verifies CRD status to confirm successful installation

This order prevents errors where templates try to use CRDs that don't exist yet.

## Best practices

1. **Place CRDs in `crds/` directory**
2. **Use proper CRD versions**
3. **Test CRD installation locally**
4. **Document CRD requirements**

## See also

* [Helm](/docs/orchestration/packages/artifacts-overview/helm): full Helm artifact reference
* [Packages overview](/docs/orchestration/packages): artifact types and packaging concepts
* [Creating Blueprints](/docs/orchestration/packages/blueprints-overview/creating-blueprints): compose artifacts into blueprints


# CloudFormation

CloudFormation reference: parameter mapping, outputs capture, and AWS authentication

## Overview

CloudFormation artifacts let you manage AWS infrastructure using native CloudFormation templates while taking advantage of Bluebricks' orchestration, collection management, and environment automation. You define AWS resources declaratively in JSON or YAML, then deploy and track those changes reliably across collections.

<figure><img src="/files/bqH2bh6bldFZ4eSskWFX" alt=""><figcaption></figcaption></figure>

<table><thead><tr><th width="164.9609375">Feature</th><th>Details</th></tr></thead><tbody><tr><td><strong>Template-driven</strong></td><td>Supports <code>bluebricks.json</code> or <code>bluebricks.yaml</code> templates</td></tr><tr><td><strong>Change-set plan</strong></td><td>Plan creates a Change Set that previews adds/updates/deletes without altering resources</td></tr><tr><td><strong>Stack apply</strong></td><td>Executes the Change Set, waits for stack completion, captures outputs</td></tr><tr><td><strong>Outputs capture</strong></td><td>Template Outputs become artifact outputs for downstream packages</td></tr><tr><td><strong>State-free</strong></td><td>CloudFormation stores state, so you don't need backend configuration</td></tr></tbody></table>

For a complete guide to how inputs and outputs work across all IaC tools, see [Inputs & Outputs](/docs/orchestration/packages/inputs-and-outputs).

## Required files and directory structure

A CloudFormation artifact requires a template file named `bluebricks.json` or `bluebricks.yaml`:

```
my-cfn-artifact/
├── bricks.json                    # Artifact manifest
└── template/
    └── bluebricks.json            # CloudFormation template (required name)
```

{% hint style="info" %}
The CloudFormation template **must** be named `bluebricks.json` or `bluebricks.yaml`. Other file names are not recognized.
{% endhint %}

The `native.path` field in `bricks.json` points to the **template file itself** (not the directory).

### Example template

A simple VPC template (`bluebricks.json`):

```json
{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Description": "VPC infrastructure",
  "Parameters": {
    "VpcCidr": {
      "Type": "String",
      "Default": "10.0.0.0/16",
      "Description": "CIDR block for the VPC"
    },
    "Environment": {
      "Type": "String",
      "Default": "development",
      "Description": "Environment name"
    }
  },
  "Resources": {
    "VPC": {
      "Type": "AWS::EC2::VPC",
      "Properties": {
        "CidrBlock": { "Ref": "VpcCidr" },
        "EnableDnsHostnames": true,
        "Tags": [
          {
            "Key": "Name",
            "Value": { "Fn::Sub": "${Environment}-vpc" }
          }
        ]
      }
    }
  },
  "Outputs": {
    "VpcId": {
      "Description": "ID of the VPC",
      "Value": { "Ref": "VPC" }
    }
  }
}
```

## bricks.json reference

<table><thead><tr><th width="134.40234375">Field</th><th width="113.8046875">Required</th><th>Description</th></tr></thead><tbody><tr><td><strong><code>type</code></strong></td><td>Yes</td><td><code>"cloudformation"</code></td></tr><tr><td><strong><code>path</code></strong></td><td>Yes</td><td>Path to the CloudFormation template file (must be <code>bluebricks.json</code> or <code>bluebricks.yaml</code>)</td></tr><tr><td><strong><code>stack_name</code></strong></td><td>No</td><td>Custom stack name. Defaults to a sanitized version of the artifact name.</td></tr></tbody></table>

### Example bricks.json

```json
{
  "name": "vpc-infrastructure",
  "version": "0.1.0",
  "description": "VPC infrastructure",
  "native": {
    "type": "cloudformation",
    "path": "./template/bluebricks.json"
  },
  "props": {
    "VpcCidr": {
      "type": "string",
      "default": "10.0.0.0/16",
      "description": "CIDR block for the VPC"
    },
    "Environment": {
      "type": "string",
      "default": "development",
      "description": "Environment name"
    },
    "cf_stack_name": {
      "type": "string",
      "description": "Optional name for the CloudFormation stack"
    }
  },
  "outs": {
    "VpcId": {
      "type": "string",
      "description": "ID of the VPC"
    }
  }
}
```

## How to create this artifact

The only requirement is a CloudFormation template named `bluebricks.json` or `bluebricks.yaml`. Point Bluebricks at your template and it handles parameter mapping, change-set workflows, and output capture for you.

You can create a CloudFormation artifact in two ways:

* **In the Bluebricks app** during [blueprint creation](/docs/orchestration/packages/blueprints-overview/creating-blueprints): select your repository and the directory containing your template, and Bluebricks generates the artifact automatically
* **Via CLI**: run `bricks blueprint publish` from the directory containing your template. See [Creating Artifacts](/docs/orchestration/packages/artifacts-overview/creating-artifacts) for the full workflow

You can also scaffold the `bricks.json` manifest automatically using the `prepare` command:

```bash
# In-place (keeps original files)
bricks blueprint prepare --source . --iac-type cloudformation

# With output directory (copies files to a separate folder)
bricks blueprint prepare --source . --output ./dist --iac-type cloudformation
```

The `prepare` command analyzes your template, extracts Parameters as props and Outputs as outs, and generates a `bricks.json` manifest.

### Test locally

Before publishing, verify the artifact works with a local dry run:

```bash
# Plan only (creates a Change Set without applying)
bricks run . --dry

# Apply to AWS
bricks run . --apply
```

***

> The sections below explain how Bluebricks maps your code to inputs, outputs, and operations under the hood. Everything here is optional reading. To get started, head to [Creating Blueprints](/docs/orchestration/packages/blueprints-overview/creating-blueprints).

## Inputs

### What becomes an input

CloudFormation `Parameters` in your template map to `props` in `bricks.json`:

```yaml
Parameters:
  VpcCidr:
    Type: String
    Default: "10.0.0.0/16"
  Environment:
    Type: String
```

### How inputs are delivered at runtime

Blueprint props and secrets map directly to CloudFormation Parameters:

<table><thead><tr><th width="254.9765625">Blueprint field</th><th>Parameter example</th></tr></thead><tbody><tr><td>Prop <code>Environment = "prod"</code></td><td><code>{ "ParameterKey": "Environment", "ParameterValue": "prod" }</code></td></tr><tr><td>Secret <code>DbPassword</code></td><td><code>{ "ParameterKey": "DbPassword", "ParameterValue": "" }</code></td></tr></tbody></table>

{% hint style="info" %}
Use `NoEcho: true` on sensitive parameters in your template to hide them from the AWS console.
{% endhint %}

## Outputs

### What becomes an output

CloudFormation template `Outputs` map to `outs` in `bricks.json`:

```yaml
Outputs:
  VpcId:
    Description: ID of the created VPC
    Value: !Ref VPC
  PrivateSubnetIds:
    Value: !Join [ ",", [ !Ref SubnetA, !Ref SubnetB ] ]
```

### How outputs are captured

After a successful apply, Bluebricks calls `DescribeStacks` to retrieve all stack outputs. During planning, output keys appear as placeholders until apply sets real values.

### Referencing outputs downstream

In a blueprint, reference a CloudFormation output from another package using `Data.network_stack.VpcId` or `Data.network_stack.PrivateSubnetIds`.

## Supported operations

CloudFormation artifacts use Change Sets for safe, predictable deployments:

<table><thead><tr><th width="149.19140625">Operation</th><th>What happens</th><th>Notes</th></tr></thead><tbody><tr><td><strong>Plan</strong></td><td>Creates a Change Set (<code>bbx-plan-</code>), waits for creation, then describes it to build a JSON plan</td><td>If the stack does not exist yet, the Change Set type is CREATE</td></tr><tr><td><strong>Apply</strong></td><td>Executes the pending Change Set (or creates the stack on first run) and waits for Complete status</td><td>If the stack is in a blocked state like UPDATE_ROLLBACK_FAILED, the deploy is halted</td></tr><tr><td><strong>Plan Destroy</strong></td><td>Creates a DELETE Change Set listing every resource that will be removed</td><td>Output list is empty</td></tr><tr><td><strong>Apply Destroy</strong></td><td>Deletes the stack and waits for DeleteComplete; outputs and state are cleared</td><td>Only one Change Set per deploy prevents concurrent modifications</td></tr></tbody></table>

## Best practices

* Keep templates focused: one stack per artifact; compose multiple stacks with exports if needed
* Use Parameters for environment-specific data; avoid hard-coding ARNs or IDs
* Tag resources in the template's `Tags` section for cost and compliance reporting
* Use `DeletionPolicy: Retain` on data resources if you don't want them deleted with the stack
* Mark sensitive outputs appropriately or avoid emitting secrets via `Outputs`


# Generic

Generic artifact reference: run any containerized task as a one-shot Kubernetes Job

## Overview

Generic artifacts extend Bluebricks orchestration beyond native IaC tools. They let you run any containerized task (scripts, CLIs, data migrations, automation flows) as a one-shot Kubernetes Job that executes your code, captures outputs, and cleans up.

<table><thead><tr><th width="289.23828125">Feature</th><th>Details</th></tr></thead><tbody><tr><td><strong>Bring-your-own Docker image</strong></td><td>Run any language or runtime that fits in a container</td></tr><tr><td><strong>No-code plan</strong></td><td>Planning always reports "no changes"</td></tr><tr><td><strong>Container I/O wiring</strong></td><td>Props and secrets injected as JSON files and environment variables</td></tr><tr><td><strong>Portable outputs</strong></td><td>Your script writes <code>outputs.json</code>; Bluebricks stores the values for downstream use</td></tr><tr><td><strong>Ephemeral execution</strong></td><td>Kubernetes Job, auto-cleaned after exit</td></tr></tbody></table>

Common use cases:

<table><thead><tr><th width="177.2109375">Use case</th><th width="248.5078125">Example image</th><th>Typical command</th></tr></thead><tbody><tr><td>Shell automation</td><td><code>alpine:latest</code></td><td><code>sh run.sh</code></td></tr><tr><td>Python script</td><td><code>python:3.12</code></td><td><code>python main.py</code></td></tr><tr><td>Ansible playbook</td><td><code>alpine/ansible</code></td><td><code>ansible-playbook site.yml</code></td></tr><tr><td>Database migration</td><td><code>python:3.11-slim</code></td><td><code>python migrate.py</code></td></tr><tr><td>API integration</td><td><code>curlimages/curl:latest</code></td><td><code>sh api_call.sh</code></td></tr></tbody></table>

For a complete guide to how inputs and outputs work across all IaC tools, see [Inputs & Outputs](/docs/orchestration/packages/inputs-and-outputs).

## Required files and directory structure

A Generic artifact requires user-defined scripts or executables in the directory specified by `native.path`:

```
my-generic-artifact/
├── bricks.json              # Artifact manifest
└── src/                     # native.path points here → mounted at /workspace
    ├── main.py              # Entry script
    ├── helper.py
    └── sidefiles/
        └── config.json
```

The `native.path` directory is mounted as `/workspace` inside the container at runtime. This is the working directory and the only writable mount point.

## bricks.json reference

<table><thead><tr><th width="119.76171875">Field</th><th width="131.4296875">Required</th><th>Description</th></tr></thead><tbody><tr><td><strong><code>image</code></strong></td><td>No</td><td>Docker image (default: <code>busybox:stable</code>). Must come from an <a href="/pages/16dshHm4pqgFl1dFSoCo#approved-container-registries">approved registry</a>.</td></tr><tr><td><strong><code>command</code></strong></td><td>No</td><td>Entry command array. Omit to use the image's default entrypoint.</td></tr><tr><td><strong><code>args</code></strong></td><td>No</td><td>Arguments array appended to command.</td></tr><tr><td><strong><code>path</code></strong></td><td>Yes</td><td>Folder in the artifact to mount as <code>/workspace</code>.</td></tr><tr><td><strong><code>env_vars</code></strong></td><td>No</td><td>Key-value map of environment variables injected into the container. See <a href="/pages/16dshHm4pqgFl1dFSoCo">Container Configuration</a> for details.</td></tr><tr><td><strong><code>lifecycle</code></strong></td><td>No</td><td>Per-stage overrides for plan, apply, and destroy. See <a href="/pages/5oHSLcqnff4FYuNNnHdn">Lifecycle and Execution</a>.</td></tr></tbody></table>

## Approved container registries

Only images from the registries below are accepted at publish time. Attempting to use an image from any other registry will be rejected.

| Registry                          | Description                  |
| --------------------------------- | ---------------------------- |
| `docker.io`                       | Docker Hub                   |
| `ghcr.io`                         | GitHub Container Registry    |
| `quay.io`                         | Red Hat Quay                 |
| `registry.gitlab.com`             | GitLab Container Registry    |
| `mcr.microsoft.com`               | Microsoft Container Registry |
| `gcr.io`                          | Google Container Registry    |
| `artifactregistry.googleapis.com` | Google Artifact Registry     |
| `ecr.aws`                         | AWS ECR                      |
| `*.us-east-1.amazonaws.com`       | AWS ECR us-east-1            |
| `*.eu-west-1.amazonaws.com`       | AWS ECR eu-west-1            |

{% hint style="warning" %}
Images from registries not on this list are rejected at publish time. See [Container Configuration](/docs/orchestration/packages/artifacts-overview/generic/container-config) for image selection best practices.
{% endhint %}

## How to create this artifact

The only requirement is a directory with your script or executable. Any language, any runtime: if it runs in a container, Bluebricks can orchestrate it. Bluebricks handles input injection, output capture, and container lifecycle for you.

You can create a Generic artifact in two ways:

* **In the Bluebricks app** during [blueprint creation](https://github.com/bluebricks-dev/Bluebricks-Documentation/blob/main/orchestration/packages/artifacts-overview/blueprints-overview/creating-blueprints.md): select your repository and the directory containing your code, and Bluebricks generates the artifact automatically
* **Via CLI**: run `bricks blueprint publish` from the directory containing your code. See [Creating Artifacts](https://github.com/bluebricks-dev/Bluebricks-Documentation/blob/main/orchestration/packages/artifacts-overview/generic/creating-artifacts.md) for the full workflow

***

> The sections below explain how Bluebricks maps your code to inputs, outputs, and operations under the hood. Everything here is optional reading. To get started, head to [Creating Blueprints](/docs/orchestration/packages/blueprints-overview/creating-blueprints).

## Inputs

### What becomes an input

Generic artifacts have no native input construct; all inputs are declared explicitly as `props` in `bricks.json`. There is no auto-discovery.

### How inputs are delivered at runtime

Bluebricks delivers inputs through three mechanisms simultaneously:

<table><thead><tr><th width="225.1796875">Mechanism</th><th>Location inside the container</th><th>Notes</th></tr></thead><tbody><tr><td><strong>Environment variables</strong></td><td><code>GREETING</code>, <code>REGION</code>, ... (one per prop/secret)</td><td>Secrets are also passed; avoid printing them</td></tr><tr><td><strong><code>/workspace/vars.json</code></strong></td><td>JSON file with all props</td><td>Non-secret configuration</td></tr><tr><td><strong><code>/workspace/secrets.json</code></strong></td><td>JSON file with all secrets</td><td>0600 permissions</td></tr></tbody></table>

### Reading inputs in code

{% tabs %}
{% tab title="Python" %}

```python
import json

with open('/workspace/vars.json', 'r') as f:
    vars = json.load(f)

database_host = vars['database_host']
```

{% endtab %}

{% tab title="Node.js" %}

```javascript
const fs = require('fs');

const vars = JSON.parse(fs.readFileSync('/workspace/vars.json', 'utf8'));
const databaseHost = vars.database_host;
```

{% endtab %}

{% tab title="Bash" %}

```bash
#!/bin/bash
VARS_FILE="/workspace/vars.json"

DATABASE_HOST=$(jq -r '.database_host' "$VARS_FILE")
DATABASE_NAME=$(jq -r '.database_name' "$VARS_FILE")
```

{% endtab %}
{% endtabs %}

### Auto-injected environment variables

Bluebricks injects the following environment variables into every Generic artifact execution, in addition to any `env_vars` you define:

| Variable        | Description                                                             |
| --------------- | ----------------------------------------------------------------------- |
| `BRICKS_ACTION` | Current deployment stage: `plan`, `apply`, `plan-destroy`, or `destroy` |
| `BRICKS_STATE`  | Base64-encoded JSON of previous deployment state (when state exists)    |
| `BRICKS_JOB_ID` | UUID identifying the current job execution                              |

See [Lifecycle and Execution](/docs/orchestration/packages/artifacts-overview/generic/lifecycle) for details on using these variables.

## Outputs

### What becomes an output

Your code defines the outputs by writing a JSON file. There is no native output construct; outputs are whatever your script produces.

### Output contract

Your code must create `/workspace/outputs.json` before exiting:

<table><thead><tr><th width="149.51171875">Rule</th><th>Detail</th></tr></thead><tbody><tr><td><strong>File name</strong></td><td><code>outputs.json</code> (exact)</td></tr><tr><td><strong>Location</strong></td><td><code>/workspace/outputs.json</code></td></tr><tr><td><strong>Size limit</strong></td><td>1 MiB maximum</td></tr><tr><td><strong>Format</strong></td><td>Flat JSON object (nested objects/arrays allowed)</td></tr><tr><td><strong>Auto-added</strong></td><td><code>job_id</code> is automatically included</td></tr></tbody></table>

### Writing outputs in code

{% tabs %}
{% tab title="Python" %}

```python
import json, pathlib

with open("/workspace/vars.json") as f:
    variables = json.load(f)

(pathlib.Path("/workspace") / "outputs.json").write_text(
  json.dumps({"message": "done", "records": 42}, indent=2)
)
```

{% endtab %}

{% tab title="Node.js" %}

```javascript
const fs = require('fs');

const outputs = {
    migration_status: 'success',
    rows_affected: 150,
    completion_time: new Date().toISOString()
};

fs.writeFileSync('/workspace/outputs.json', JSON.stringify(outputs, null, 2));
```

{% endtab %}

{% tab title="Bash" %}

```bash
#!/bin/bash
cat > /workspace/outputs.json <<EOF
{
  "migration_status": "success",
  "rows_affected": 150,
  "completion_time": "$(date -u +%Y-%m-%dT%H:%M:%SZ)"
}
EOF
```

{% endtab %}
{% endtabs %}

### Error handling pattern

Always write `outputs.json` even on failure, then exit with a non-zero code:

```python
import json, sys

try:
    result = perform_operation()
    with open('/workspace/outputs.json', 'w') as f:
        json.dump({'status': 'success', 'result': result}, f)
    sys.exit(0)
except Exception as e:
    with open('/workspace/outputs.json', 'w') as f:
        json.dump({'status': 'failed', 'error': str(e)}, f)
    sys.exit(1)
```

If the file is missing or invalid, the deployment fails.

### Referencing outputs downstream

In a blueprint, reference a Generic artifact's output the same way as any other package using `Data.hello_world.cidr_list`.

## Testing locally

You can test your Generic artifact locally with Docker before publishing:

```bash
# Create a test vars.json
cat > /tmp/vars.json << 'EOF'
{
  "database_host": "localhost",
  "database_name": "test_db"
}
EOF

# Run the container with mounted files
docker run --rm \
  -v /tmp/vars.json:/workspace/vars.json \
  -v $(pwd)/src:/workspace \
  python:3.11-slim \
  python /workspace/main.py

# Check the outputs
cat /workspace/outputs.json
```

## Supported operations

<table><thead><tr><th width="138.7109375">Operation</th><th>What happens</th><th>Notes</th></tr></thead><tbody><tr><td><strong>Plan</strong></td><td>Always returns an empty plan (<code>{}</code>) and lists outputs as "known after apply"</td><td>No resources are previewed; Generic is execution-only</td></tr><tr><td><strong>Apply</strong></td><td>Launches a Kubernetes Job with your image, mounts your artifact, runs the command, captures <code>outputs.json</code>, then cleans up</td><td>Job fails if exit code is not 0, timeout is hit, or <code>outputs.json</code> is invalid</td></tr><tr><td><strong>Plan Destroy</strong></td><td>Also always empty</td><td>Nothing to show; there are no persistent resources</td></tr><tr><td><strong>Apply Destroy</strong></td><td>No-op. Marks the deployment destroyed immediately.</td><td>Any cleanup must be coded into your script.</td></tr></tbody></table>

## Runtime environment

<table><thead><tr><th width="124.80078125">Resource</th><th>Value</th></tr></thead><tbody><tr><td><strong>CPU</strong></td><td>0.1 core guaranteed, burstable</td></tr><tr><td><strong>Memory</strong></td><td>256 MiB request, 256 MiB limit</td></tr><tr><td><strong>Timeout</strong></td><td>60 minutes (hard stop)</td></tr><tr><td><strong>User</strong></td><td>UID 1000 (non-root); no privilege escalation</td></tr><tr><td><strong>Filesystem</strong></td><td><code>/workspace</code> is read-write; remainder is read-only</td></tr></tbody></table>

Need more resources? Split the task, optimize code, or run it in your own environment and call back to Bluebricks via API.

## Python dependencies

If your Python script needs remote dependencies at runtime:

```sh
export HOME=${CWD} && pip install --user -r requirements.txt
```

This installs dependencies to the user's local Python package directory, avoiding system-wide permissions.

## Best practices

* Pick a minimal image with only what you need; smaller = faster pull
* Pin image digests (`python@sha256:...`) for reproducible builds
* Log verbosely to stdout; Bluebricks streams logs in real time
* Validate inputs early; exit 1 with a helpful message if invalid
* Keep execution under 5 minutes or design for resumable/partitioned runs
* Never echo secrets; they're in env vars, so accidental `print(os.environ)` will leak them to logs


# Container Configuration

Configure Docker containers for Generic artifacts: image selection, commands, environment variables, and approved registries

Configure how your Generic artifact's Docker container runs, including the image, entry command, arguments, and environment variables.

## Native configuration fields

All container settings live under the `native` key in `bricks.json`:

<table><thead><tr><th width="107.49609375">Field</th><th width="93.1953125">Type</th><th width="108.953125">Required</th><th width="152.1796875">Default</th><th>Description</th></tr></thead><tbody><tr><td><code>type</code></td><td>string</td><td>Yes</td><td>:</td><td>Must be <code>"generic"</code></td></tr><tr><td><code>path</code></td><td>string</td><td>Yes</td><td>:</td><td>Path to source files relative to package root. Mounted as <code>/workspace</code></td></tr><tr><td><code>image</code></td><td>string</td><td>No</td><td><code>busybox:stable</code></td><td>Docker image to use. Must come from an <a href="#approved-container-registries">approved registry</a></td></tr><tr><td><code>command</code></td><td>array</td><td>No</td><td>Image's CMD</td><td>Entry command array</td></tr><tr><td><code>args</code></td><td>array</td><td>No</td><td>:</td><td>Arguments appended to command</td></tr><tr><td><code>env_vars</code></td><td>object</td><td>No</td><td>:</td><td>Key-value map of environment variables injected into the container</td></tr></tbody></table>

## Configuration examples

{% tabs %}
{% tab title="Python" %}

```json
{
  "native": {
    "type": "generic",
    "path": "./src",
    "image": "python:3.11-slim",
    "command": ["/bin/bash", "-c"],
    "args": [
      "pip install -r /workspace/requirements.txt && python /workspace/scripts/main.py"
    ],
    "env_vars": {
      "PYTHONUNBUFFERED": "1",
      "PYTHONPATH": "/workspace"
    }
  }
}
```

{% endtab %}

{% tab title="Node.js" %}

```json
{
  "native": {
    "type": "generic",
    "path": "./src",
    "image": "node:18-alpine",
    "command": ["node"],
    "args": ["/workspace/app.js"],
    "env_vars": {
      "NODE_ENV": "production"
    }
  }
}
```

{% endtab %}

{% tab title="Bash" %}

```json
{
  "native": {
    "type": "generic",
    "path": "./src",
    "image": "alpine:latest",
    "command": ["/bin/sh"],
    "args": ["/workspace/scripts/deploy.sh"],
    "env_vars": {
      "DEBUG": "false"
    }
  }
}
```

{% endtab %}

{% tab title="Multi-step" %}

```json
{
  "native": {
    "type": "generic",
    "path": "./src",
    "image": "python:3.11-slim",
    "command": ["/bin/bash", "-c"],
    "args": [
      "python /workspace/step1.py && python /workspace/step2.py && python /workspace/step3.py"
    ]
  }
}
```

{% endtab %}
{% endtabs %}

## Approved container registries

Only images from the registries below are accepted at publish time:

<table><thead><tr><th width="304.3125">Registry</th><th>Description</th></tr></thead><tbody><tr><td><code>docker.io</code></td><td>Docker Hub</td></tr><tr><td><code>ghcr.io</code></td><td>GitHub Container Registry</td></tr><tr><td><code>quay.io</code></td><td>Red Hat Quay</td></tr><tr><td><code>registry.gitlab.com</code></td><td>GitLab Container Registry</td></tr><tr><td><code>mcr.microsoft.com</code></td><td>Microsoft Container Registry</td></tr><tr><td><code>gcr.io</code></td><td>Google Container Registry</td></tr><tr><td><code>artifactregistry.googleapis.com</code></td><td>Google Artifact Registry</td></tr><tr><td><code>ecr.aws</code></td><td>AWS ECR</td></tr><tr><td><code>*.us-east-1.amazonaws.com</code></td><td>AWS ECR us-east-1</td></tr><tr><td><code>*.eu-west-1.amazonaws.com</code></td><td>AWS ECR eu-west-1</td></tr></tbody></table>

{% hint style="warning" %}
Images from registries not on this list are rejected at publish time. If you need a registry added, contact Bluebricks support.
{% endhint %}

## Best practices

### Image selection

* **Pin versions**: use `python:3.11-slim` instead of `python:latest` for reproducible builds
* **Use minimal images**: Alpine-based images pull faster and have a smaller attack surface
* **Pin digests for production**: `python@sha256:...` guarantees byte-for-byte reproducibility
* **Choose official images**: prefer images from trusted publishers

### Command configuration

* **Be explicit**: always specify `command` and `args` rather than relying on image defaults
* **Use absolute paths**: reference `/workspace/` for all mounted files
* **Handle errors in scripts**: use `set -e` in Bash scripts so failures propagate

### Environment variables

* **Use `env_vars` for static config**: values known at publish time (log levels, feature flags)
* **Use props for dynamic config**: values that change per collection or deployment
* **Never put secrets in `env_vars`**: use Bluebricks secrets instead; they're injected separately at runtime


# Lifecycle and Execution

How Generic artifacts execute across deployment stages, with per-stage configuration and smart execution caching

Generic artifacts support per-stage configuration and smart execution caching. This page covers lifecycle overrides, auto-injected environment variables, and the rules that determine when your container runs or is skipped.

## Lifecycle configuration

The `lifecycle` key in `bricks.json` lets you override the default container configuration for individual deployment stages. Each stage (`plan`, `apply`, `destroy`) can specify its own image, command, args, env vars, or skip the stage entirely.

### When to use lifecycle config vs. environment variable detection

<table><thead><tr><th width="228.703125">Approach</th><th>Best for</th></tr></thead><tbody><tr><td><strong>Lifecycle config</strong></td><td>Different CLI arguments per stage, different images, skipping stages</td></tr><tr><td><strong><code>BRICKS_ACTION</code> detection</strong></td><td>A single script that branches on the current stage</td></tr></tbody></table>

### Basic structure

```json
{
  "native": {
    "type": "generic",
    "image": "custom/tool:1.0",
    "command": ["tool"],
    "args": ["default-action"],
    "lifecycle": {
      "plan": {
        "args": ["plan", "--detailed"]
      },
      "apply": {
        "args": ["apply", "--auto-approve"]
      },
      "destroy": {
        "args": ["destroy", "--force"]
      }
    }
  }
}
```

### Phase fields

Each phase (`plan`, `apply`, `destroy`) supports these fields:

<table><thead><tr><th width="103.76171875">Field</th><th width="97.78515625">Type</th><th>Description</th><th>Default</th></tr></thead><tbody><tr><td><code>image</code></td><td>string</td><td>Container image for this phase</td><td>Inherits from <code>native.image</code></td></tr><tr><td><code>command</code></td><td>array</td><td>Command to execute</td><td>Inherits from <code>native.command</code></td></tr><tr><td><code>args</code></td><td>array</td><td>Command arguments</td><td>Inherits from <code>native.args</code></td></tr><tr><td><code>env_vars</code></td><td>object</td><td>Environment variables (merged with native)</td><td>Inherits from <code>native.env_vars</code></td></tr><tr><td><code>skip</code></td><td>boolean</td><td>Skip execution for this phase (plan and destroy only)</td><td><code>false</code></td></tr></tbody></table>

Phase fields **override** the native configuration. If a field is not specified in the phase, it falls back to the native value. Environment variables are **merged**, with phase values taking precedence.

## Skipping stages

Set `skip: true` to prevent the container from executing during a stage. This is supported for `plan` and `destroy` only: `apply` cannot be skipped.

```json
{
  "native": {
    "type": "generic",
    "image": "python:3.11-slim",
    "command": ["python"],
    "args": ["healthcheck.py"],
    "lifecycle": {
      "destroy": {
        "skip": true
      }
    }
  }
}
```

Common use cases for skipping:

* **Skip destroy**: read-only scripts, health checks, monitoring tools
* **Skip plan**: operations that don't benefit from a preview phase

When a stage is skipped, the container does not execute, but the deployment stage still completes successfully.

## Environment variables

Bluebricks injects the following environment variables into every Generic artifact execution:

### BRICKS\_ACTION

The current deployment stage. Your script can use this to branch behavior without lifecycle config.

<table><thead><tr><th width="169.7890625">Value</th><th>Stage</th></tr></thead><tbody><tr><td><code>plan</code></td><td>Preview/planning phase</td></tr><tr><td><code>apply</code></td><td>Create or update operation</td></tr><tr><td><code>plan-destroy</code></td><td>Preview before destruction</td></tr><tr><td><code>destroy</code></td><td>Cleanup/removal operation</td></tr></tbody></table>

```python
import os

action = os.environ.get('BRICKS_ACTION')

if action == 'plan':
    validate_configuration()
elif action == 'apply':
    deploy_resources()
elif action in ('plan-destroy', 'destroy'):
    cleanup_resources()
```

### BRICKS\_STATE

Base64-encoded JSON containing the previous deployment's output. Available when state exists from a prior execution.

```python
import os, json, base64

state_b64 = os.environ.get('BRICKS_STATE')
if state_b64:
    state = json.loads(base64.b64decode(state_b64))
    previous_outputs = state.get('output', {})
    resource_id = previous_outputs.get('resource_id')
```

### BRICKS\_JOB\_ID

UUID identifying the current job execution. Useful for logging and correlation.

```python
job_id = os.environ.get('BRICKS_JOB_ID')
print(f"[{job_id}] Starting operation")
```

## Execution behavior

Generic artifacts use input tracking to decide when to run your container:

### Container executes when:

* **First deployment**: no previous outputs exist
* **Inputs change**: props or secrets are modified
* **Version changes**: the package version is bumped
* **Forced execution**: using techniques like the `now()` function

### Container skips when:

* **Inputs unchanged**: props and secrets are identical to the previous run
* **Outputs exist**: previous execution results are cached
* **Same version**: the package version hasn't changed

{% hint style="warning" %}
**Container code changes do NOT trigger re-execution.** If you fix a bug in your script but don't change any inputs or the package version, existing deployments won't pick up the fix. You must bump the version or change an input to force re-execution.
{% endhint %}

## Forcing execution

When you need a Generic artifact to run on every deployment regardless of input changes (e.g., health checks, cleanup scripts), use the `now()` function to ensure inputs always differ:

```json
{
  "props": {
    "api_endpoint": {
      "type": "string",
      "description": "API endpoint to check"
    },
    "force_run": {
      "type": "string",
      "description": "Timestamp to force execution",
      "value": "now().Format('2006-01-02T15:04:05Z')"
    }
  }
}
```

Because `force_run` changes on every deployment, the input hash always differs and the container always executes.

**Alternative:** bump the package version to force a single re-execution.

## Example: database migration

A complete example showing lifecycle configuration for a database migration tool:

```json
{
  "name": "db-migration",
  "version": "1.0.0",
  "native": {
    "type": "generic",
    "image": "migrate/migrate:latest",
    "command": ["migrate"],
    "args": [
      "-source", "file:///workspace/migrations",
      "-database", "postgres://...",
      "up"
    ],
    "lifecycle": {
      "plan": {
        "args": [
          "-source", "file:///workspace/migrations",
          "-database", "postgres://...",
          "version"
        ]
      },
      "destroy": {
        "args": [
          "-source", "file:///workspace/migrations",
          "-database", "postgres://...",
          "down"
        ]
      }
    }
  },
  "props": {
    "database_url": {
      "type": "string",
      "description": "PostgreSQL connection string"
    }
  }
}
```

<table><thead><tr><th width="129.11328125">Stage</th><th>What happens</th></tr></thead><tbody><tr><td><strong>Plan</strong></td><td>Checks the current migration version</td></tr><tr><td><strong>Apply</strong></td><td>Runs migrations up</td></tr><tr><td><strong>Destroy</strong></td><td>Runs migrations down</td></tr></tbody></table>


# Bicep

Bicep reference: deployment modes, parameter mapping, outputs capture, and Azure authentication

## Overview

Bicep artifacts let you manage Azure infrastructure using native Bicep templates while taking advantage of Bluebricks' orchestration, collection management, and environment automation. You describe Azure resources declaratively using the Bicep language, then deploy and track environments consistently across all collections through Bluebricks.

<table><thead><tr><th width="219.7265625">Feature</th><th>Details</th></tr></thead><tbody><tr><td><strong>Azure-native IaC</strong></td><td>Full Bicep language support including modules, loops, conditions, and decorators</td></tr><tr><td><strong>What-if plan</strong></td><td>Plan runs <code>az deployment what-if</code> to preview changes without altering resources</td></tr><tr><td><strong>Deployment modes</strong></td><td>Complete (default) or Incremental mode for resource lifecycle control</td></tr><tr><td><strong>Parameter injection</strong></td><td>Props and secrets are passed as deployment parameters at runtime</td></tr><tr><td><strong>No state backend to manage</strong></td><td>Bluebricks tracks deployment metadata internally; no user-managed state backend required</td></tr></tbody></table>

For a complete guide to how inputs and outputs work across all IaC tools, see [Inputs & Outputs](/docs/orchestration/packages/inputs-and-outputs).

## Required files and directory structure

A Bicep artifact requires at least one `.bicep` file in the directory specified by `native.path`:

```
my-bicep-artifact/
├── bricks.json              # Artifact manifest
├── main.bicep               # Main Bicep template
└── modules/                 # Bicep modules (optional)
    ├── storage.bicep
    └── networking.bicep
```

The `native.path` field in `bricks.json` points to the directory containing your Bicep files.

{% hint style="warning" %}
The Bicep entry file **must** be named `main.bicep`. Bluebricks uses this file as the entry point for parameter extraction, output capture, and runtime execution. Module files in subdirectories can use any name.
{% endhint %}

## bricks.json reference

<table><thead><tr><th width="92.49609375">Field</th><th width="112.31640625">Required</th><th>Description</th></tr></thead><tbody><tr><td><strong><code>type</code></strong></td><td>Yes</td><td><code>"bicep"</code></td></tr><tr><td><strong><code>path</code></strong></td><td>Yes</td><td>Directory containing the Bicep template files</td></tr><tr><td><strong><code>mode</code></strong></td><td>No</td><td>Deployment mode: <code>"Complete"</code> (default) or <code>"Incremental"</code>. See <a href="/pages/YyIxHkxz9xrh2xm2AamQ">Deployment Modes</a></td></tr></tbody></table>

### Example bricks.json

```json
{
  "name": "azure-storage",
  "version": "0.1.0",
  "description": "Azure storage account",
  "native": {
    "type": "bicep",
    "path": ".",
    "mode": "Complete"
  },
  "props": {
    "location": {
      "type": "string",
      "default": "East US",
      "description": "Azure region for resource group and resources"
    },
    "storageAccountName": {
      "type": "string",
      "description": "Storage account name"
    }
  },
  "outs": {
    "storageAccountId": {
      "type": "string",
      "description": "Storage account resource ID"
    }
  }
}
```

## How to create this artifact

The only requirement is a directory with valid Bicep files. If you can run `az deployment group create` from it, Bluebricks can use it as-is. Bluebricks handles parameter injection, deployment mode selection, and Azure authentication for you.

You can create a Bicep artifact in two ways:

* **In the Bluebricks app** during [blueprint creation](/docs/orchestration/packages/blueprints-overview/creating-blueprints): select your repository and the directory containing your `.bicep` files, and Bluebricks generates the artifact automatically
* **Via CLI**: use the `bricks blueprint prepare` workflow described below

### Create a Bicep artifact via CLI

**Prerequisites:**

* Bluebricks CLI installed and authenticated (`bricks login`)
* Existing Bicep code (`.bicep` files)
* Azure account with appropriate permissions

**Steps:**

1. **Navigate to your Bicep directory:**

   ```bash
   cd ~/my-bicep-project
   ```
2. **Run blueprint prepare:**

   ```bash
   # Option 1: In-place (keeps original files)
   bricks blueprint prepare --source . --iac-type bicep

   # Option 2: With output directory (copies files to src/bicep/)
   bricks blueprint prepare --source . --output ./dist --iac-type bicep
   ```
3. **Publish the package:**

   ```bash
   bricks blueprint publish
   ```

**Example directory structure:**

Before:

```
my-bicep-project/
├── main.bicep
├── modules/
│   ├── storage.bicep
│   └── networking.bicep
└── README.md
```

After (in-place, no output directory):

```
my-bicep-project/
├── bricks.json          # Generated metadata
├── main.bicep           # Original files remain
├── modules/
│   ├── storage.bicep
│   └── networking.bicep
└── README.md
```

After (with output directory `--output ./dist`):

```
my-bicep-project/
├── main.bicep               # Original files untouched
├── modules/
│   ├── storage.bicep
│   └── networking.bicep
├── README.md
└── dist/
    ├── bricks.json          # Generated metadata
    └── src/
        └── bicep/           # Your files (copied)
            ├── main.bicep
            └── modules/
                ├── storage.bicep
                └── networking.bicep
```

### Test locally

Verify your package works before publishing:

```bash
# Dependency tree only (skips Azure what-if)
bricks run . --dry

# With custom properties
bricks run . --dry --props-file properties.json
```

The `--dry` flag creates a dependency tree without running the Azure deployment plan. Omit `--dry` to run a full `what-if` preview against Azure.

***

> The sections below explain how Bluebricks maps your code to inputs, outputs, and operations under the hood. Everything here is optional reading. To get started, head to [Creating Blueprints](/docs/orchestration/packages/blueprints-overview/creating-blueprints).

## Inputs

### What becomes an input

Bicep `param` declarations map to `props` in `bricks.json`. During publishing, Bluebricks compiles your Bicep to an ARM template (via `bicep build --stdout`) and extracts parameters automatically.

{% hint style="info" %}
Bluebricks always injects two parameters: `location` (Azure region) and `resourceGroup` (resource group name). You do not need to declare these in `bricks.json`; they are added automatically.
{% endhint %}

**Type mapping:**

<table><thead><tr><th width="180">Bicep type</th><th width="180">bricks.json type</th><th>Notes</th></tr></thead><tbody><tr><td><code>string</code></td><td><code>string</code></td><td></td></tr><tr><td><code>int</code></td><td><code>number</code></td><td></td></tr><tr><td><code>bool</code></td><td><code>boolean</code></td><td></td></tr><tr><td><code>array</code></td><td><code>list</code></td><td></td></tr><tr><td><code>object</code></td><td><code>map</code></td><td></td></tr><tr><td><code>@secure() string</code></td><td><code>string</code> (sensitive)</td><td>Marked as sensitive; never shown in diffs</td></tr><tr><td><code>@secure() object</code></td><td><code>map</code> (sensitive)</td><td>Marked as sensitive; never shown in diffs. See known issue below</td></tr><tr><td>Typed arrays (<code>int[]</code>, <code>string[]</code>)</td><td><code>list</code></td><td>Compiled to generic <code>array</code> in ARM JSON; element type information is not preserved</td></tr></tbody></table>

{% hint style="warning" %}
Parameters with Bicep expressions as defaults (e.g., `[resourceGroup().location]`) are skipped during extraction because they cannot be represented as static values.
{% endhint %}

{% hint style="warning" %}
`@secure() object` parameters are not correctly mapped to `map` in all code paths. If you use `@secure() object`, verify the generated `bricks.json` has the correct type after publishing.
{% endhint %}

**Example:**

```bicep
@description('Azure region')
param location string = 'East US'

@description('Storage account name')
param storageAccountName string

@secure()
@description('Admin password')
param adminPassword string
```

Becomes in `bricks.json`:

```json
{
  "props": {
    "location": {
      "type": "string",
      "default": "East US",
      "description": "Azure region"
    },
    "storageAccountName": {
      "type": "string",
      "description": "Storage account name"
    },
    "adminPassword": {
      "type": "string",
      "sensitive": true,
      "description": "Admin password"
    }
  }
}
```

### How inputs are delivered at runtime

All props are passed as Azure deployment parameters. Secrets are merged separately and never shown in diffs.

## Outputs

### What becomes an output

Bicep `output` declarations map to `outs` in `bricks.json`:

```bicep
output storageAccountName string = storageAccount.name
output storageAccountId string = storageAccount.id
```

After a successful apply, Bluebricks captures deployment outputs from Azure. During planning, output keys appear as placeholders until apply sets real values.

### Referencing outputs downstream

In a blueprint, reference a Bicep output from another package using `Data.azure_storage.storageAccountId`.

## Supported operations

<table><thead><tr><th width="149.66015625">Operation</th><th>What happens</th><th>Notes</th></tr></thead><tbody><tr><td><strong>Plan</strong></td><td>Runs <code>az deployment what-if</code> to preview resource changes</td><td>Mode (Complete/Incremental) affects which changes are shown</td></tr><tr><td><strong>Apply</strong></td><td>Executes <code>az deployment create</code> with the configured mode</td><td>Waits for deployment completion</td></tr><tr><td><strong>Plan Destroy</strong></td><td>Previews resources that will be removed</td><td>Always uses Complete mode regardless of artifact configuration</td></tr><tr><td><strong>Apply Destroy</strong></td><td>Deploys an empty template in Complete mode to remove all resources in the resource group</td><td>Always uses Complete mode; also deletes the Azure deployment object and clears state</td></tr></tbody></table>

## Deployment scope

Bicep deployments in Bluebricks run at the **resource group** scope. Bluebricks automatically provisions a resource group for each environment and executes all deployments against it. Subscription-level, management-group-level, and tenant-level scopes are not supported.

{% hint style="info" %}
If your Bicep template uses `targetScope = 'subscription'`, refactor it to deploy at the resource group level before publishing to Bluebricks.
{% endhint %}

## Deployment modes

Bicep artifacts support two deployment modes that control resource lifecycle behavior: **Complete** (default) deletes resources not in the template, while **Incremental** preserves existing resources. Choose based on whether Bluebricks owns the entire resource group.

For a full comparison with decision matrix and configuration examples, see [Deployment Modes](/docs/orchestration/packages/artifacts-overview/bicep/bicep-deployment-modes).

## Best practices

* Keep the main template in `main.bicep` and use `modules/` for reusable components
* Provide sensible defaults and include `@description()` decorators on all parameters
* Use `@secure()` for sensitive parameters (passwords, connection strings)
* Only output values needed by downstream packages
* Use Complete mode with auto-generated resource groups for clean lifecycle management
* Use Incremental mode when deploying to shared or user-provided resource groups

## See also

* [Deployment Modes](/docs/orchestration/packages/artifacts-overview/bicep/bicep-deployment-modes): Complete vs Incremental mode for Bicep
* [Creating Artifacts](/docs/orchestration/packages/artifacts-overview/creating-artifacts): general CLI publishing workflow
* [Creating Blueprints](/docs/orchestration/packages/blueprints-overview/creating-blueprints): compose artifacts into blueprints


# Deployment Modes

Choose between Complete and Incremental deployment modes for Bicep artifacts based on resource group ownership

When deploying Bicep templates through Bluebricks, you can choose between two deployment modes: **Complete** and **Incremental**. Each mode has different behavior for resource lifecycle management.

## Complete mode (default)

### How it works

* Creates or updates resources defined in the template
* **Deletes any resources in the resource group that are not in the template**
* Provides full lifecycle management (create, update, destroy)

### When to use Complete mode

**Standard Bluebricks deployments:**

* Bluebricks auto-generates a unique resource group per deployment (e.g., `rg-myapp-a1b2c`)
* The blueprint owns the entire resource group
* Safe cleanup on destroy operations
* Full control over all resources in the scope

**Benefits:**

* Clean destroy behavior removes all resources when the blueprint is uninstalled
* Prevents orphaned resources
* Simplifies cost management

### Example configuration

```json
{
  "name": "azure-vm",
  "native": {
    "type": "bicep",
    "path": ".",
    "mode": "Complete"
  },
  "props": {
    "location": {"type": "string"}
  }
}
```

Bluebricks creates a dedicated resource group, deploys resources, and can safely clean up everything on uninstall.

## Incremental mode

### How it works

* Creates or updates resources defined in the template
* **Never deletes resources** (even if removed from template)
* Resources remain in Azure when removed from the Bicep template
* Requires manual cleanup for decommissioned resources

### When to use Incremental mode

**Shared resource group scenarios:**

* Multiple teams or blueprints deploy to the same resource group
* Need to preserve existing resources not managed by this blueprint
* Adding resources to existing infrastructure

**User-provided resource groups:**

* User specifies an existing resource group name
* Resource group contains resources from other sources
* Cannot take full ownership of the resource group

### Example configuration

```json
{
  "name": "add-vm-to-existing-rg",
  "native": {
    "type": "bicep",
    "path": ".",
    "mode": "Incremental"
  },
  "props": {
    "resourceGroup": {"type": "string", "required": true},
    "location": {"type": "string"}
  }
}
```

Deploys to an existing resource group without affecting other resources. Manual cleanup required on uninstall.

## Decision matrix

Choose the right deployment mode based on your scenario:

| Scenario                       | Mode        | Resource group strategy          |
| ------------------------------ | ----------- | -------------------------------- |
| Standard Bluebricks deployment | Complete    | Auto-generated                   |
| User-provided shared RG        | Incremental | User-provided                    |
| User-provided RG (sole owner)  | Complete    | User-provided (use with caution) |
| Multiple teams, same RG        | Incremental | User-provided                    |

## Resource group management

### Complete mode with auto-generated resource groups

**Configuration:**

* Do not provide a `resourceGroup` parameter
* Bluebricks generates a unique RG name based on the deployment
* Full lifecycle management enabled

**Workflow:**

1. User deploys blueprint
2. Bluebricks creates `rg-<blueprint>-<hash>`
3. Resources deployed to the dedicated RG
4. On uninstall: all resources cleaned up automatically

### Incremental mode with user-provided resource groups

**Configuration:**

* Provide `resourceGroup` parameter as a required property
* User specifies an existing RG name during deployment
* Manual cleanup process required

**Workflow:**

1. User deploys blueprint and specifies an existing RG
2. Resources added to the specified RG
3. Other resources in the RG remain untouched
4. On uninstall: resources remain, manual cleanup needed

## Important considerations

### Complete mode risks

When a user provides an existing resource group name and Complete mode is active:

* All resources in that RG not defined in the template will be deleted
* This includes resources from other teams, manual deployments, or other blueprints

{% hint style="danger" %}
Use Incremental mode when deploying to user-provided resource groups. Reserve Complete mode for Bluebricks-managed (auto-generated) resource groups.
{% endhint %}

### Incremental mode trade-offs

**Orphaned resources:**

* Resources removed from the template remain in Azure
* Increases cost over time if not manually cleaned
* Requires a decommission process

**Cost management:**

* Bluebricks calculates cost based on blueprint definitions
* Orphaned resources are not reflected in Bluebricks cost tracking
* Manual reconciliation required

## Referencing external resources

Both modes support referencing resources from other resource groups without managing them.

### Example: VM with existing VNet

```bicep
param virtualNetworkResourceGroup string
param virtualNetworkName string
param subnetName string

var subnetRef = resourceId(
  virtualNetworkResourceGroup,
  'Microsoft.Network/virtualNetworks/subnets',
  virtualNetworkName,
  subnetName
)

resource nic 'Microsoft.Network/networkInterfaces@2023-06-01' = {
  name: 'myNic'
  properties: {
    ipConfigurations: [{
      properties: {
        subnet: { id: subnetRef }
      }
    }]
  }
}
```

The VNet exists in `virtualNetworkResourceGroup`, but the NIC is created in the deployment's resource group. Complete mode only affects resources in the deployment's resource group.

## Cost management

### Complete mode

* Bluebricks tracks all resources in the deployment
* Cost calculation accurate
* Uninstall frees up environment budget immediately

### Incremental mode

* Bluebricks tracks resources at deployment time
* Orphaned resources not reflected in cost tracking
* Manual reconciliation required for accurate costs
* Budget freed only after manual resource cleanup

## See also

* [Bicep](/docs/orchestration/packages/artifacts-overview/bicep): artifact overview, parameter mapping, and CLI workflow
* [Packages](/docs/orchestration/packages): artifact types and packaging concepts


# .bricksignore

Exclude large or unnecessary files from published packages using a .bricksignore file, similar to .gitignore pattern format.

Before publishing a package to the Bluebricks repository, it's suggested that large files that don't directly support the package's functionality be excluded.

In addition, bricks CLI will automatically exclude runtime files and directories such as .terraform to ensure lightweight blueprints, easing the automation workflow.

## `.bricksignore`

The bricks CLI uses `.bricksignore` file, that specifies intentionally untracked files to ignore.

The file should be located in the root folder of a blueprint, next to [bricks.json](broken://pages/WT8nZ8bvssk2A9FFnomC).

The file content is similar to the `.gitignore` pattern format, which is detailed in the [gitignore documentation article on the Git docs website](https://git-scm.com/docs/gitignore/en).


# Inputs & Outputs

How inputs and outputs define the interface of every package in Bluebricks

Every package in Bluebricks has an interface defined by **inputs** and **outputs**. Inputs are the values a package needs to run: a region, a CIDR block, a cluster name, a database password. Outputs are the values a package produces after execution: a VPC ID, an endpoint URL, a connection string.

This interface makes packages composable. One package's output can feed into another package's input, and Bluebricks handles the wiring, ordering, and execution automatically.

This page explains how inputs and outputs work across all layers of Bluebricks, from native IaC code to runtime environments.

## The data flow model

Inputs and outputs flow through four layers:

**Layer 1: Native IaC code** is the infrastructure code you write: Terraform variables, Helm values, CloudFormation parameters, or scripts. This is where inputs and outputs originate.

**Layer 2: Artifact** is the `bricks.json` manifest. Its `props` and `outs` fields define the package's external interface. Bluebricks auto-discovers these from your native code when you publish.

**Layer 3: Blueprint** wires packages together. It connects outputs from one package to inputs of another, passes blueprint-level properties down to packages, and references secrets.

**Layer 4: Environment + Collection** is where Bluebricks resolves values at runtime. Collection properties, secrets, context references, output references, and deployer overrides supply the concrete values.

## Inputs

An input is any value a package needs to execute. In `bricks.json`, inputs are declared in the `props` object.

### How native code maps to inputs

Each IaC tool defines inputs differently at the native level. Bluebricks maps them all to the same `props` interface:

<table><thead><tr><th width="187.41015625">IaC Tool</th><th width="236.94921875">Native input construct</th><th width="320.06640625">Example</th></tr></thead><tbody><tr><td><strong>Terraform/OpenTofu</strong></td><td><code>variable</code> blocks in <code>.tf</code> files</td><td><code>variable "region" { type = string }</code></td></tr><tr><td><strong>Helm</strong></td><td>Keys in <code>values.yaml</code></td><td><code>replicaCount: 1</code></td></tr><tr><td><strong>CloudFormation</strong></td><td><code>Parameters</code> section in the template</td><td><code>Parameters: VpcCidr: Type: String</code></td></tr><tr><td><strong>Generic</strong></td><td>No native construct; props defined in <code>bricks.json</code> only</td><td>N/A</td></tr><tr><td><strong>Bicep</strong></td><td><code>param</code> declarations</td><td><code>param location string</code></td></tr></tbody></table>

When you publish an artifact, Bluebricks reads your native code and auto-populates the `props` section in `bricks.json`.

### How inputs get their values

Inside a blueprint, each package input can receive its value from five sources:

#### 1. Hardcoded value

A fixed value set directly in the blueprint definition:

```yaml
# UI / YAML
props:
  instance_type: t3.medium
```

#### 2. Blueprint-level input

A value passed down from the blueprint's own inputs:

```yaml
# UI / YAML
props:
  region: inputs.region
```

#### 3. Another package's output

A value produced by a sibling package. This creates a dependency in the execution graph:

```yaml
# UI / YAML
props:
  vpc_id: data.network_stack.vpc_id
```

#### 4. Secret

A sensitive value stored in the target collection's secret store:

```yaml
# UI / YAML
props:
  db_password: secrets.db_password
```

#### 5. Collection property or context reference

Values that come from the collection or environment at runtime:

* **Collection properties**: matched by key name. When a blueprint input key matches a collection property name, Bluebricks injects the collection's value automatically
* **Context references**: dynamic placeholders like `${{bricks.collection.slug}}` or `${{bricks.environment.slug}}` that resolve at runtime

See [Properties](/docs/orchestration/collections/properties), [Secrets](/docs/orchestration/collections/secrets), and [Using Context References](https://github.com/bluebricks-dev/Bluebricks-Documentation/blob/main/orchestration/deployments/using-context-references.md).

### How inputs are delivered at runtime

Each IaC tool receives inputs through a different mechanism:

<table><thead><tr><th width="186.4765625">IaC Tool</th><th width="223.1171875">Delivery mechanism</th><th>Details</th></tr></thead><tbody><tr><td><strong>Terraform/OpenTofu</strong></td><td><code>0_bbx_props.auto.tfvars</code></td><td>All props and secrets written to a single auto-vars file. Mark secrets <code>sensitive = true</code> in HCL.</td></tr><tr><td><strong>Helm</strong></td><td>Merged into Helm values</td><td>Props become Helm values; secrets are merged separately and never shown in diffs.</td></tr><tr><td><strong>CloudFormation</strong></td><td>CloudFormation Parameters</td><td>Each prop/secret becomes a <code>ParameterKey</code>/<code>ParameterValue</code> pair. Use <code>NoEcho: true</code> for secrets.</td></tr><tr><td><strong>Generic</strong></td><td>JSON files + environment variables</td><td>Props in <code>/workspace/vars.json</code>. Secrets in <code>/workspace/secrets.json</code>. Both also set as env vars.</td></tr></tbody></table>

## Outputs

An output is a value that a package produces after execution. In `bricks.json`, outputs are declared in the `outs` object.

### How native code maps to outputs

<table><thead><tr><th width="190.2734375">IaC Tool</th><th>Native output construct</th><th>How Bluebricks captures outputs</th></tr></thead><tbody><tr><td><strong>Terraform/OpenTofu</strong></td><td><code>output</code> blocks in <code>.tf</code> files</td><td><code>terraform output -json</code> after apply</td></tr><tr><td><strong>Helm</strong></td><td>No auto-generated outputs (coming soon)</td><td>Manually defined in <code>bricks.json</code></td></tr><tr><td><strong>CloudFormation</strong></td><td><code>Outputs</code> section in the template</td><td><code>DescribeStacks</code> API after apply</td></tr><tr><td><strong>Generic</strong></td><td><code>/workspace/outputs.json</code> written by your script</td><td>File parsed after container exits</td></tr></tbody></table>

### Referencing outputs downstream

Once a package produces outputs, other packages in the same blueprint can reference them using `Data` references:

```yaml
# UI / YAML syntax
vpc_id: data.network_stack.vpc_id
```

The reference format is:

```
Data.<package_id>.<output_key>
  │       │            │
  │       │            └── The output name from the source package's outs
  │       └────────────── The package ID within the blueprint
  └────────────────────── The Data object (runtime output store)
```

During planning, output values appear as "known after apply" placeholders. After apply, Bluebricks captures and stores the real values.

### Cross-environment output references

You can also reference outputs across environments. If a foundational environment (e.g., a shared VPC) produces outputs, dependent environments can consume them. See [Using Output References](https://github.com/bluebricks-dev/Bluebricks-Documentation/blob/main/orchestration/deployments/using-outputs-references.md).

## Secrets

Secrets are inputs that carry sensitive data: API keys, passwords, tokens. They behave like regular inputs but with additional protections:

* **Stored in the collection's secret store**, encrypted at rest
* **Never shown in logs, diffs, or UI fields**
* **Injected only at runtime** within the secure execution context
* **Wiped from the runner** after execution completes

In a blueprint, you reference secrets using the `Secrets` keyword:

```yaml
# UI / YAML
db_password: secrets.db_password
```

Each IaC tool delivers secrets through a different mechanism:

<table><thead><tr><th width="185.31640625">IaC Tool</th><th>How secrets are delivered</th><th>Best practice</th></tr></thead><tbody><tr><td><strong>Terraform/OpenTofu</strong></td><td>Included in <code>0_bbx_props.auto.tfvars</code></td><td>Mark variables <code>sensitive = true</code> in HCL</td></tr><tr><td><strong>Helm</strong></td><td>Merged into values separately from props</td><td>Never shown in rendered diffs</td></tr><tr><td><strong>CloudFormation</strong></td><td>Passed as Parameters</td><td>Use <code>NoEcho: true</code> in template</td></tr><tr><td><strong>Generic</strong></td><td>Written to <code>/workspace/secrets.json</code> (0600 permissions) + set as env vars</td><td>Never <code>print(os.environ)</code></td></tr></tbody></table>

See [Secrets](/docs/orchestration/collections/secrets) for how to create and manage secrets at the collection level.

## Package-to-package wiring

When one package's input references another package's output via a `Data` reference, Bluebricks creates an implicit dependency between them. These dependencies form a directed acyclic graph (DAG) that determines execution order.

{% @mermaid/diagram content="flowchart LR
VPC\["<b>VPC</b><br/>outs: vpc\_id"] -- "Data ref" --> Subnet\["<b>Subnet</b><br/>outs: subnet\_id"] -- "Data ref" --> App\["<b>App Server</b>"]" %}

In this example:

* **Subnet** depends on **VPC** because its `vpc_id` input references `Data.vpc.vpc_id`
* **App Server** depends on **Subnet** because it references `Data.subnet.subnet_id`

Bluebricks resolves this graph at plan time and executes packages in the correct order: parallel where there are no dependencies, sequential where one package needs another's output.

The `Data` reference is an [expr](https://expr-lang.org/) expression, so you can manipulate values. For example, select the first subnet from a list with `data.vpc.private_subnets[0]`, or use a fallback with `data.vpc.vpc_id ?? inputs.fallback_vpc_id`.

## Syntax quick reference

Bluebricks uses two equivalent syntaxes depending on context:

<table><thead><tr><th width="222.46875">Concept</th><th>bricks.json syntax</th><th>UI / YAML syntax</th></tr></thead><tbody><tr><td>Blueprint-level input</td><td><code>Props.region</code></td><td><code>inputs.region</code></td></tr><tr><td>Package output reference</td><td><code>Data.pkg_id.output_key</code></td><td><code>data.pkg_id.output_key</code></td></tr><tr><td>Secret reference</td><td><code>Secrets.db_password</code></td><td><code>secrets.db_password</code></td></tr><tr><td>Hardcoded string</td><td><code>"'us-east-1'"</code></td><td><code>us-east-1</code></td></tr><tr><td>Hardcoded number</td><td><code>14</code></td><td><code>14</code></td></tr></tbody></table>

Both syntaxes are [expr](https://expr-lang.org/) expressions. The capitalized form (`Props`, `Data`, `Secrets`) appears in `bricks.json`. The lowercase form (`inputs`, `data`, `secrets`) appears in the UI and YAML configurations.

## End-to-end example

This example shows a blueprint with two packages: a Terraform VPC and a Helm application. The VPC output flows into the Helm chart input, and secrets are pulled from the collection.

**Blueprint YAML (UI-generated):**

```yaml
name: webapp_stack
version: 1.0.0
description: Deploys networking and a web application

inputs:
  region:
    type: string
    allowed_values:
      - us-east-1
      - eu-west-1
  cluster_name:
    type: string

packages:
  - name: vpc
    version: 2.1.0
    props:
      region: inputs.region
      cidr_block: 10.0.0.0/16

  - name: webapp
    version: 1.3.0
    props:
      cluster_name: inputs.cluster_name
      vpc_id: data.vpc.vpc_id
      subnet_ids: data.vpc.private_subnet_ids
      db_password: secrets.db_password

outputs:
  vpc_id:
    value: data.vpc.vpc_id
  app_endpoint:
    value: data.webapp.endpoint
```

**What happens at runtime:**

1. Bluebricks resolves the DAG: `vpc` has no dependencies, `webapp` depends on `vpc`
2. The `vpc` package runs first. Inputs `region` and `cidr_block` are delivered via `0_bbx_props.auto.tfvars`.
3. After `vpc` completes, Bluebricks captures its outputs (`vpc_id`, `private_subnet_ids`) via `terraform output -json`.
4. The `webapp` package runs next. Its inputs include the VPC outputs (resolved from `Data.vpc.*`) and the secret `db_password` (resolved from the collection's secret store).
5. The blueprint's outputs are populated and available to dependent environments.


# Environments

An environment is the workflow that provisions, updates, and destroys infrastructure by executing a blueprint against a target collection

A Bluebricks **environment** provides a consistent, controlled, and repeatable way to execute a [blueprint](/docs/orchestration/packages/blueprints-overview) against a specific [collection](/docs/orchestration/collections). An environment represents the ongoing workflow responsible for provisioning, updating, and destroying all infrastructure defined by the blueprint, across every package, artifact, and dependency it contains.

{% hint style="success" %}
**Try it with the agent.** Deploy, update, and govern environments through conversation with built-in approval flows. See [Agent Overview](/docs/agent/agents-overview).
{% endhint %}

Once created, an environment serves as the stable interface for managing the lifecycle of your infrastructure in that collection. It centralizes configuration, tracks every change, and ensures that updates are performed safely and predictably, whether triggered manually, through CI/CD, or [automatically from Git](/docs/orchestration/environments/gitops-environments).

<figure><img src="/files/OSRjYJt2qz2AJzBbYI59" alt=""><figcaption></figcaption></figure>

## How environments work

When you create an environment [run](/docs/orchestration/runs), Bluebricks evaluates the blueprint and all of its child [packages](/docs/orchestration/packages) to produce a **unified execution plan**. This plan captures every expected change across all layers of infrastructure, allowing you to:

* Preview changes before applying them
* Understand the full impact of updates
* Maintain an auditable history of every modification

Each execution of an environment creates a [**run**](/docs/orchestration/runs), which encapsulates the plan, logs, state updates, and resulting outputs. Runs are fully versioned and traceable, enabling teams to understand how infrastructure evolves over time and why each change was made.

## What an environment contains

An environment bundles configuration, execution history, and lifecycle controls into a single manageable unit:

* **Blueprint binding**: the specific blueprint (and version) that defines the infrastructure to provision
* **Collection target**: the collection that determines where resources are created and which policies, variables, and secrets apply
* **Run history**: a full audit trail of every plan, apply, and destroy run, including logs, diffs, inputs, and outputs
* **Lifecycle controls**: [drift detection](/docs/orchestration/environments/drift-detection) schedules, [TTL](/docs/orchestration/environments/environment-ttl) rules, and [archiving](/docs/orchestration/environments/archiving-environments) state that govern how the environment behaves over time

## GitOps environments

You can connect an environment directly to a Git repository so that every push triggers a run and every pull request gets a plan. Bluebricks registers a webhook through the GitHub App and handles the full cycle: publishing an updated blueprint from source, triggering the run, and posting the plan back to the PR as a GitHub Check Run.

For setup instructions, auto-trigger rules, and limitations, see [GitOps Environments](/docs/orchestration/environments/gitops-environments).

## The environment detail page

When you review an environment, the detail page organizes everything into four tabs: **Overview**, **Drift detection**, **States**, and **Environment TTL**.

<figure><picture><source srcset="/files/KfHPP1pMvzr2eVexB6xh" media="(prefers-color-scheme: dark)"><img src="/files/hQjK8OGQz6584hbgse6q" alt=""></picture><figcaption></figcaption></figure>

### Overview tab

The Overview tab is the default view. It shows general information about the environment and a complete run history.

<details>

<summary><strong>General info</strong> displays at the top of the page</summary>

* **Collection**: the target collection with its cloud provider badge
* **Blueprint**: the installed blueprint name, version, and a badge if a newer version is available
* **Status**: the current environment status with a drift indicator
* **Current cost**: the estimated cost of provisioned resources (or "n/a" if unavailable)

</details>

<details>

<summary><strong>Run history</strong> lists every run for the environment in a table</summary>

You can filter by type, stage, or who initiated the run. Each row shows:

* **Blueprint and version**: which blueprint version the run used
* **Type**: Install, Uninstall, Plan only, or Drift detection
* **Cost change**: the cost before and after the run
* **Actions**: a summary of planned and actual resource changes
* **Stage**: the current run stage with a timestamp
* **Participants**: avatars for the creator and reviewer
* **Git source**: the linked PR, branch, or commit (if triggered from Git)

From each row, you can review the plan, trigger a new run, [promote](/docs/orchestration/runs/promoting-environments) to another collection, or delete the run.

</details>

### Drift detection tab

The Drift detection tab lets you enable automatic drift detection and view drift history. When enabled, Bluebricks runs a daily plan-only check at 00:00 UTC to compare your deployed infrastructure against the blueprint definition. You can also enable auto-remediation to automatically correct any detected drift.

For setup instructions and details on how drift detection works, see [Drift Detection](/docs/orchestration/environments/drift-detection).

### States tab

The States tab lists all infrastructure state files managed within the environment. For each state, you can see the associated package, version, and who last updated it. Actions include downloading, viewing (with version history), or uploading a state file.

For details on state ownership models, see [State Management and History](/docs/orchestration/runs/state-management-and-history).

### Environment TTL tab

The Environment TTL tab lets you schedule automatic uninstalls on a daily or weekly cadence. This is useful for ephemeral environments (dev, staging, sandboxes) where you want to avoid accumulating unused infrastructure.

For setup instructions and scheduling options, see [Time to Live (TTL)](/docs/orchestration/environments/environment-ttl).

## Best practices

* **Use descriptive slugs** (e.g., `networking_prod`, `data_staging`) so environments are easy to identify in lists and automation
* **Review the unified plan before approving** to understand the full impact of changes across all packages
* **Enable drift detection** on long-lived environments to catch out-of-band changes early
* **Set a TTL on ephemeral environments** (e.g., feature branches, demos) to avoid unused infrastructure accumulating cost
* **Archive environments you no longer need** instead of leaving them in the active list. See [Archiving Environments](/docs/orchestration/environments/archiving-environments)


# Creating Environments

Create environments from the Bluebricks app or CLI to deploy blueprints into collections

## Overview

An environment binds a blueprint to a collection and triggers the first run, provisioning your infrastructure. You can create environments directly from the Bluebricks app, the CLI, manifest files, or webhooks. This guide focuses on the Bluebricks app and CLI workflows.

{% hint style="info" icon="book" %}
For conceptual background on environments and how they work, see [Environments](/docs/orchestration/environments).
{% endhint %}

## Prerequisites

All methods require a **collection** with at least one connected cloud account. See [Creating Collections](/docs/orchestration/collections/create-an-environment). Additional prerequisites depend on how you create the environment and are listed in each section below.

## How to create an environment in the Bluebricks app

The Bluebricks app provides a guided wizard for creating environments.

From the **Environments page**, click **create environment** to get started.

You choose one of three paths:

* **From blueprint**: deploy an existing published [blueprint](/docs/orchestration/packages/blueprints-overview) into a collection
* **From code**: connect a Git repository containing your IaC source code
* **From cloud**: import unmanaged cloud resources into a managed environment via the [cloud import agent](/docs/agent/codifying-infrastructure)

<details>

<summary>When to use "From blueprint"</summary>

Choose this when your team has already published a blueprint and you want to deploy it into a collection. This is the fastest path because the blueprint already defines your infrastructure code, packages, and relationships.

[Jump to the instructions](https://bluebricks.co/docs/orchestration/environments/creating-environments#how-to-create-from-blueprint)

</details>

<details>

<summary>When to use "From code"</summary>

Choose this when you have IaC source code in a Git repository (Terraform, OpenTofu, Helm, CloudFormation, or Bicep) and want to create a new blueprint from it. Bluebricks connects to your repo, wraps the code in a blueprint, and deploys it.

This is the standard path for writing infrastructure from scratch or bringing existing code under Bluebricks management. [Jump to the instructions](https://bluebricks.co/docs/orchestration/environments/creating-environments#how-to-create-from-code)

</details>

<details>

<summary>When to use "From cloud"</summary>

Choose this when you have existing cloud resources that were created outside of Bluebricks and want to bring them under management. The Cloud Import Agent scans the cloud account associated with your [collection](/docs/orchestration/collections), lets you select resources, and generates the IaC code for you.

Choose this path when you have infrastructure already running that you want to codify and manage on Bluebricks going forward. [Jump to the instructions](https://bluebricks.co/docs/orchestration/environments/creating-environments#how-to-create-from-cloud)

</details>

<figure><img src="/files/DzVIBdCsnjYZqXWA7h1n" alt="Create environment modal showing three options: From blueprint, From code, and From cloud"><figcaption></figcaption></figure>

### How to create from blueprint

Choose **From blueprint** when your team has already published a blueprint and you want to deploy it into a collection.

**Prerequisites**: at least one published blueprint. See [Creating Blueprints](/docs/orchestration/packages/blueprints-overview/creating-blueprints).

{% hint style="info" %}
The **From blueprint** option is disabled if no blueprints exist yet. Publish a blueprint first, or use **From code** to create one from a Git repository.
{% endhint %}

{% stepper %}
{% step %}
**Select a collection**

Choose the target collection for the environment.
{% endstep %}

{% step %}
**Name the environment**

Enter a descriptive slug (e.g., `git_ops_prod`).
{% endstep %}

{% step %}
**Select a blueprint**

Choose the blueprint you want to deploy from the dropdown. Blueprints are filtered by the selected collection.
{% endstep %}

{% step %}
**Create the environment**

Click **Create** to create the environment and trigger the first run.
{% endstep %}
{% endstepper %}

### How to create from code

Choose **From code** when you have IaC source code in a Git repository and want to create a new blueprint from it.

**Prerequisites**: a public or private Git repository with IaC code.

{% stepper %}
{% step %}
**Select a collection**

Choose the target collection for the environment.
{% endstep %}

{% step %}
**Set source code**

Select the IaC technology (OpenTofu, Terraform, Helm, CloudFormation, or Bicep), then choose how to connect your repository:

{% tabs %}
{% tab title="From connected repo" %}
Select your Git organization and repository from your connected integrations, then set the branch and optionally a subdirectory path.

{% hint style="info" icon="github-alt" %}
This option requires the [GitHub integration](/docs/integrations/github). If no repositories are connected, you will see a prompt to configure repository access.
{% endhint %}
{% endtab %}

{% tab title="From remote URL" %}
Enter a Git remote URL manually (e.g., `https://github.com/org/repo`), then set the branch and optionally a subdirectory path. Use this for public repositories that don't require an integration.
{% endtab %}
{% endtabs %}
{% endstep %}

{% step %}
**Name the environment**

Enter a descriptive slug (e.g., `git_ops_prod`).
{% endstep %}

{% step %}
**Define a blueprint**

Every environment runs a blueprint, so Bluebricks creates one from your source code as part of this flow. Give the blueprint a name and optional description. Once created, other team members can reuse this blueprint to deploy the same infrastructure into other collections without reconnecting the repository. See [Blueprints](/docs/orchestration/packages/blueprints-overview) for more on how blueprints work.
{% endstep %}

{% step %}
**Create the environment**

Click **Create** to generate the blueprint and environment. Bluebricks triggers the first run automatically.
{% endstep %}
{% endstepper %}

### How to create from cloud

Choose **From cloud** to import and codify existing unmanaged cloud resources into a managed environment.

{% stepper %}
{% step %}
**Select a collection**

Choose the collection you want to import resources from.
{% endstep %}

{% step %}
**Go to the Cloud Graph**

Click **Go to graph** to open the resource explorer, where you can select cloud resources to import and codify. See [Codifying Infrastructure](/docs/agent/codifying-infrastructure) for more details.
{% endstep %}
{% endstepper %}

## How to create an environment via the CLI

Use the `bricks install` command to create an environment from the terminal.

**Prerequisites**: Bricks CLI installed and authenticated. See [Bricks CLI](/docs/bricks-cli/bricks-cli).

### Basic example

```bash
bricks install @bluebricks/postgres --collection=production --props-file=path/to/props.json
```

### Plan-only (preview changes without applying)

```bash
bricks install @bluebricks/postgres --collection=production --props-file=path/to/props.json --plan-only
```

### Key flags

| Flag               | Description                                                               |
| ------------------ | ------------------------------------------------------------------------- |
| `-c, --collection` | Collection slug as the deployment target                                  |
| `--env-slug`       | Environment slug (target an existing environment for redeployment)        |
| `--set-slug`       | Set a custom environment slug                                             |
| `-p, --props`      | JSON string containing blueprint properties                               |
| `--props-file`     | Path to a JSON file containing blueprint properties                       |
| `-f, --file`       | Path to a YAML manifest file (`bricks/v1` schema) for non-interactive use |
| `--plan-only`      | Create a plan without applying                                            |
| `-y, --yes`        | Skip confirmation and deploy directly                                     |

For the full command reference, see [`bricks install`](/docs/bricks-cli/cli-reference/bricks_install).

## Other ways to create environments

* **Manifest file (CI/CD)**: define environments declaratively using a manifest file. See [Environment Manifest File Format](/docs/orchestration/runs/deployment-manifest-file-format) and [Managing Configuration on Git](/docs/orchestration/bluebricks-git-repository-guide/managing-configuration-on-git).
* **Webhooks**: trigger environment creation from external systems. See [Webhooks](/docs/orchestration/webhooks).

## What happens after creation

When you create an environment, Bluebricks automatically triggers the first run in **plan** phase. The unified plan shows all proposed infrastructure changes across every package in the blueprint.

Review the plan, then **approve** to apply the changes and provision your infrastructure. For full details on the run lifecycle, see [Runs](/docs/orchestration/runs).


# GitOps Environments

Automatically trigger infrastructure plans and deployments from Git pushes

## Overview

The basic promise of infrastructure as code is simple: when you change your code, your infrastructure should respond. Bluebricks lets you connect an environment directly to\
a Git repository so that every push triggers a run and every pull request gets a plan.

No CI/CD pipeline to build or maintain, and no need to manually create or version artifacts or blueprints; Bluebricks handles all of that from your source code.

<figure><picture><source srcset="/files/idqTampbHlXTUuTHABC7" media="(prefers-color-scheme: dark)"><img src="/files/YI5XIx0A2or1PK0fj7Ut" alt=""></picture><figcaption></figcaption></figure>

### How it works

When you create an automated environment, Bluebricks registers a webhook on your GitHub repository through the GitHub App. From that point, the flow is automatic: you push code (or open a PR), Bluebricks publishes an updated blueprint from the source, triggers a run, and posts the plan results back to the PR as a [check run](#plan-results-on-pull-requests).

* **Push to the trigger branch**: Bluebricks runs a full plan and apply
* **Pull request targeting the trigger branch**: Bluebricks runs a **plan only** (changes are never applied from a PR)

{% hint style="info" %}
The auto-trigger pipeline is read-only: it clones your repository and publishes a blueprint to the Bluebricks registry, but never pushes files back. Files generated during publishing (such as `bricks.json`) must be committed to your repo manually if you need them in version control.
{% endhint %}

<figure><picture><source srcset="/files/4gXzJnKWIwAOswsoxP2F" media="(prefers-color-scheme: dark)"><img src="/files/LqpqcHTUzkZnJmvjRlfA" alt=""></picture><figcaption></figcaption></figure>

### Auto-trigger rules

Every automated environment has a **trigger branch**, the branch you select when creating the environment (e.g., `main`). Auto-trigger behavior depends on the type of Git event.

<details open>

<summary>Push events</summary>

When code is pushed to the trigger branch, Bluebricks triggers a full **install** run (plan followed by apply). This is the default behavior for automated environments.

Pushes to other branches are ignored. Only the configured trigger branch activates the pipeline.

</details>

<details>

<summary>Pull request events</summary>

When a pull request is **opened**, **updated** (new commits pushed), or **reopened** against the trigger branch, Bluebricks triggers a **plan-only** run. This is a safety guard: pull request events never trigger an apply, regardless of configuration.

The plan output is posted back to the PR as a GitHub Check Run so reviewers can evaluate the infrastructure impact before approving the merge.

When a pull request is **closed** (merged or abandoned), Bluebricks cancels any pending check runs associated with that PR.

</details>

<details>

<summary>Blueprint publish events</summary>

If a new version of the linked blueprint is published through other means (e.g., the CLI or API), Bluebricks also triggers an auto-run on any environment with auto-trigger enabled for that blueprint. This ensures environments stay in sync even when blueprints are updated outside the Git flow.

</details>

### Plan results on pull requests

When a pull request targets the trigger branch of an automated environment, Bluebricks creates a **GitHub Check Run** named `Bluebricks Run: <environment-slug>`. The check run progresses through several states:

<table><thead><tr><th width="219.23828125">Check Run status</th><th>Meaning</th></tr></thead><tbody><tr><td><strong>Queued</strong></td><td>The environment is waiting for a previous run to finish</td></tr><tr><td><strong>In progress</strong></td><td>Bluebricks is analyzing the repository or executing the plan</td></tr><tr><td><strong>Completed (success)</strong></td><td>The plan succeeded. The check run output contains the full plan details</td></tr><tr><td><strong>Completed (failure)</strong></td><td>The plan failed. The check run output contains error details</td></tr><tr><td><strong>Cancelled</strong></td><td>The PR was closed or the run was superseded by a newer push</td></tr></tbody></table>

The plan output (resource changes, additions, and deletions) appears directly in the check run's **output tab** on GitHub. Reviewers can read the infrastructure plan without leaving the pull request.

{% hint style="info" %}
If an environment already has a running deployment when a new PR event arrives, the new run is **queued** and starts automatically once the current run completes.
{% endhint %}

### How to set up an automated environment

To create an automated environment, use the **From code** flow in the **Create environment** modal. For step-by-step instructions, see [Creating Environments > Connect source](/docs/orchestration/environments/creating-environments#connect-source).

Bluebricks generates a blueprint from your source code, creates the environment, and triggers the first run. You must **approve and apply this initial run** to activate auto-trigger. Once the first run completes, the webhook is registered and every subsequent push to the configured branch and every PR targeting it automatically triggers runs.

{% hint style="warning" %}
Auto-trigger requires the [GitHub integration](/docs/integrations/github) (GitHub App). Public repositories created without the GitHub App do not support auto-trigger or check runs.
{% endhint %}

### Limitations

* **Single trigger branch**: each environment is linked to one branch. Pushes to other branches do not trigger runs
* **Cannot link existing environments**: you can only create a *new* automated environment through the "From code" flow. Connecting an existing environment to a Git repository via the UI is planned for a future release


# Archiving Environments

Remove environments from your active list without affecting deployed infrastructure

## Overview

Archiving moves an environment to the **Archived** tab, removing it from your active environment list. Archived environments no longer trigger new runs, but all existing infrastructure remains untouched. Archiving is purely a visibility and state change: no resources are created, modified, or destroyed.

You can archive an environment regardless of its install status (live, uninstalled, or draft). However, you cannot archive an environment while a run is in progress. Wait for the current run to complete before archiving.

Archived environments are excluded from collection cost calculations.

{% hint style="info" %}
Archiving does **not** destroy infrastructure. If you want to tear down resources, uninstall the environment first. See [Runs](/docs/orchestration/runs) for details on the uninstall workflow.
{% endhint %}

## How to archive an environment

{% stepper %}
{% step %}
**Open the environment actions menu**

From the [**Environments**](https://app.bluebricks.co/environments) page, go to the environment you want to archive and click the he **three-dot menu**.
{% endstep %}

{% step %}
**Click Archive**

Select **Archive** from the dropdown menu.
{% endstep %}

{% step %}
**Confirm**

Review the confirmation message and confirm. The environment moves to the **Archived** tab.
{% endstep %}
{% endstepper %}

## How to unarchive an environment

{% stepper %}
{% step %}
**Open the Archived tab**

Navigate to the [**Archived**](https://app.bluebricks.co/environments?tab=archive) tab in the environments list.
{% endstep %}

{% step %}
**Click Unarchive**

Find the environment you want to restore and click **Unarchive**. The environment returns to the active list and can trigger runs again.
{% endstep %}
{% endstepper %}

{% hint style="warning" %}
You cannot unarchive an environment if its parent collection has been deleted or locked. To unarchive an environment in a locked collection, unlock the collection first.
{% endhint %}


# Automatic Drift Detection

Detect when infrastructure state diverges from the desired blueprint configuration

## Overview

Drift detection helps you identify when a deployed environment no longer matches its defined blueprint. In Bluebricks, you can continuously compare the actual cloud state with the desired state declared in your Infrastructure as Code. If resources were modified manually, changed outside the pipeline, or partially failed during execution, we surface that difference as drift. This gives you clear visibility into what changed, where it changed, and whether action is required, so you can restore consistency and keep your environments reliable and automation-ready.

<figure><picture><source srcset="/files/SCuE6rp48OdGhym43WaF" media="(prefers-color-scheme: dark)"><img src="/files/cy33nZ8zgsvlsvZzLl7v" alt=""></picture><figcaption></figcaption></figure>

## How drift detection works

When a drift check runs, Bluebricks performs a plan-only execution against the environment’s current blueprint configuration. This run does not apply changes. It safely evaluates the difference between the declared state and the live resources in the connected collection.

During the run, Bluebricks:

* Executes a plan-only run using the latest Blueprint configuration
* Compares the declared state with the actual cloud resources
* Identifies differences such as added, changed, or deleted resources
* Records the result as a drift detection activity in the environment history

If the plan returns zero changes, the environment matches the declared code and no further action is required. If differences are detected, the environment status is flagged as Drifted, indicating that the live infrastructure no longer aligns with the Blueprint and review is required.

## How to enable automatic drift detection

You enable drift detection per environment. Once enabled, Bluebricks runs drift checks on the configured schedule.

1. Open the environment detail page
2. Go to the **Automatic drift detection** tab
3. Toggle drift detection to **On**
4. Optionally, enable **Auto-Remediate** to automatically correct detected drift

The drift detection label shows the current state: **On**, **Off**, or [**Paused**](#user-content-fn-1)[^1].

{% hint style="info" %}
By default, checks run every 24 hours at 2:00 AM UTC.
{% endhint %}

## Auto-Remediation

Auto-remediation automatically corrects detected drift by reapplying the declared configuration.

### How it works

1. A drift detection run executes a plan-only check
2. If the plan detects drift, Bluebricks automatically initiates a second run
3. The second run executes with **auto-approve**, applying the plan without waiting for manual approval
4. The environment is brought back to its declared state

Both the detection run and the remediation run appear in the environment's activity history as separate entries.

### Safeguards

* **No concurrent tasks**: Bluebricks does not start a remediation run if another task is already in progress on the same environment.
* **Respects collection policies**: auto-remediation follows the same policy framework as regular runs.
* **Full audit trail**: every auto-remediation run is logged with plan output, apply logs, and state changes.

<details>

<summary>When to enable auto-remediation</summary>

* You maintain a strict desired-state model and want zero tolerance for drift.
* Your environments enforce compliance or security baselines that must not diverge.
* Your team has confidence in the declared configuration and wants hands-off correction.

</details>

<details>

<summary>When to avoid auto-remediation</summary>

* Your team makes intentional manual changes that should persist (for example, during incident response).
* Your blueprints include resources where the live state is expected to diverge from the declared configuration.
* You prefer to review drift diffs before taking corrective action.

</details>

{% hint style="warning" %}
Auto-remediation applies changes automatically. Make sure your blueprint configuration is accurate and tested before enabling it on production environments.
{% endhint %}

## Drift runs history

Drift detection runs appear in the environment's activity history alongside regular runs. You can distinguish them by:

* **Task type**: drift runs are labeled with the `drift_detection` task type.
* **Plan-only indicator**: drift runs are always plan-only and never include an apply phase.
* **Drift tab**: the **Automatic drift detection** tab on the environment detail page provides a focused view of drift status, including the latest result and historical drift runs.

When drift is detected, the drift details show which resources changed, the attribute-level diffs, and whether resources were added, modified, or deleted outside of Bluebricks.

[^1]: Drift detection is paused when the environment's status is **draft** or **uninstalled.**


# Time to Live (TTL)

Define how long an environment should be up and running

## Overview

Environment TTL (Time to Live) lets you schedule the automatic uninstallation of an environment. Instead of relying on someone to manually tear down infrastructure, you define a recurring daily or weekly schedule and Bluebricks uninstalls the environment at the specified time.

## How environment TTL works

TTL supports intentional environment management. You can shut down dev, staging, or sandbox environments outside business hours to control cloud spend, align teardown with maintenance windows, or ensure environments follow internal operational standards. It also helps prevent environments from running longer than intended, reducing drift and maintaining cleaner collections.

Each environment includes a dedicated **Environment TTL** tab on its detail page. From this tab, you can create, edit, enable, or disable a TTL schedule.

<figure><img src="/files/L1POK9qEYYJdSfqCDbyO" alt=""><figcaption></figcaption></figure>

When a TTL schedule triggers, Bluebricks starts an uninstall run for the environment, the same operation as a manual uninstall. The run follows the standard environment lifecycle: it evaluates the blueprint, builds a destroy plan across all packages, and tears down resources in the correct dependency order. The run appears in the environment's history with full logs and status tracking.

The uninstall follows the same policies and approval flows configured on the target collection. If an approval policy is in place, the scheduled uninstall respects it.

{% hint style="info" %}
A TTL schedule does not delete the environment itself. It uninstalls the deployed resources. The environment record, history, and configuration remain intact. You can re-run the environment at any time.
{% endhint %}

## How to set up a TTL schedule

{% stepper %}
{% step %}
**Turn on TTL**

1. Go to the [Environment](https://app.bluebricks.co/environments) page and click **Review** on the environment you want to configure
2. Click the **Environment TTL** tab
3. Set the toggle to **On**, which will open the scheduler
   {% endstep %}

{% step %}
**Create a schedule**

1. Choose a recurrence type: **Daily** or **Weekly**
   1. Set the time in hours and minutes using 24-hour UTC time
   2. For weekly schedules, select which days the uninstall should run
2. Click **save**

<details>

<summary>Using CRON expression</summary>

You can also use a five-field cron structure in UTC to schedule the TTL.

Configure the minute, hour, and day-of-week fields, which accept values 0-6 (Sun-Sat). The day-of-month and month fields are fixed to `*`.

</details>
{% endstep %}
{% endstepper %}

{% hint style="info" %}
TTL schedules run under a dedicated system identity. The uninstall run is attributed to the scheduler, not to a specific user.
{% endhint %}

{% hint style="success" %}
TTL works well with temporary scaling workflows. Set a TTL on environments that are scaled up for testing to ensure automatic cleanup. See [Temporary Scaling](/docs/managing-infrastructure/managing-infrastructure/temporary-scaling) for the full workflow.
{% endhint %}

#### Edit or disable TTL

You can edit or disable Environment TTL at any time to change the recurrence, adjust the time, or disable the schedule. Disabling preserves your configuration so you can re-enable it later without reconfiguring.


# Runs

Plan and apply infrastructure changes through runs

A run is a single execution of an environment. Each time you deploy, update, or destroy infrastructure through Bluebricks, you trigger a run. Runs are divided into two phases, plan and apply, with an optional approval step in between.

{% hint style="success" %}
**Try it with the agent.** The agent handles plan/approve/apply flows through conversation. See [Agent Overview](/docs/agent/agents-overview).
{% endhint %}

Every run is fully tracked: Bluebricks records the plan output, apply logs, inputs, outputs, and state changes. This gives your team a complete, auditable history of how your infrastructure has changed over time.

## How runs work

Every run executes against a published, immutable version of the blueprint, not the latest code in your repository. This guarantees that what you reviewed in the plan phase is exactly what gets applied.

When a run starts, Bluebricks evaluates the blueprint and all its child packages to build a directed acyclic graph (DAG). This determines the order in which packages are planned and applied: parallel where possible, sequential where dependencies require it. For details on how the DAG works and how to optimize for parallelism, see [Parallel Execution](/docs/orchestration/runs/parallel-execution).

### Plan phase

During the plan phase, Bluebricks iterates through each package in the DAG and produces a unified plan. The plan captures every expected change across all layers of infrastructure, including resources to be created, updated, or destroyed, before anything is applied.

The plan output groups changes into four categories: resources to create, resources to update, resources to destroy, and resources with no changes. This unified view spans every package in the blueprint so you can review all proposed changes in one place.

Once planning is complete, the run pauses and surfaces the plan for review. You can inspect the full diff before deciding whether to proceed.

{% @mermaid/diagram content="sequenceDiagram
participant C as Client
participant B as Bluebricks
participant O as Orchestrator

```
C->>B: Trigger run
B->>B: Create run task
O-->>B: Poll for pending tasks
O->>O: Build DAG & plan packages
O->>B: Plan complete
B->>C: Plan ready for review" %}
```

### Approval

After the plan phase, you can approve or reject the run. If your collection has an [owner approval](/docs/orchestration/collections/owners-and-members) policy configured, a designated collection owner must approve before the run can proceed.

You can also configure environments to auto-approve, skipping the review step and proceeding directly to apply.

### Apply phase

When the run is approved, Bluebricks executes the plan in the same order it was evaluated. During each step, it collects outputs from the completed package and passes them to the next package in the sequence.

Once the apply phase is complete, Bluebricks updates the environment state and records the run in the environment's history.

{% @mermaid/diagram content="sequenceDiagram
participant C as Client
participant B as Bluebricks
participant O as Orchestrator

```
C->>B: Approve run
B->>B: Update run stage
O-->>B: Poll for pending tasks
O->>O: Apply packages in DAG order
O->>B: Run complete
B->>C: Run complete" %}
```

## Git source

Runs triggered from a git-connected environment display their source context in the **Git source** column on the **Runs** tab.

<figure><picture><source srcset="/files/dYLvBih869GRMCZGMRWe" media="(prefers-color-scheme: dark)"><img src="/files/itbKITJI5MBm8I1D4jLS" alt="The Runs tab showing the Git source column with PR number, branch, and commit SHA for each run"></picture><figcaption></figcaption></figure>

Each git-triggered run shows:

* **PR number**: links to the pull request that triggered the run
* **Branch name**: the head branch of the pull request or push event
* **Commit SHA**: the short commit hash, links to the commit in your VCS provider. Hover to see the commit author

Runs not triggered by a git event display "n/a" in the Git source column.

## How to trigger a run

You can trigger a run from any of the following interfaces:

* **Web app:** initiate a run manually from the [environment page](/docs/orchestration/environments/creating-environments)
* **Git push:** connect an environment to a repository so that pushes or pull requests trigger runs automatically
* **MCP:** trigger runs through [Model Context Protocol](/docs/integrations/bricks-mcp) for AI agent integrations
* **Bricks CLI:** use the [`bricks install`](/docs/bricks-cli/cli-reference/bricks_install) command to trigger a run from your terminal
* **API:** trigger runs programmatically via the [Deployments API](https://bluebricks.co/docs/api/reference/deployments)
* **Webhooks:** configure webhooks to trigger runs automatically on external events
* **CI/CD pipelines:** integrate with [GitHub Actions](/docs/integrations/githubactions), [GitLab](/docs/integrations/gitlab), [Azure DevOps](/docs/integrations/azure-devops), and other CI/CD tools

Regardless of how a run is triggered, every execution follows the same plan-approve-apply lifecycle and is fully recorded in the environment's history.


# Monitoring Runs

Track run progress and status from the Bluebricks app or CLI

## Overview

Every run progresses through a series of statuses as it moves from planning to completion. You can monitor run progress in real time from the Bluebricks app or list environments from the CLI.

{% hint style="info" icon="book" %}
For background on how runs work, see [Runs](/docs/orchestration/runs). For details on the plan-approve-apply lifecycle, see the plan phase and apply phase sections on that page.
{% endhint %}

## Run statuses

<table><thead><tr><th width="169.20703125">Status</th><th>Description</th></tr></thead><tbody><tr><td>Pending</td><td>Run is queued and waiting to start</td></tr><tr><td>Planning</td><td>Generating the execution plan across all packages</td></tr><tr><td>Waiting for input</td><td>Plan complete, awaiting approval</td></tr><tr><td>Plan approved</td><td>Approved, pending installation</td></tr><tr><td>Installing</td><td>Actively provisioning or updating infrastructure resources</td></tr><tr><td>Completed</td><td>Run finished successfully</td></tr><tr><td>No changes</td><td>Plan detected no infrastructure changes</td></tr><tr><td>Failed</td><td>Run encountered an error</td></tr><tr><td>Canceled</td><td>Run was canceled before completion</td></tr><tr><td>Skipped</td><td>Run execution was skipped</td></tr><tr><td>Drifted</td><td>Infrastructure differs from planned state (drift detection only)</td></tr></tbody></table>

## How to monitor runs in the Bluebricks app

### Environments list

Navigate to **Environments** to see the latest run status for each environment. Each row shows a status badge with the current stage.

### Run detail page

Click an environment to open its run detail page. The detail page shows:

* **Status timeline**: a vertical progression through each stage with timestamps for every transition
* **Plan diff**: resources to create, update, or destroy, grouped by package
* **Live logs**: real-time streaming logs during execution, filterable by log level
* **Resource list**: individual resource states, configuration, and outputs
* **Dependency graph**: visual representation of resource dependencies

### Approving or rejecting a run

When a run reaches **Waiting for input** status:

* Click **Approve & Apply** to proceed with the plan (keyboard shortcut: `Cmd+Enter` / `Ctrl+Enter`)
* Click **Reject** to cancel the run (keyboard shortcut: `Cmd+Z` / `Ctrl+Z`)

{% hint style="warning" %}
If you reject a run that is already partially applied, some resources may have been modified. Review the run logs to understand what was applied before the rejection.
{% endhint %}

For uninstall runs, the **Approve & Apply** button appears in red. A confirmation dialog reminds you that approving will remove all previously provisioned resources.

{% hint style="info" %}
If the collection has a cost quota configured and the run would exceed it, the **Approve & Apply** button is disabled. Contact the collection owner to adjust the quota or approve the run.
{% endhint %}

## How to monitor runs via the CLI

### List environments

```bash
bricks deploy list
```

Output columns:

* **SLUG**: environment identifier
* **BLUEPRINT**: blueprint name and version
* **TARGET COLLECTION**: target collection name

### Limit results

```bash
bricks deploy list --limit 50
```

The default limit is 100. The CLI paginates results and prompts to fetch more if available.

For the full command reference, see [`bricks deploy list`](/docs/bricks-cli/cli-reference/bricks_deploy/bricks_deploy_list).

## See also

* [Runs](/docs/orchestration/runs): run lifecycle and plan/apply phases
* [Destroying Environments](/docs/orchestration/runs/destroying-environments): uninstall environments and clean up resources
* [Creating Environments](/docs/orchestration/environments/creating-environments): deploy blueprints into collections


# Destroying Environments

Uninstall an environment to destroy all infrastructure resources it provisioned

## Overview

Uninstalling an environment triggers a destroy run that removes all infrastructure resources previously provisioned by that environment. Like a deploy run, the destroy run follows the plan-approve-apply lifecycle: Bluebricks generates a destroy plan for you to review before any resources are deleted.

{% hint style="info" icon="book" %}
For background on how runs work, see [Runs](/docs/orchestration/runs). For creating environments, see [Creating Environments](/docs/orchestration/environments/creating-environments).
{% endhint %}

## How to uninstall from the Bluebricks app

{% stepper %}
{% step %}
**Step 1: Open the environments page**

Navigate to **Environments** and find the environment you want to destroy.
{% endstep %}

{% step %}
**Step 2: Start the uninstall**

Click the three-dot menu on the environment row and select **Uninstall**.
{% endstep %}

{% step %}
**Step 3: Confirm**

A dialog asks you to confirm: "This will generate a plan to destroy the infrastructure resources previously provisioned by this environment. Are you sure you want to proceed?" Click **Uninstall** to continue.
{% endstep %}

{% step %}
**Step 4: Review the destroy plan**

Bluebricks generates a destroy plan and opens the run detail page. The plan shows all resources that will be removed. Review the changes carefully.
{% endstep %}

{% step %}
**Step 5: Approve and apply**

Click **Approve & Apply** to execute the destroy plan. The button appears in red for uninstall runs as a visual reminder.

{% hint style="warning" %}
Destroyed resources cannot be recovered. Back up any critical data before approving.
{% endhint %}
{% endstep %}
{% endstepper %}

## How to uninstall via the CLI

**Prerequisites**: Bricks CLI installed and authenticated. See [Bricks CLI](/docs/bricks-cli/bricks-cli).

### Plan destruction first (recommended)

```bash
bricks uninstall --env-slug my-postgres-db --collection production --plan-only
```

Review the plan in the Bluebricks app, then approve to proceed.

### Uninstall by environment slug

```bash
bricks uninstall --env-slug my-postgres-db --collection production
```

### Uninstall by package name

```bash
bricks uninstall @myorg/postgres --collection production
```

If multiple environments exist for the same package, the CLI prompts you to select one.

### Key flags

<table><thead><tr><th width="193.328125">Flag</th><th>Description</th></tr></thead><tbody><tr><td><code>--env-slug</code></td><td>Environment slug to destroy</td></tr><tr><td><code>-c, --collection</code></td><td>Target collection</td></tr><tr><td><code>--plan-only</code></td><td>Generate a destroy plan without applying</td></tr></tbody></table>

For the full command reference, see [`bricks uninstall`](/docs/bricks-cli/cli-reference/bricks_uninstall).

## What happens during uninstall

1. Bluebricks creates a destroy plan showing all resources to be removed
2. Resources are destroyed in reverse dependency order (child packages first)
3. The plan requires approval before execution, unless the environment is configured to auto-approve
4. Once complete, the environment moves to an uninstalled state

## Important considerations

* **Back up critical data** before destroying (databases, configuration files, logs)
* **Destroy child environments first** when environments depend on shared resources (e.g., destroy the app service before the VPC)
* **Check for resources outside Bluebricks management**: persistent storage volumes, external DNS records, and manually created firewall rules may require manual cleanup in your cloud console
* **Production collections**: if the collection has an [Owner Approval](/docs/orchestration/collections/owners-and-members) policy, a designated owner must approve the destroy plan

## See also

* [Runs](/docs/orchestration/runs): run lifecycle and plan/apply phases
* [Creating Environments](/docs/orchestration/environments/creating-environments): deploy blueprints into collections
* [Monitoring Runs](/docs/orchestration/runs/monitoring-runs): track run progress and status


# Promoting Environments

Promote an environment run to another collection with the same blueprint and inputs

## Overview

Promotion creates a new environment in another collection using the exact blueprint version and inputs from a completed run. This enables controlled progression between collections when you want to carry proven configuration forward without rebuilding it from scratch (for example, *dev* to *staging* to *production*).

<figure><img src="/files/TMU0SLDVzlA1rqqvceJT" alt=""><figcaption></figcaption></figure>

## How promotion works

Promotion creates a new [environment](/docs/orchestration/environments) in a different [collection](/docs/orchestration/collections) using the configuration from a specific completed run.

It helps to think of promotion as copying the **run configuration**, not the environment itself. The blueprint version and inputs move forward, while collection-specific settings are resolved from the target collection.

<details>

<summary>Example: Promoting from Staging to Production</summary>

Your team deploys a `web-app` blueprint into the **Dev** collection.

* Blueprint version: `v1.4.2`
* Inputs:
  * `instance_count = 3`
  * `enable_monitoring = true`
  * `domain_name = dev.example.com`

The run completes successfully and is validated by QA.

You now want to deploy the same configuration to **Staging**.

Instead of manually selecting `v1.4.2` again and re-entering all inputs, you click **Promote** on the selected run and choose your **Staging** collection.

You’re redirected to a new environment run in the Staging collection with:

* Blueprint version `v1.4.2`
* All input values prefilled

You can update what is environment-specific (for example, change `domain_name` to `staging.example.com`). The environment will automatically use the Staging collection’s properties, secrets, connected cloud accounts, and policies.

Then click **Deploy**.

The result:

* A new Staging environment
* The same validated configuration
* No copied state or resources from Dev
* Staging collection policies applied automatically

</details>

The sections below explain what is copied and what is automatically adjusted.

### What promotion copies

Promotion copies the **configuration** from one specific completed run.

That means:

* The same **blueprint version**
* The same **input values**
* The same configuration that was executed in that run

When you promote, Bluebricks opens the **Deploy** page for the target collection with that configuration already filled in. You do not need to reselect the blueprint or re-enter inputs.

Promotion copies configuration only. It does **not** copy: run history, outputs, state files, or existing cloud resources.

The result is a new environment in the target collection that starts fresh but uses the same setup.

### What adjusts automatically

Collection-level settings are **not** copied from the source collection.

Instead, the new environment uses the configuration of the **target collection**, including:

* Collection properties
* Secrets
* Connected cloud accounts
* Policies (such as Owner Approval or Cost Limits)

You do not need to reconfigure properties or secrets during promotion because promotion does not change them. However, the collection you are promoting into must already have the required properties and secrets defined.

## How to promote an environment

**Prerequisites**:

* An existing [environment](/docs/orchestration/environments/creating-environments) with at least one successful (completed) run
* Access to both the source and target collections
* At least one [cloud account](/docs/getting-started/connect-your-cloud) connected to the target collection

{% stepper %}
{% step %}
**Open the source environment**

1. Navigate to the environment you want to promote:
   1. You can do this from the environment's **Run history** or from the **Graph view**
2. From the three dot-menu, click **Promote** and the promote dialog opens

{% hint style="warning" %}
Make sure you are promoting from the run whose configuration you want to replicate.
{% endhint %}
{% endstep %}

{% step %}
**Select a target collection**

The dialog lists all available collections except the current one. Collections without connected cloud accounts are filtered out.

1. Select the collection you want to promote into
2. Name the new environment
   {% endstep %}

{% step %}
**Review and deploy**

Bluebricks redirects you to the **Deploy** page with the selected run's configuration prefilled.

1. Review the configuration and adjust any values needed for the target collection
2. Click **Deploy**

If the target collection has an Owner Approval or Cost Limit policy configured, those checks apply before the run executes. Learn more about environments
{% endstep %}
{% endstepper %}

{% hint style="info" %}
Promotion is also useful for temporary scaling workflows. You can test a configuration change in staging and promote only the validated result to production. See [Temporary Scaling](/docs/managing-infrastructure/managing-infrastructure/temporary-scaling) for the full workflow.
{% endhint %}


# State Management and History

Track infrastructure state safely across environments and teams

Bluebricks supports two state management models. You choose who owns and operates the infrastructure state: **Bluebricks-managed** state or **Customer-managed** state.

Your choice determines where state is stored, how access is controlled, and how executions interact with it.

### Bluebricks-managed state

When Bluebricks manages state, it becomes part of the deployment execution lifecycle.\
\
State is stored securely and accessed only through authorized Bluebricks executions. You do not define or maintain a Terraform backend in your code.\
\
**How it works**

* State storage is provisioned and managed by Bluebricks.
* For each execution, Bluebricks injects a temporary backend configuration at runtime.
* Short-lived credentials are generated per execution.
* State access is allowed only while the execution is active.

If your code defines a backend, execution will fail until it is removed.

**Benefits**

* Zero setup: Enable managed state during environment creation. No backend configuration required.
* Execution-scoped access: Only active, authorized executions can read or modify state.
* Encrypted storage: State is encrypted at rest in managed object storage.
* Automatic locking: State locking is handled as part of plan and apply operations.

{% hint style="info" %}
Although the state is managed by Bluebricks, you are the owner and you can export it anytime.
{% endhint %}

#### How to view states in Bluebricks

To view state history:

1. Log-in to Bluebricks
2. Go to **Environments**
3. Hover over the environment you want to view, and click **Review** to open the environment's overview page
4. Go to **States** in the left panel

<details>

<summary>How to view or download a state's config</summary>

From the **environment's state** pag&#x65;**:**

1. Click **the three-dot menu** on the state you want to view
2. Click **Download state** to down a JSON of that state

Or, you can click **View Config** to see the JSON config of the state from the Bluebricks app.

{% hint style="info" %}
Only admins can download states.
{% endhint %}

</details>

### Customer-managed state

With customer-managed state, you retain full control over state storage and access.

You define and operate the Terraform backend in your code. Bluebricks interacts with state using the configuration you provide.\
\
**How it works**

* State backend is defined in your Terraform configuration.
* Credentials and access policies are owned and managed by you.
* Bluebricks executions use the backend as-is.

This model is useful when state must remain in an existing system or comply with strict organizational constraints.

**Considerations**

* You are responsible for backend availability and security.
* State access is not scoped or mediated by Bluebricks.
* Locking behavior depends on your backend configuration.


# Environment Manifest File Format

Declarative YAML format for defining environment state, used in CI/CD pipelines and Git-based infrastructure workflows

The environment manifest file defines the desired state of a Blueprint in Bluebricks. Each environment is represented as a declarative YAML file, which can be integrated into CI/CD processes to enable Git-based workflows and trigger infrastructure changes.

{% hint style="info" %}
Learn more about using the environment declarative file in [Managing Configuration on Git](/docs/orchestration/bluebricks-git-repository-guide/managing-configuration-on-git).
{% endhint %}

### Examples

The following manifest file demonstrates how to declare an environment of an RDS instance to an AWS collection using Bluebricks:

```
---
apiVersion: bricks/v1 
kind: Deployment
metadata:
  name: aws-rds-postgres-bluebricks-staging
spec:
  blueprint: "aws_rds_postgres"
  version: "1.8.0"
  force: false
  planOnly: false
  collection: "bluebricks-staging"
  props:
    rds_postgres_family: postgres16
    rds_postgres_identifier: stage-db
    rds_postgres_engine_version: "16.4"
    rds_postgres_instance_class: db.t4g.micro
    rds_postgres_allocated_storage: 20
    rds_postgres_major_engine_version: "16"
    rds_postgres_max_allocated_storage: 100
    rds_postgres_db_name: bluebricks
    rds_postgres_vpc_private_subnets_ids:
      - "subnet-066c7.....3b6"
      - "subnet-00484.....9d6"
      - "subnet-0321e.....357"
    rds_postgres_create_db_subnet_group: true
    rds_postgres_db_subnet_group_name: staging
    rds_postgres_vpc_security_group_ids:
      - "sg-0e262....536"
```

### Reference

<table><thead><tr><th width="250">Keys</th><th width="418">Description</th><th width="108" data-type="checkbox">Mandatory</th></tr></thead><tbody><tr><td><code>apiVersion</code></td><td>Constant value, should always be <code>bricks/v1</code></td><td>true</td></tr><tr><td><code>kind</code></td><td>Constant value, should always be <code>Deployment</code></td><td>true</td></tr><tr><td><code>metadata</code></td><td>Metadata object, contain non-spec values</td><td>true</td></tr><tr><td><code>metadata.name</code></td><td>The environment name, aka "the slug"</td><td>true</td></tr><tr><td><code>spec</code></td><td>Spec object</td><td>true</td></tr><tr><td><code>spec.blueprint</code></td><td>The name of the blueprint to deploy</td><td>true</td></tr><tr><td><code>spec.version</code></td><td>The blueprint version to deploy</td><td>true</td></tr><tr><td><code>spec.force</code></td><td>Indicate if Orchestrator should skip the "pending for review" step. Default: <code>false</code></td><td>false</td></tr><tr><td><code>spec.planOnly</code></td><td>Indicate if the environment life-cycle ended after the plan step is done. Default: <code>false</code></td><td>false</td></tr><tr><td><code>spec.collection</code></td><td>The targeted collection of the environment. If not provided, targeting the default collection</td><td>false</td></tr><tr><td><code>spec.props</code></td><td>Properties of the environment. Equivalent to <code>props.json</code> file when executing <code>bricks install</code></td><td>true</td></tr><tr><td><code>spec.props.{{name}}</code></td><td>Property name and value</td><td>false</td></tr></tbody></table>


# Using Outputs References

Use the outputs of one environment as inputs for another to compose modular, cross-layer infrastructure architectures

## Overview

Output References in Bluebricks allow you to use the outputs of one environment as inputs for another. This creates a powerful way to compose infrastructure across layers, enabling teams to build modular architectures where higher-level environments automatically consume values produced by foundational or shared environments.

By linking environments through output references, Bluebricks ensures consistency, reduces duplication, and provides a clean interface for passing cross-collection or cross-service dependencies, such as network configurations, credentials, resource identifiers, or endpoints.

## How Output References Work

Each environment exposes its outputs once a run completes successfully. These outputs can be referenced directly as inputs in another environment’s configuration. Bluebricks ensures:

* **Automatic resolution** of referenced outputs during run execution
* **Type-safe and consistent value propagation** across collections
* **Easy change management** by automatically tracking related resources

This turns each environment into a reusable building block that can feed data into any number of dependent environments.

<figure><img src="/files/UDifrlF2Z49VVuCWFk72" alt=""><figcaption><p>Environment page with output references of vgw_id and vpc_id</p></figcaption></figure>

<figure><img src="/files/t89OYgGYFZDSHeMj49pT" alt=""><figcaption><p>Cloud graph showing related resources</p></figcaption></figure>

## Common Use Cases

#### **1. Shared “Master” Resources**

A common pattern is creating a core set of foundational resources (such as networking, IAM, logging, or shared services) and exposing their outputs so they can be consumed by multiple downstream environments.

Examples include:

* Using a central VPC or subnet ID for many application environments
* Providing a shared security group or firewall rule set
* Passing common monitoring or logging endpoints
* Using a globally managed KMS key or identity provider

This ensures consistency across teams and collections while avoiding duplication of foundational resources.

#### **2. Cross-Account Security Dependencies**

Output references also make it straightforward to establish secure relationships between different cloud tenants. This is particularly useful for organizations implementing multi-account architectures, security boundaries, or centralized governance models.

Examples include:

* Passing IAM role ARNs from a security account to workload accounts
* Sharing KMS keys or encryption settings between isolated accounts
* Providing resource identifiers needed for cross-account trust or permissions
* Coordinating shared identity providers, signing keys, or audit pipelines

By using output references, you ensure that these sensitive dependencies remain explicit, discoverable, and centrally managed.

## Benefits of Output References in Bluebricks

Bluebricks enhances the output-reference workflow with:

* **Native dependency management**: get alerted when there is change to dependent resource
* **Automatic output resolution**: removing the need for manual copy-paste or scripting
* **Strong separation of concerns**: foundational and application layers are decoupled


# Using Context References

Insert dynamic references to environment and collection metadata in property values, resolved automatically at runtime

### Overview

You can insert **dynamic references** into property values when configuring **collection properties** or **environment properties**.

These references automatically pull information from the current **Environment** or **Collection**, so you don’t have to hard-code values.

When the environment runs, the reference will be replaced with the actual value.

### Available References

#### Environment References

<table data-full-width="false"><thead><tr><th width="294.9453125">Reference</th><th width="272.078125" valign="middle">Description</th><th>Example Output</th></tr></thead><tbody><tr><td><code>${{bricks.environment.slug}}</code></td><td valign="middle">The unique slug of the environment.</td><td>payments-prod</td></tr><tr><td><code>${{bricks.environment.package}}</code></td><td valign="middle">The blueprint or package assigned to the environment.</td><td>@bluebricks/payments_blueprint</td></tr><tr><td><code>${{bricks.environment.created_time}}</code></td><td valign="middle">The date/time the environment was created. <em>(Only works for existing</em> environment<em>s)</em></td><td>2025-06-30T09:27:14Z</td></tr></tbody></table>

{% hint style="danger" %}
`${{bricks.environment.created_time}}` refers to the creation time of the parent environment and not to a specific run. This means every run of the same environment will have the same creation\_time.
{% endhint %}

#### Collection References

<table><thead><tr><th width="295.03515625">Reference</th><th width="271.515625">Description</th><th>Example Output</th></tr></thead><tbody><tr><td><code>${{bricks.collection.slug}}</code></td><td>The unique slug of the collection.</td><td>prod</td></tr><tr><td><code>${{bricks.collection.name}}</code></td><td>The display name of the collection.</td><td>Production</td></tr></tbody></table>

### How It Works <a href="#dedcf9e6-cb47-4829-97a2-8a8e67306395" id="dedcf9e6-cb47-4829-97a2-8a8e67306395"></a>

Anywhere you can type a property value, you can use:

```
${{bricks.environment.*}} → Information about the environment

${{bricks.collection.*}} → Information about the collection
```

When the environment starts, these placeholders are replaced with the real values from your Bluebricks setup.

### **Example Usage** <a href="#id-418fc142-6d1f-4d7b-a901-dfd76f6b4f63" id="id-418fc142-6d1f-4d7b-a901-dfd76f6b4f63"></a>

#### Collection **Properties Page** <a href="#id-2bdf778c-0a1a-4038-a1be-19cf46933f90" id="id-2bdf778c-0a1a-4038-a1be-19cf46933f90"></a>

You can set a property to dynamically reference the collection name:

```
app_collection = ${{bricks.collection.name}}
```

<figure><img src="/files/OLHYEtNexjXy0l1tMlCe" alt=""><figcaption></figcaption></figure>

When deployed to **Production** collection, this becomes:

```
app_collection = Production
```

#### Environment **Page** <a href="#id-2bdf778c-0a1a-4038-a1be-19cf46933f90" id="id-2bdf778c-0a1a-4038-a1be-19cf46933f90"></a>

You can set a property to dynamically reference the environment name:

```
bucket_name = ${{bricks.environment.slug}}
```

<figure><img src="/files/cg1Ia9ToTRyL9hjSluUf" alt=""><figcaption></figcaption></figure>

When deployed the property will be resolved as:

```
bucket_name = single-tenant-452846-service-bucket
```


# Parallel Execution

How Bluebricks executes blueprint packages in parallel based on their dependencies

When a [run](/docs/orchestration/runs) starts, Bluebricks builds a dependency graph (DAG) from the Data references in your blueprint. Independent packages execute in parallel; dependent packages wait for their inputs to be ready.

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

<details>

<summary><strong>Example</strong></summary>

```json
{
  "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" }
      }
    }
  ]
}
```

</details>

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](/docs/orchestration/packages/blueprints-overview/expr) expressions:

<details>

<summary><strong>Example</strong></summary>

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

</details>

Expressions are evaluated at runtime after dependencies complete.

## Execution order

Bluebricks determines execution order automatically from your Data references. Consider this blueprint:

<details>

<summary><strong>Example</strong></summary>

```json
{
  "packages": [
    {
      "id": "launch_template",
      "props": {
        "name": { "value": "Props.template_name" }
      }
    },
    {
      "id": "s3_bucket",
      "props": {
        "bucket_name": {
          "value": "'logs-' + Data.launch_template.launch_template_id"
        }
      }
    },
    {
      "id": "monitoring",
      "props": {
        "template_id": {
          "value": "Data.launch_template.launch_template_id"
        }
      }
    }
  ]
}
```

</details>

{% @mermaid/diagram content="flowchart TD
LT\["launch\_template"]
S3\["s3\_bucket"]
MON\["monitoring"]

```
LT --> S3
LT --> MON" %}
```

`launch_template` runs first because it has no dependencies. Once it completes, `s3_bucket` and `monitoring` run **in parallel** since both depend only on `launch_template`.

Data references can also chain across nested blueprints — Bluebricks resolves the full dependency chain automatically, regardless of nesting depth.

## Tips for faster runs

Fewer Data references between packages means more parallel execution. Where possible, use `Props` (set at deployment time) instead of `Data` (resolved at runtime) to keep packages independent.

<details>

<summary><strong>Sequential:</strong> each package depends on the previous one</summary>

```json
{
  "packages": [
    { "id": "A" },
    { "id": "B", "props": { "input": { "value": "Data.A.output" } } },
    { "id": "C", "props": { "input": { "value": "Data.B.output" } } }
  ]
}
```

</details>

<details>

<summary><strong>Parallel:</strong> packages use properties instead of cross-package Data references</summary>

```json
{
  "packages": [
    { "id": "A", "props": { "input": { "value": "Props.value" } } },
    { "id": "B", "props": { "input": { "value": "Props.value" } } },
    { "id": "C", "props": { "input": { "value": "Props.value" } } }
  ]
}
```

</details>

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

* [Runs](/docs/orchestration/runs)
* [Inputs & Outputs](/docs/orchestration/packages/inputs-and-outputs)
* [Creating Blueprints](/docs/orchestration/packages/blueprints-overview/creating-blueprints)
* [Using expr](/docs/orchestration/packages/blueprints-overview/expr)


# Cloud Graph

Get a comprehensive understanding of the cloud graph

The cloud graph gives you a clear, operational view of your infrastructure and the relationships between different resources. It brings discovery, codification, and deployment into a single visual graph, so you can reason about infrastructure before deciding how to change it.

{% hint style="success" %}
**Ask the agent.** Query your cloud graph through natural conversation. See [Agent Overview](/docs/agent/agents-overview).
{% endhint %}

<figure><img src="/files/psziwIIWNXNHoH48LvEP" alt=""><figcaption></figcaption></figure>

The cloud graph shows infrastructure across all [collections](/docs/orchestration/collections) you configured in Bluebricks.\
While the graph itself shows all managed environments and their states, Discovery allows you to drill in and see all resources provisioned to your cloud, even those that are not managed by code.

## How the cloud graph works

The cloud graph starts with **discovery**.

Bluebricks first reads your cloud as it exists today and shows those resources in the graph. From there, each resource is labelled as either **unmanaged** (visible but not controlled) or **managed** (controlled via Bluebricks through an [environment](/docs/orchestration/environments)).

### Graph canvas

The canvas shows the structure of a collection at a glance:

* **Collection nodes**
* **Environment nodes** represent managed environments

### Resource explorer

The resource explorer drawer is where details live. It is the single source of truth for resource data.

What you see depends on what’s selected in the graph:

* If a **collection** is selected, it shows all resources in the collection, managed & unmanaged.
* If a **environment** is selected, it shows the packages and resources managed by that environment.
* If an **artifact** or **resource** selected, it shows details scoped to that node.

Managed resources are clearly labeled, with links back to the environment that owns them. Unmanaged resources remain selectable for codification.

### Codification

Discovery is not just for viewing. Unmanaged resources can be turned into code through the **cloud import agent**.

Once codified, those resources become managed. Their ownership shifts from “cloud-only” to an explicit environment in the graph.

[Learn more about importing and codifying your resources](/docs/agent/codifying-infrastructure)

### Notes and limitations

Discovery visibility depends on the permissions configured for the collection. Collections without discovery enabled will show managed resources only.


# Webhooks

Configure webhook callbacks to receive real-time notifications for environment events like creation, updates, and status changes

Webhooks are user-defined HTTP callbacks or event notification mechanisms that allow applications to send real-time information to other systems when specific events occur.

They enable seamless communication between systems by automatically triggering an HTTP request to a specified URL whenever the defined event takes place.

Webhooks are highly effective tools for automating workflows, integrating services, and providing updates without the need for constant polling.

## Scopes and Events

Bluebricks provides hooks related to environments within defined scopes. Webhook events are tied to environments, such as `environment:created` and `environment:updated`, while scopes serve as contextual triggers.

At Bluebricks, there are three types of scopes: collections, blueprints, and environments. Developers can register a webhook for each scope to receive notifications when an environment is created or updated.

#### Examples

If a developer wants to be notified when a new environment occurs in the production collection, the event would be `environment:created` with the scope type set to `collection` and its value, `production`.

In this case, the developer will receive notifications for **any** **new** environment taking place in `production`.

On the other hand, if the developer registers for both events; `environment:created` and environment`:updated`, they will receive notifications for **any** environment event (creation or update) occurring in the `production` collection.

{% hint style="info" %}
The events are agnostic to the environment intention and include modifications, deletions, or even no-change actions.
{% endhint %}

### Required Permission Scopes

Managing webhooks on Bluebricks requires users to have the following permission scopes:

* `create:webhook`
* `update:webhook`
* `delete:webhook`

### How to Create a Webhook Subscription

Webhook subscriptions can be managed through the [Bluebricks API](https://github.com/bluebricks-dev/Bluebricks-Documentation/blob/main/workflows/broken-reference/README.md) or directly via the [Bluebricks App](https://app.bluebricks.co). Follow the below steps to create your first webhook subscription:

1. [Open the Account Settings Page and select the Webhooks tab](https://app.bluebricks.co/settings?tab=webhooks)
2. Click the Add Webhook button on the top right corner of the pane
3. Choose a name, set a URL, and choose Scope object and Events
4. Click the Create Webhook button at the bottom left corner of the sidebar

<figure><img src="/files/ZRPvuL5CCIS6tdiDHpRq" alt=""><figcaption></figcaption></figure>

### Scope Types

#### Collection

The collection scope type ensures that notifications are triggered for any environments and updates within the selected collection, regardless of the blueprint. Use this scope type to track changes across the collection holistically.

#### Blueprint 🔜

The blueprint scope type triggers notifications based on environments of a specific blueprint. Use this type if you want to be notified whenever a specific blueprint is deployed or modified.

#### Environments

The environment scope type ensures that notifications are triggered for any updates to a specific environment. Use this scope type to track changes related to a particular environment.

### Events

#### `environment:created`

The `created` event is triggered each time a new environment activity occurs.

For example, this event will be triggered when a developer deploys a blueprint for the first time and each time they deploy an update to an existing one.

Bluebricks will call the webhook for each activity without tracking its progress or reporting its outcome (see red arrows below):

<figure><img src="/files/oHDzw7hxY38nlKWqrv2a" alt=""><figcaption></figcaption></figure>

### `environment:updated`

The `updated` event is triggered for every change in the environment lifecycle, excluding its creation. By subscribing to `environment:updated`, developers will receive notifications for the following events:

| Event                | Key             | Description                                                                                                  |
| -------------------- | --------------- | ------------------------------------------------------------------------------------------------------------ |
| Planning             | `planning`      | Whenever Bluebricks begins predicting upcoming changes in the cloud and generates a environment run plan.    |
| Waiting for Approval | `planned`       | This is an optional event, dependent on the configuration set during the initiation of the environment run.  |
| Plan Approved        | `plan_approved` |                                                                                                              |
| Installing           | `installing`    | The active phase of the environment run, during which Bluebricks implements changes in the cloud collection. |
| Completed            | `completed`     | Triggered when the installation is successfully completed, and all changes have been implemented.            |
| Canceled             | `canceled`      | Triggered when the environment run is canceled by an authorized user.                                        |
| No Changes           | `no_change`     | Triggered, typically after the planning stage, when Bluebricks detects that no changes are required.         |

#### Payload Example

```
{
  "type": "environment:updated",
  "webhook": {
    "id": "80df0bf0-4b05-4c96-9216-ec5057a71da2",
    "scope": "organization",
    "scope_id": "org_e5Oh1aexw4OUDZmd"
  },
  "blueprint": {
    "qualified_name": "@bluebricks/eks_core",
    "version": "1.12.0"
  },
  "environment": {
    "id": "2a151a4b-874b-46d8-8f34-a803c80a69fe",
    "slug": "bluebricks-eks-api-core-us-west-1",
    "created_at": "2025-03-02T11:39:36.585Z",
    "initiated_by": {
      "name": "Jane Doe",
      "email": "jane@example.com"
    },
    "reviewed_by": null,
    "changes": {
      "stage": "planned",
      "archived": null
    },
    "plan_url": "https://app.bluebricks.co/plan/2a151a4b-874b-46d8-8f34-a803c80a69fe",
  },
  "collection": {
    "id": "4145de0d-bfc4-4df9-a067-c6f06d8f4fb0",
    "slug": "staging-us",
    "name": "Staging Env / US",
    "created_at": "2025-02-04T14:36:57.960Z"
  },
  "organization": {
    "id": "org_e5Oh1aexw4OUDZmd",
    "slug": "Bluebricks",
    "name": "bluebricks"
  }
}
```

<figure><img src="/files/YW4Y1O9olKl4OSjYj9gW" alt=""><figcaption></figcaption></figure>


# Best Practices

Best practices for using Git repositories as the primary driver for infrastructure modifications with Bluebricks

This document outlines Bluebricks' best practices for using Git repositories as the primary driver for infrastructure modifications.

Since workflows vary between teams and serve different goals, the recommended Bluebricks workflow emphasizes key capabilities needed to manage infrastructure at scale, including:

* **Version Control & Change Management**: Ensuring traceability and rollback capabilities.
* **Collaboration & Review Processes**: Leveraging Git-based approvals for controlled environments.
* **Automation & CI/CD Integration**: Enforcing consistency through automated pipelines.
* **Security & Compliance**: Embedding policies and audits within infrastructure changes.

## Core Principles

Bluebricks **Git best practices** follow three core principles:

1. **Separation of Concerns**: Maintain distinct directories for business logic ("Blueprints"), reusable components ("Artifacts"), and designed ("live") configurations.
2. **Industry Standards**: Use declarative file formats to simplify infrastructure management while ensuring Git as the source of truth and GitOps compatibility.

### Separation of Concerns

Bluebricks emphasizes [Separation of Concerns](https://www.wikiwand.com/en/articles/Separation_of_concerns) (SoC) in infrastructure development, enabling independent development of each distinct part of the code while ensuring unified execution. This approach enhances flexibility, leading to advanced automation and streamlined operations.

SoC aligns with 2 out of the 5 [SOLID principles](https://www.wikiwand.com/en/articles/SOLID) ([SRP](https://www.wikiwand.com/en/articles/Single-responsibility_principle) and [ISP](https://www.wikiwand.com/en/articles/Interface_segregation_principle)), helping to prevent [tight coupling](https://www.wikiwand.com/en/articles/Coupling_\(computer_programming\)#Disadvantages_of_tight_coupling) and reducing the blast radius in case of errors.

By following SoC, code is easier to update and extend, workflows scale efficiently, and repetitive cloud tasks can be automated earlier in the development cycle.

This results in greater resilience, efficiency, and scalability in cloud infrastructure management.

#### Bluebricks Development Life Cycles

To ensure Due to Separation of Concerns (SoC), Bluebricks recommends maintaining two distinct life cycles for infrastructure code management:

1. [**Code Lifecycle**](/docs/orchestration/bluebricks-git-repository-guide/managing-infrastructure-as-code-on-git): Manages reusable infrastructure components (e.g., Blueprints and Artifacts) sourced from any Infrastructure-as-Code (IaC) language such as Terraform, Helm, OpenTofu, CloudFormation, and more.
2. [**Configuration Lifecycle**](/docs/orchestration/bluebricks-git-repository-guide/managing-configuration-on-git): Manages the values provided to Blueprints and Artifacts for a specific environment.

Preserving the two life cycles **enhances scalability and reusability**.

* For example, a VPC module can be reused across different environments (e.g., staging, production) without modifying other resources.
* Teams can standardize best practices across multiple environments without duplicating code.

It also increases **Security and Compliance**:

* Security policies can be defined at the code level, preventing configurations from introducing vulnerabilities during environment run.
* Security and compliance scans can be performed once at the code level, ensuring a secure infrastructure while reducing the need for repetitive scans.

Lastly, it facilitates collaboration and unlocks workflow bottlenecks; In DevOps, platform engineering, and SRE teams, different groups often manage different aspects of infrastructure. SoC ensures clear boundaries, making it easier for teams to collaborate without stepping on each other’s changes.

## Bricks Action

Bricks Action is a GitHub Action implementation that enforces Bluebricks' Separation of Concerns (SoC) concept for infrastructure management.

Bricks Action aligns with the discussed Code and Configuration Lifecycles and is responsible for the following actions:

**Code Lifecycle**

1. Updating Artifact and Blueprint versions
2. Resolving dependencies and updating versioning accordingly
3. Publishing the updated Artifact and Blueprint

**Configuration Lifecycle**

1. Initiate environments over pull requests or merges

## Getting Started with Bricks Action

Follow these steps to set up your Git-based workflow with Bricks Action:

1. [Create Repository Folder Structure Following Bluebricks Guide](/docs/orchestration/bluebricks-git-repository-guide/git-repository-folder-structure)
2. [Configure your first Github Action Workflow using Bricks Action](/docs/orchestration/bluebricks-git-repository-guide/getting-started-with-bricks-action)
3. [Setup Workflow for Blueprints and Artifacts Update Automation](/docs/orchestration/bluebricks-git-repository-guide/managing-infrastructure-as-code-on-git)
4. [Shift-Left Blueprint Environment using Github Workflows](/docs/orchestration/bluebricks-git-repository-guide/managing-configuration-on-git)


# Git Repository Folder Structure

Recommended folder structure for managing Bluebricks artifacts, blueprints, and environment configurations in a Git repository

The following Git repository folder structure represents Bluebricks' best practice for managing infrastructure development using [Separation of Concerns (SoC)](/docs/orchestration/bluebricks-git-repository-guide#separation-of-concerns) principles.

```
.
├── bluebricks/                          # Bluebricks specific files
│   ├── blueprints/                      # Business logic implementations
│   │   ├── <blueprint_name>/
│   │   │   ├── bricks.json              # Blueprint definition
│   │   └── ...
│   ├── artifacts/                       # Reusable components
│   │   ├── <artifact_name>/
│   │   │   ├── bricks.json              # Artifact definition (metadata, dependencies, etc.)
│   │   │   ├── src/                     # Source code (e.g., Terraform, Helm charts, CloudFormation Stacks)
│   │   │   │   └── terraform/
│   │   │   │       ├── main.tf
│   │   │   │       ├── outputs.tf
│   │   │   │       └── variables.tf
│   │   └── ...
│   ├── environments/                    # Encapsulating folder for environment configuration 
│   │   ├── dev/
│   │   │   ├── <environment_name>.yaml   # Environment declarative file 
│   │   │   └── ...
│   │   ├── staging/
│   │   │   ├── <environment_name>.yaml   # Environment declarative file 
│   │   │   └── ...
│   │   ├── prod/
│   │   │   ├── <environment_name>.yaml   # Environment declarative file 
│   │   │   └── ...
```

## Explanation of Key Directories

* **`bluebricks/blueprints/`:** Contains the blueprints that define specific infrastructure or application environments. Each blueprint has its own directory and a `bricks.json` file defining its composition.
  * **`bricks.json` (Blueprint):** Defines the blueprint's name, description, version, and the Artifacts it uses.
* **`bluebricks/artifacts/`:** Contains reusable Artifacts that can be used across multiple blueprints. Each package has its own directory and a `bricks.json` file.
  * **`bricks.json` (Artifact):** Defines the package's metadata (name, description, version), dependencies on other artifacts, and any configurable properties.
  * **`src/`:** Contains the implementation of the package, typically using Infrastructure-as-Code tools like Terraform or Helm.
* **`environments/`:** Contains environment-specific configurations and manifests for deploying blueprints. This directory is used for GitOps pull-based environments to different environments.
  * **`<environment_name>.yaml`:** Declarative file for managing the configuration fed by a environment.

### `bricks.json` Structure (Examples)

Terraform AWS Launch Template Artifact:

`bluebricks/artifacts/terraform-aws-launch-template/bricks.json`

```
{
  "name": "terraform_aws_launch_template",
  "description": "Creates an AWS Launch Template.",
  "version": "1.2.0",
  "native": {
    "type": "terraform",
    "path": "./src/terraform"
  },
  "props": { /* ... */ },
  "outs": { /* ... */ }
}
```

AWS Launch Template Blueprint:

`bluebricks/blueprints/launch_template_s3/bricks.json`

```
{
  "name": "@bluebricks/launch_template_s3",
  "description": "EC2 Launch Template and S3 bucket.",
  "version": "1.2.0",
  "packages": [
    {
      "name": "random_output",
      "version": "1.0.4",
      "props": { /* ... */ }
    },
    {
      "name": "terraform_aws_launch_template",
      "version": "1.2.0", // Explicitly specifying the desired version
      "props": { /* ... */ }
    },
    {
      "name": "terraform_aws_s3_new",
      "version": "1.0.1",
      "props": { /* ... */ }
    }
  ],
  "props": { /* ... */ },
  "outs": { /* ... */ }
}
```


# Getting Started with Bricks Action

Set up the Bricks GitHub Action to run CLI commands in GitHub workflows for automated version bumping, publishing, and deployment

Bricks Action makes [Bricks CLI](/docs/bricks-cli/bricks-cli) accessible through [GitHub Actions](https://github.com/features/actions), allowing DevOps teams to run any Bricks CLI command directly within their workflows. It seamlessly automates tasks such as:

* Version bumping (`bricks bp bump`)
* Blueprint and Artifact updates and publishing (`bricks bp update`)
* Blueprint installation and uninstall (`bricks install/uninstall`)

{% hint style="info" %}
For the full list of available bricks CLI commands, please see the [bricks CLI Commands Reference](broken://pages/NlU8bDKW2TUici1gVVoA).
{% endhint %}

By integrating Bricks Action, teams can streamline CI/CD processes, ensuring efficient, automated, and scalable infrastructure management.

## Getting Started

Integrate **bricks CLI** with your **GitHub CI/CD** by following the instructions in the **bricks-action** repository on **GitHub** 🔗 <https://github.com/bluebricks-co/bricks-action>

### Prerequisites

1. **Bricks API Key**
   * **Requirement:** A valid Bluebricks Long-Lived Token (API key) is required to authenticate with the bricks service and perform version bumps, blueprint updates, and publishing operations.
   * **How to Generate:** Follow the steps outlined in the [official Bluebricks documentation](https://bluebricks.co/docs/api/authenticate/authentication).
   * **Tip:** Store your API key securely in your GitHub repository secrets as `BRICKS_API_KEY`.
2. **GitHub Token**
   * **Requirement:** The action leverages GitHub's built-in `GITHUB_TOKEN` to perform Git operations such as commits and pushes.
   * **Setup:** Ensure that your workflow has the necessary permissions (e.g., `contents: write`, `pull-requests: write`).
3. **Repository Organization**
   * Structure your repository with designated directories for artifacts and blueprints (e.g., `bluebricks/artifacts` and `bluebricks/blueprints`).
   * Prepare a Bricks configuration file (e.g., `config-dev.yaml`) with your project-specific settings.

### Usages

Bricks Action does not include built-in workflows and must be implemented based on specific use-case requirements. Below is an example of how to integrate Bricks Action within a GitHub Actions workflow:

```
name: 'Update Artifacts and Blueprints'

on:
  pull_request:
    types: [opened, synchronize, reopened]
  pull_request_review:
    types: [submitted]

permissions:
  id-token: write
  contents: write
  pull-requests: write

jobs:
  updateci:
    runs-on: ubuntu-latest
    if: |
      (github.event_name == 'pull_request') ||
      (github.event_name == 'pull_request_review' && github.event.review.state == 'approved')

    steps:
      - name: Checkout code
        uses: actions/checkout@v4
        with:
          fetch-depth: 0
          persist-credentials: false
          ref: ${{ github.event.pull_request.head.ref }} # This is the PR branch

      - name: Run updateci Command
        uses: bluebricks-co/bricks-action@main
        with:
          command: 'updateci'
          artifacts-folder: 'bluebricks/packages'
          blueprints-folder: 'bluebricks/blueprints'
          artifact-bump: 'patch'
          blueprint-bump: 'patch'
          base: 'origin/master'
          api-key: ${{ secrets.BRICKS_API_KEY }}
          config-file: ${{ github.workspace }}/config-dev.yaml
          flags: ${{ github.event_name == 'pull_request' && '--dry' || '' }}
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
```

## Next Steps

1. [Implement Code Lifecycle Workflow using Bricks Action](/docs/orchestration/bluebricks-git-repository-guide/managing-infrastructure-as-code-on-git)
2. [Implement Configuration Lifecycle Workflow using Bricks Action](/docs/orchestration/bluebricks-git-repository-guide/managing-configuration-on-git)


# Managing Infrastructure-as-Code on Git

Automate blueprint version bumping, publishing, and updates through Git-based CI workflows using Bricks Action

By integrating with Bricks Action, teams can automate Blueprint management commands (such as `bp bump` and `bp publish`) to the CI workflow, allowing them to **focus on coding modules** while optimizing collaboration and automation.

Bluebricks recommends triggering the `updateci` command when a Pull Request (PR) is opened and approved or when a Git tag is assigned (e.g., for versioning).

## Recommended Workflow Described

Below is a suggested opinionated workflow that can be modified according to the team's needs:

1. Each PR Open event creates a dependency validation and preview changes which are being added to the PR as a comment
2. On PR Approve event, Bircks Action will bump versions, update the blueprints and publish recursively
3. Once the publish is completed, Bricks Action will update the PR with another commit, including the new versions.
4. On a merge event, Bricks Action won't take any action.

<figure><img src="/files/O70pYdrntoCaBGDIfAUy" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
**Attention:** The `updateci` command **automatically commits version updates** once the **Blueprint/Artifact is published**.

This ensures that:\
✅ **Version changes are tracked** in Git.\
✅ **Consistency is maintained** across CI/CD workflows.\
✅ **Automation remains seamless** without manual intervention.

Teams can integrate `updateci` into their **CI/CD pipelines** to streamline **Blueprint versioning and publishing**. 🚀
{% endhint %}

## Action File Example

```
name: 'Update Artifacts and Blueprints'

on:
  pull_request:
    types: [opened, synchronize, reopened]
  pull_request_review:
    types: [submitted]

permissions:
  id-token: write
  contents: write
  pull-requests: write

jobs:
  updateci:
    runs-on: ubuntu-latest
    if: |
      (github.event_name == 'pull_request') ||
      (github.event_name == 'pull_request_review' && github.event.review.state == 'approved')

    steps:
      - name: Checkout code
        uses: actions/checkout@v4
        with:
          fetch-depth: 0
          persist-credentials: false
          ref: ${{ github.event.pull_request.head.ref }} # This is the PR branch

      - name: Run updateci Command
        uses: bluebricks-co/bricks-action@main
        with:
          command: 'updateci'
          artifacts-folder: 'bluebricks/packages'
          blueprints-folder: 'bluebricks/blueprints'
          artifact-bump: 'patch'
          blueprint-bump: 'patch'
          base: 'origin/master'
          api-key: ${{ secrets.BRICKS_API_KEY }}
          config-file: ${{ github.workspace }}/config-dev.yaml
          flags: ${{ github.event_name == 'pull_request' && '--dry' || '' }}
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
```

<figure><img src="/files/b3xashzzg1sUhFkmROQC" alt=""><figcaption><p>Example of a run workflow</p></figcaption></figure>

<figure><img src="/files/Cei2yhlheCkTI0xfHCyC" alt=""><figcaption></figcaption></figure>


# Managing Configuration on Git

Use declarative environment files and PR-based workflows to manage infrastructure provisioning through Git with Bricks Action

By integrating with Bricks Action, teams can "shift-left" infrastructure provisioning and maintain PR-based workflows, leveraging developer-friendly and GitOps-compatible declarative files.

## Recommended Workflow Described

Below is a suggested opinionated workflow that can be modified according to the team's needs.

1. Developers leverage side branches to provision their infrastructure. Each commit triggers a environment to a developer-owned environment
2. Once the changes are ready, the engineer opens a Pull Request (PR) to promote the change for review and obtain approval before merging and deploying to shared environments.
3. Once the Pull Request (PR) is approved, the engineer merges its code and waits for the next release day.
4. On the release day, the DevOps team should trigger a workflow that detects the recent changes and creates a batch environment.

<figure><img src="/files/DZjIuZUjacJzcwt8Jvgx" alt=""><figcaption></figcaption></figure>

### Batch Environments

Bluebricks recommends aligning infrastructure modifications with the primary SDLC.

On release day, the Delivery team manually triggers or automates a workflow using a ticketing system; the GitHub Action Workflow should collect the recent changes and trigger installation for each.

This approach ensures:

1. Synchronized application and infrastructure releases.
2. Controlled, predictable, and repeatable environments.
3. Automation-driven efficiency with minimal manual intervention.

### Github Action Workflow Example

```
name: Bricks Matrix Environment Workflow

on:
  pull_request:
    branches: [master]
    paths:
      - 'bluebricks/collections/**'
  push:
    branches:
      - master
      - feature/inf-273/environments
    paths:
      - 'bluebricks/collections/**'
  workflow_dispatch:
    inputs:
      plan_only:
        description: 'Generate plan only without deploying'
        required: true
        default: true
        type: boolean

jobs:
  # Detect changes in environments folder and prepare matrix
  changes:
    runs-on: ubuntu-latest
    outputs:
      matrix: ${{ steps.set-matrix.outputs.matrix }}
      any_changes: ${{ steps.set-matrix.outputs.any_changes }}
    steps:
      - name: Checkout code
        uses: actions/checkout@v4
        with:
          fetch-depth: 0  # Fetch all history for detecting changes

      - name: Get changed files
        id: changed-files
        # For PRs use git diff, for manual runs find all YAML files
        run: |
          if [[ "${{ github.event_name }}" == "pull_request" ]]; then
            # Get changed files in PR
            CHANGED_FILES=$(git diff --name-only ${{ github.event.pull_request.base.sha }} ${{ github.sha }} -- bluebricks/environments/ | grep -v values.yaml | grep -E '\.ya?ml$' || echo "")
          else
            # For workflow_dispatch, consider all YAML files
            CHANGED_FILES=$(find bluebricks/environments -type f \( -name "*.yaml" -o -name "*.yml" \) ! -name "values.yaml" | sort)
          fi
          echo "Files to process:"
          echo "$CHANGED_FILES"
          {
            echo "CHANGED_FILES<<EOF"
            echo "$CHANGED_FILES"
            echo "EOF"
          } >> "$GITHUB_ENV"

      - name: Set matrix
        id: set-matrix
        run: |
          # Convert changed files to JSON array format
          if [[ -z "$CHANGED_FILES" ]]; then
            echo "No environment files changed"
            echo "matrix=[]" >> $GITHUB_OUTPUT
            echo "any_changes=false" >> $GITHUB_OUTPUT
          else
            # Convert space separated file list to JSON array
            FILES_JSON=$(echo "$CHANGED_FILES" | jq -R -s -c 'split("\n") | map(select(length > 0))')
            echo "matrix=${FILES_JSON}" >> $GITHUB_OUTPUT
            echo "any_changes=true" >> $GITHUB_OUTPUT
          fi

  # Create environment plans for all changed files
  bricks-plan:
    needs: changes
    if: needs.changes.outputs.any_changes == 'true'
    runs-on: ubuntu-latest
    strategy:
      matrix:
        file: ${{ fromJson(needs.changes.outputs.matrix) }}
      # Allow other environments to continue even if one fails
      fail-fast: false
      # Limit parallel executions to avoid rate limiting
      max-parallel: 5
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Extract environment name
        id: extract-name
        run: |
          # Extract environment name from file path for use in job display
          FILENAME=$(basename "${{ matrix.file }}")
          ENVIRONMENT_NAME=${FILENAME%.*}  # Remove extension
          echo "name=$ENVIRONMENT_NAME" >> $GITHUB_OUTPUT

      - name: Create Bricks environment plan (${{ steps.extract-name.outputs.name }})
        uses: bluebricks-co/bricks-action@support-for-install-flow
        with:
          command: install
          file: ${{ matrix.file }}
          # env: ${{ github.event.inputs.environment || 'staging' }}
          plan-only: ${{ github.event.inputs.plan_only || 'true' }}
          api-key: ${{ secrets.BRICKS_API_KEY }}

  # Deploy if workflow_dispatch and plan_only is false
  bricks-deploy:
    needs: [changes, bricks-plan]
    if: |
      needs.changes.outputs.any_changes == 'true' && 
      github.event_name == 'workflow_dispatch' && 
      github.event.inputs.plan_only == 'false'
    runs-on: ubuntu-latest
    strategy:
      matrix:
        file: ${{ fromJson(needs.changes.outputs.matrix) }}
      fail-fast: false
      max-parallel: 3
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Extract environment name
        id: extract-name
        run: |
          FILENAME=$(basename "${{ matrix.file }}")
          ENVIRONMENT_NAME=${FILENAME%.*}
          echo "name=$ENVIRONMENT_NAME" >> $GITHUB_OUTPUT

      - name: Execute Bricks environment (${{ steps.extract-name.outputs.name }})
        uses: bluebricks-co/bricks-action@support-for-install-flow
        with:
          command: install
          file: ${{ matrix.file }}
          api-key: ${{ secrets.BRICKS_API_KEY }}

  summary:
    needs: [changes, bricks-plan]
    if: always() && needs.changes.outputs.any_changes == 'true'
    runs-on: ubuntu-latest
    steps:
      - name: Environment Summary
        run: |
          echo "### Environment Summary" >> $GITHUB_STEP_SUMMARY
          echo "" >> $GITHUB_STEP_SUMMARY
          echo "Processed Environment files:" >> $GITHUB_STEP_SUMMARY
          
          # Use a more reliable approach that avoids complex JSON parsing
          matrix='${{ needs.changes.outputs.matrix }}'
          # Method 1: Simple approach that works even if JSON is malformed
          echo "$matrix" | grep -o '"[^"]*"' | sed 's/"//g' | while read file; do
            echo "- $file" >> $GITHUB_STEP_SUMMARY
          done
          
          # Method 2 (Fallback): If nothing was listed above
          if ! grep -q "^-" $GITHUB_STEP_SUMMARY; then
            echo "- No files were processed or could not parse file list" >> $GITHUB_STEP_SUMMARY
          fi
```


# Day 2 Operations

Update deployed infrastructure by changing blueprint inputs and re-running environments in Bluebricks

After you deploy an [environment](/docs/orchestration/environments), your infrastructure needs change. These post-deployment changes are commonly called Day 2 operations. It refers to everything you do to a running environment after the initial provisioning, from scaling compute to adjusting storage to reconfiguring clusters.

{% hint style="success" %}
**Ask the agent.** Make Day 2 changes through conversation, from scaling resources to updating configurations. See [Agent Overview](/docs/agent/agents-overview).
{% endhint %}

## How Day 2 changes work in Bluebricks

Every environment in Bluebricks is backed by a [blueprint](/docs/orchestration/packages/blueprints-overview) that declares the desired state of your infrastructure. When you need to change a deployed resource, you update the relevant [input values](/docs/orchestration/packages/inputs-and-outputs#how-inputs-get-their-values) and start a new run. Bluebricks generates a plan that shows exactly what will change, and applies only the difference.

The core workflow is:

1. **Identify the input to change** in the blueprint (e.g., `vm_size`, `disk_size_gb`, `node_count`)
2. **Update the input value** in your Git-managed manifest, through the Bluebricks app, or via the CLI
3. **Push the change** (Git) or **start a new run** (app/CLI) to generate a plan and apply the change
4. **Verify the result** in the run logs and your cloud provider console

{% hint style="info" %}
Bluebricks does not modify resources directly. It updates the IaC configuration and delegates execution to the underlying engine (Terraform, Helm, CloudFormation, Bicep). The cloud provider determines how each change is applied, whether in-place or via replacement.
{% endhint %}

## Targeting an existing environment

If your environment is connected to a Git repository through [GitOps environments](/docs/orchestration/environments/gitops-environments), update the input values in your source code or manifest file and push the change. Bluebricks detects the update, generates a plan, and applies it automatically. Pull requests trigger a plan-only run so you can review the impact before merging. See [Managing Configuration on Git](/docs/orchestration/bluebricks-git-repository-guide/managing-configuration-on-git) for details on the manifest file format.

You can also target an existing environment through the Bluebricks app or CLI. In the app, select the environment from the **Environments** page and click **Deploy**. In the CLI, use the `--env-slug` flag to target the correct environment:

```bash
bricks install web-stack --collection=production --env-slug=web-stack-prod
```

## What happens at the cloud provider level

When Bluebricks applies a change, the underlying IaC engine translates input changes into cloud API calls. The behavior depends on the resource type and cloud provider:

* **In-place updates**: most compute and configuration changes (VM size, node count, scaling settings) are applied without replacing the resource
* **Replace (destroy + recreate)**: some changes require a full resource replacement (e.g., changing a disk type that the provider does not support modifying in-place)
* **No-op**: if the new input values match the current state, the plan shows no changes

The run plan always shows the exact operations before they execute, so you can review whether a change is in-place or requires replacement.

{% hint style="warning" %}
Some changes cause downtime. Review the plan output carefully, especially for production environments. If a resource shows `destroy` then `create`, expect a brief interruption.
{% endhint %}


# Scaling Compute Resources

Update CPU, memory, and VM sizes for deployed workloads by changing blueprint inputs and re-running environments

## Overview

Scaling compute resources (CPU, memory, VM size) is one of the most common [Day 2 operations](/docs/managing-infrastructure/managing-infrastructure). In Bluebricks, you change the relevant [blueprint](/docs/orchestration/packages/blueprints-overview) input values and start a new run of the [environment](/docs/orchestration/environments). The underlying IaC engine handles the cloud provider API calls to resize or reconfigure your resources.

{% hint style="success" %}
**Ask the agent.** Scale resources directly, for example: "Scale the EKS cluster in prod-eu to 5 nodes." See [Agent Overview](/docs/agent/agents-overview).
{% endhint %}

## Prerequisites

* An existing [environment](/docs/orchestration/environments) with a completed run
* The blueprint exposes inputs for the compute properties you want to change (e.g., `vm_size`, `instance_type`, `cpu_cores`, `memory_gb`)
* Access to the [collection](/docs/orchestration/collections) that the environment belongs to

## How to scale compute resources

{% tabs %}
{% tab title="Git" %}
Update the compute-related input in your environment manifest file and push the change. If you use [GitOps environments](/docs/orchestration/environments/gitops-environments), Bluebricks triggers a plan automatically. For PR-based workflows, the plan posts to your pull request for review before merging.

```yaml
# environment manifest (e.g., web-app-prod.yaml)
inputs:
  vm_size: "Standard_D4s_v3"
```

See [Managing Configuration on Git](/docs/orchestration/bluebricks-git-repository-guide/managing-configuration-on-git) for the full manifest format.
{% endtab %}

{% tab title="Bluebricks app" %}

1. Open the **Environments** page and go to the environment you want to update
2. In the three-dot menu click **Deploy**
3. Update the compute-related input values (e.g., change `vm_size` from `Standard_D2s_v3` to `Standard_D4s_v3`)
4. Review the plan to confirm the change is in-place
5. Click **Deploy**
   {% endtab %}

{% tab title="CLI" %}
Pass the updated input values using `--props` or `--props-file`:

```bash
bricks install web-app \
  --collection=production \
  --env-slug=web-app-prod \
  --props '{"vm_size": "Standard_D4s_v3"}'
```

Or use a properties file:

```bash
bricks install web-app \
  --collection=production \
  --env-slug=web-app-prod \
  --props-file=./updated-props.json
```

Add `--plan-only` first to preview the change without applying it:

```bash
bricks install web-app \
  --collection=production \
  --env-slug=web-app-prod \
  --props '{"vm_size": "Standard_D4s_v3"}' \
  --plan-only
```

{% endtab %}
{% endtabs %}

## Common compute changes

### Increase CPU or memory

Most cloud providers bundle CPU and memory into instance or VM sizes. To scale up, change the VM size input to a larger tier:

<table><thead><tr><th width="148.8359375">Cloud provider</th><th width="173.1484375">Typical input</th><th>Example change</th></tr></thead><tbody><tr><td>Azure</td><td><code>vm_size</code></td><td><code>Standard_D2s_v3</code> to <code>Standard_D4s_v3</code></td></tr><tr><td>AWS</td><td><code>instance_type</code></td><td><code>t3.medium</code> to <code>t3.xlarge</code></td></tr><tr><td>GCP</td><td><code>machine_type</code></td><td><code>e2-medium</code> to <code>e2-standard-4</code></td></tr></tbody></table>

{% hint style="info" %}
The exact input name depends on how the blueprint author defined the inputs. Check the blueprint's input definitions using `bricks blueprint describe <blueprint>` or in the Bluebricks app under the blueprint details page.
{% endhint %}

### Change VM series or family

Switching between VM families (e.g., from general-purpose to compute-optimized) follows the same workflow. Update the VM size input to the new family:

```bash
bricks install web-app \
  --collection=production \
  --env-slug=web-app-prod \
  --props '{"vm_size": "Standard_F4s_v2"}'
```

{% hint style="warning" %}
Changing VM families may cause a brief restart. The plan output indicates whether the change is in-place or requires replacement. Review it before approving.
{% endhint %}

## Cloud provider behavior

How a compute change is applied depends on the cloud provider. Most resize operations require a brief stop/start cycle but preserve attached storage and network configuration.

<details>

<summary>Azure</summary>

* VM resizing is typically in-place. Azure stops the VM, resizes it, and restarts it. Expect a brief interruption.
* Not all VM sizes are available in every region. Check [Azure VM sizes](https://learn.microsoft.com/en-us/azure/virtual-machines/sizes) for availability.
* Switching between VM families (e.g., D-series to F-series) is in-place but may take longer due to hardware reallocation.

</details>

<details>

<summary>AWS</summary>

* EC2 instance type changes require a stop/start cycle. The instance retains its private IP and attached EBS volumes.
* Changing instance families (e.g., `t3` to `c6i`) follows the same stop/start pattern but may fail if the new type is not available in the current Availability Zone.
* For Auto Scaling Groups, the launch template updates immediately but existing instances retain their current type until replaced by a scaling event or instance refresh.

</details>

<details>

<summary>GCP</summary>

* Machine type changes require a VM stop/start. Persistent disks remain attached.
* Custom machine types allow independent CPU and memory scaling.
* Switching between machine families (e.g., `e2` to `n2`) follows the same stop/start workflow.

</details>

## What to check after scaling

1. **Run status**: confirm the run completed successfully in the environment's run history
2. **Resource state**: verify the new compute configuration in your cloud provider console
3. **Application health**: check that your workloads are running correctly after the resize
4. **Drift detection**: if [drift detection](/docs/orchestration/environments/drift-detection) is enabled, the next check should show no drift


# Managing Storage

Resize disks, change disk types, and manage storage for deployed environments by updating blueprint inputs

## Overview

Storage changes include resizing disks, changing disk types, and adding new volumes. Like other [Day 2 operations](/docs/managing-infrastructure/managing-infrastructure), you update the relevant [blueprint](/docs/orchestration/packages/blueprints-overview) inputs and start a new run of the environment. However, storage changes have important constraints: some modifications are in-place, while others require resource replacement.

## Prerequisites

* An existing [environment](/docs/orchestration/environments) with a completed run
* The blueprint exposes inputs for storage properties (e.g., `disk_size_gb`, `storage_type`, `disk_sku`)
* Access to the [collection](/docs/orchestration/collections) that the environment belongs to

## How to update storage

{% tabs %}
{% tab title="Git" %}
Update the storage-related input in your environment manifest file and push the change. If you use [GitOps environments](/docs/orchestration/environments/gitops-environments), Bluebricks triggers a plan automatically. Review the plan carefully for any `destroy` + `create` operations before merging.

```yaml
# environment manifest (e.g., data-layer-prod.yaml)
inputs:
  disk_size_gb: 256
```

See [Managing Configuration on Git](/docs/orchestration/bluebricks-git-repository-guide/managing-configuration-on-git) for the full manifest format.
{% endtab %}

{% tab title="Bluebricks app" %}

1. Open the **Environments** page and go to the environment you want to update
2. In the three-dot menu click **Deploy**
3. Update the storage-related input values (e.g., change `disk_size_gb` from `128` to `256`)
4. Review the plan carefully for any `destroy` + `create` operations
5. Click **Deploy**
   {% endtab %}

{% tab title="CLI" %}

```bash
bricks install data-layer \
  --collection=production \
  --env-slug=data-layer-prod \
  --props '{"disk_size_gb": 256}'
```

Always preview first with `--plan-only`:

```bash
bricks install data-layer \
  --collection=production \
  --env-slug=data-layer-prod \
  --props '{"disk_size_gb": 256}' \
  --plan-only
```

{% endtab %}
{% endtabs %}

## Common storage changes

### Increase disk size

Increasing disk size is generally safe and applied in-place by most cloud providers. The underlying volume expands without data loss.

<table><thead><tr><th width="150.98046875">Cloud provider</th><th width="183.51171875">Typical input</th><th>Example change</th></tr></thead><tbody><tr><td>Azure</td><td><code>disk_size_gb</code></td><td><code>128</code> to <code>256</code></td></tr><tr><td>AWS</td><td><code>volume_size</code></td><td><code>100</code> to <code>200</code></td></tr><tr><td>GCP</td><td><code>disk_size_gb</code></td><td><code>50</code> to <code>100</code></td></tr></tbody></table>

{% hint style="info" %}
Disk size can only be increased, not decreased. If you need a smaller disk, you must create a new volume and migrate data.
{% endhint %}

### Change disk type

Switching between disk performance tiers (e.g., Standard HDD to Premium SSD) changes the IOPS and throughput profile of the volume.

```bash
bricks install data-layer \
  --collection=production \
  --env-slug=data-layer-prod \
  --props '{"storage_account_type": "Premium_LRS"}'
```

{% hint style="warning" %}
Some disk type changes require resource replacement depending on the cloud provider and IaC resource definition. Always run with `--plan-only` first and check whether the plan shows an in-place update or a destroy/create cycle.
{% endhint %}

### Add additional volumes

If the blueprint supports multiple volumes (e.g., a `data_disks` list input), you can add new disks by updating the input:

```bash
bricks install data-layer \
  --collection=production \
  --env-slug=data-layer-prod \
  --props-file=./storage-config.json
```

<details>

<summary>Example storage-config.json</summary>

```json
{
  "data_disks": [
    { "name": "data-01", "size_gb": 256, "type": "Premium_LRS" },
    { "name": "data-02", "size_gb": 512, "type": "Premium_LRS" }
  ]
}
```

</details>

## Constraints and caveats

Storage changes carry more risk than compute scaling because they can involve data. Keep these constraints in mind:

* **Shrinking disks is not supported** by most cloud providers. You must create a new volume and migrate data manually
* **Disk type changes may require replacement**: if the IaC resource does not support in-place type changes, the plan will show a destroy + create cycle. This means data loss unless you have backups
* **OS disks vs data disks**: changing the OS disk often requires VM replacement. Data disk changes are usually independent
* **Filesystem expansion**: increasing disk size at the cloud layer does not automatically expand the filesystem. Your application or startup scripts must handle partition and filesystem resizing

{% hint style="danger" %}
If the plan shows a `destroy` operation on a storage resource, stop and verify that you have backups before proceeding. Destroyed disks cannot be recovered.
{% endhint %}

## Cloud provider behavior

Storage change behavior varies by provider. Size increases are generally safe and online, but type changes and shrinking have significant constraints.

<details>

<summary>Azure Managed Disks</summary>

* Disk size increases are in-place but may require the VM to be deallocated
* Changing between Standard HDD, Standard SSD, and Premium SSD is supported in-place for most configurations
* Ultra Disk changes have additional constraints around availability zones

</details>

<details>

<summary>AWS EBS</summary>

* Volume size increases are applied online (no downtime) for most volume types
* Volume type changes (e.g., `gp2` to `gp3`) are applied in-place
* IOPS and throughput modifications for `gp3` and `io1`/`io2` volumes are in-place
* After resizing, the OS must extend the filesystem (`resize2fs` or `xfs_growfs`)

</details>

<details>

<summary>GCP Persistent Disks</summary>

* Disk size increases are online and do not require VM downtime
* Switching between `pd-standard`, `pd-balanced`, and `pd-ssd` requires creating a new disk
* Regional persistent disks have additional replication constraints

</details>

## What to check after storage changes

1. **Run status**: confirm the run completed successfully
2. **Disk state**: verify the new size and type in your cloud provider console
3. **Filesystem**: confirm the OS-level filesystem reflects the new disk size
4. **Application health**: check that databases and storage-dependent services are operating correctly
5. **Backups**: verify your backup schedule covers the updated volumes


# Scaling Kubernetes Clusters

Scale Kubernetes cluster nodes, add node pools, and configure autoscaling by updating blueprint inputs and re-running environments

## Overview

Scaling Kubernetes clusters involves adjusting node counts, adding node pools, or configuring autoscaler settings. In Bluebricks, these changes follow the standard Day 2 workflow: update the [blueprint](/docs/orchestration/packages/blueprints-overview) inputs that control your cluster configuration and start a new run of the [environment](/docs/orchestration/environments).

{% hint style="success" %}
**Ask the agent.** Scale your cluster directly, for example: "Add 3 nodes to the staging EKS node pool." See [Agent Overview](/docs/agent/agents-overview).
{% endhint %}

## Prerequisites

* An existing [environment](/docs/orchestration/environments) with a completed run that includes a Kubernetes cluster
* The blueprint exposes inputs for cluster configuration (e.g., `node_count`, `min_nodes`, `max_nodes`, `node_pool_vm_size`)
* Access to the [collection](/docs/orchestration/collections) that the environment belongs to

## How to scale a cluster

{% tabs %}
{% tab title="Git" %}
Update the cluster-related input in your environment manifest file and push the change. If you use [GitOps environments](/docs/orchestration/environments/gitops-environments), Bluebricks triggers a plan automatically. Review the plan to confirm the change scope before merging.

```yaml
# environment manifest (e.g., k8s-prod.yaml)
inputs:
  node_count: 5
```

See [Managing Configuration on Git](/docs/orchestration/bluebricks-git-repository-guide/managing-configuration-on-git) for the full manifest format.
{% endtab %}

{% tab title="Bluebricks app" %}

1. Open the **Environments** page and go to the environment you want to update
2. In the three-dot menu click **Deploy**
3. Update the cluster-related inputs (e.g., change `node_count` from `3` to `5`)
4. Review the plan to confirm the change scope
5. Click **Deploy**
   {% endtab %}

{% tab title="CLI" %}

```bash
bricks install k8s-platform \
  --collection=production \
  --env-slug=k8s-prod \
  --props '{"node_count": 5}'
```

Preview first:

```bash
bricks install k8s-platform \
  --collection=production \
  --env-slug=k8s-prod \
  --props '{"node_count": 5}' \
  --plan-only
```

{% endtab %}
{% endtabs %}

## Common cluster changes

### Scale node count up or down

Adjusting the number of nodes in an existing node pool is the most common cluster scaling operation. Update the node count input and start a new run:

```bash
bricks install k8s-platform \
  --collection=staging \
  --env-slug=k8s-staging \
  --props '{"node_count": 5}'
```

Scaling down removes nodes from the pool. Kubernetes drains workloads from the removed nodes and reschedules them on remaining nodes.

{% hint style="warning" %}
When scaling down, make sure the remaining nodes have enough capacity for your workloads. Kubernetes evicts pods from removed nodes, and pods without sufficient resources to reschedule will remain in a Pending state.
{% endhint %}

### Add a new node pool

If the blueprint supports multiple node pools (e.g., through a `node_pools` list input), add a new pool by updating the configuration:

```bash
bricks install k8s-platform \
  --collection=production \
  --env-slug=k8s-prod \
  --props-file=./cluster-config.json
```

<details>

<summary>Example cluster-config.json with multiple node pools</summary>

```json
{
  "node_pools": [
    {
      "name": "system",
      "vm_size": "Standard_D4s_v3",
      "node_count": 3,
      "mode": "System"
    },
    {
      "name": "workload",
      "vm_size": "Standard_D8s_v3",
      "node_count": 5,
      "mode": "User"
    },
    {
      "name": "gpu",
      "vm_size": "Standard_NC6s_v3",
      "node_count": 2,
      "mode": "User"
    }
  ]
}
```

</details>

{% hint style="info" %}
The exact input names, VM sizes, and pool configuration vary by cloud provider and how the blueprint author defined the inputs. The example above uses Azure-specific values for illustration.
{% endhint %}

### Configure autoscaling

Many Kubernetes blueprints expose autoscaler inputs. Update the minimum and maximum node counts to enable or adjust autoscaling:

```bash
bricks install k8s-platform \
  --collection=production \
  --env-slug=k8s-prod \
  --props '{"enable_autoscaler": true, "min_nodes": 3, "max_nodes": 10}'
```

When autoscaling is enabled, the cloud provider's cluster autoscaler manages node count within the defined range. Bluebricks sets the boundaries; the autoscaler handles the runtime scaling.

{% hint style="info" %}
Autoscaler settings are declarative. If the current node count is within the new min/max range, no immediate scaling occurs. The autoscaler adjusts capacity based on pod scheduling demand.
{% endhint %}

### Change node VM size

Changing the VM size of an existing node pool typically triggers a rolling replacement of nodes. The behavior varies by cloud provider:

```bash
bricks install k8s-platform \
  --collection=staging \
  --env-slug=k8s-staging \
  --props '{"node_pool_vm_size": "Standard_D8s_v3"}'
```

{% hint style="warning" %}
Changing the VM size of a node pool may cause the entire pool to be replaced. On Azure AKS, this requires creating a new node pool and draining the old one. Always run with `--plan-only` first to understand the impact.
{% endhint %}

## Cloud provider behavior

Node count changes are generally in-place across all providers. VM size changes on existing node pools typically require pool replacement.

<details>

<summary>Azure AKS</summary>

* Node count changes are applied in-place. AKS adds or removes nodes from the pool
* VM size changes require creating a new node pool and deleting the old one (the Terraform `azurerm_kubernetes_cluster_node_pool` resource forces replacement on `vm_size` change)
* Autoscaler configuration changes (`min_count`, `max_count`) are applied in-place
* System node pools require at least one node at all times

</details>

<details>

<summary>AWS EKS</summary>

* Managed node group scaling changes are applied in-place through the Auto Scaling Group
* Instance type changes in managed node groups trigger a rolling update (new nodes are created, old nodes are drained and terminated)
* Cluster autoscaler is deployed as a Helm chart, separate from the EKS node group configuration
* Fargate profiles do not use traditional node scaling

</details>

<details>

<summary>GCP GKE</summary>

* Node pool resize operations are in-place
* Machine type changes require creating a new node pool and migrating workloads
* GKE Autopilot manages node provisioning automatically; you configure resource requests instead of node counts
* Node auto-provisioning creates new node pools based on workload requirements

</details>

## Example: scaling for a traffic spike

A common scenario is scaling up before a known traffic event and scaling back down afterward.

**Baseline configuration** (normal traffic):

```json
{
  "node_pools": [
    { "name": "workload", "vm_size": "Standard_D4s_v3", "node_count": 5 }
  ]
}
```

**Scaled-up configuration** (Black Friday, product launch, etc.):

```json
{
  "node_pools": [
    { "name": "workload", "vm_size": "Standard_D4s_v3", "node_count": 12 }
  ]
}
```

```bash
bricks install k8s-platform \
  --collection=production \
  --env-slug=k8s-prod \
  --props '{"node_count": 12}'
```

After the event, restore the original value by starting a new run with `node_count` set back to `5`. For recurring events, consider using [Git-managed manifests](/docs/orchestration/bluebricks-git-repository-guide/managing-configuration-on-git) so each scaling change is tracked as a commit you can revert.

## What to check after cluster scaling

1. **Run status**: confirm the run completed successfully
2. **Node readiness**: verify all nodes are in `Ready` state (`kubectl get nodes`)
3. **Pod scheduling**: check for pods in `Pending` state that may need additional capacity
4. **Workload health**: confirm your applications are running and serving traffic
5. **Autoscaler status**: if autoscaling is enabled, verify the autoscaler is operating within the configured range


# Temporary Scaling

Scale infrastructure temporarily for testing or load evaluation, then revert or promote the change using Bluebricks environments

## Overview

Sometimes you need to scale infrastructure for a limited period: a load test, a proof of concept, or a short-term capacity increase. Bluebricks supports this through its standard [environment](/docs/orchestration/environments) workflow. Scale up by updating inputs and starting a new run, evaluate the result, then either revert to the original configuration or promote the change to other collections.

## When to use temporary scaling

* **Load testing**: increase compute or node count for a 2-7 day test, then revert
* **POC evaluation**: provision larger resources to validate a new workload, then decide whether to keep or discard
* **Seasonal demand**: scale up for a known traffic spike, then scale back down
* **Pre-production validation**: test a configuration change in staging before promoting to production

## The temporary scaling workflow

{% @mermaid/diagram content="flowchart LR
A\[Current state] --> B\[Update inputs]
B --> C\[Start new run]
C --> D\[Evaluate]
D -->|Keep| E\[Promote to production]
D -->|Revert| F\[Restore original inputs]
F --> G\[Start new run]" %}

{% stepper %}
{% step %}
**Record current input values**

Before making changes, note the current input values so you can revert later. You can find them in the environment's latest run details or in your Git-managed manifest file.

{% hint style="success" %}
If you use [Git-managed manifests](/docs/orchestration/bluebricks-git-repository-guide/managing-configuration-on-git), your current configuration is already versioned. You can revert by reverting the Git commit.
{% endhint %}
{% endstep %}

{% step %}
**Scale up**

Update the inputs and start a new run. If you use [GitOps environments](/docs/orchestration/environments/gitops-environments) or [Git-managed manifests](/docs/orchestration/bluebricks-git-repository-guide/managing-configuration-on-git), create a feature branch with the scaled-up configuration and push it:

```yaml
# environment manifest (e.g., k8s-staging.yaml)
inputs:
  node_count: 10
```

Bluebricks triggers a plan on the PR so you can review the change before merging. You can also scale up through the Bluebricks app or CLI:

```bash
bricks install k8s-platform \
  --collection=staging \
  --env-slug=k8s-staging \
  --props '{"node_count": 10}'
```

{% endstep %}

{% step %}
**Evaluate**

Run your load test, POC, or validation. Monitor resource usage, application performance, and cost.
{% endstep %}

{% step %}
**Decide: promote or revert**

**To promote the change** to another collection (e.g., staging to production), use the [promotion workflow](/docs/orchestration/runs/promoting-environments). Promotion copies the blueprint version and input values from one collection to another, then starts a new run in the target environment.

**To revert**, restore the original input values and start a new run. With Git, revert the commit or close the PR. With the CLI:

```bash
bricks install k8s-platform \
  --collection=staging \
  --env-slug=k8s-staging \
  --props '{"node_count": 5}'
```

{% endstep %}
{% endstepper %}

## Using Git for temporary changes

When using [Git-managed manifests](/docs/orchestration/bluebricks-git-repository-guide/managing-configuration-on-git) or [GitOps environments](/docs/orchestration/environments/gitops-environments), temporary scaling fits naturally into a branch-based workflow:

1. **Create a feature branch** with the scaled-up configuration
2. **Push the branch** to trigger a deployment to a development or staging environment
3. **Evaluate** the scaled configuration
4. **Merge to main** if you want to keep the change, or **close the PR** to discard it

This gives you a full audit trail of temporary changes and easy rollback through Git history.

## Combining with TTL for automatic cleanup

For environments that should only exist for a limited time, combine temporary scaling with [Time to Live (TTL)](/docs/orchestration/environments/environment-ttl). TTL schedules automatic uninstallation of the environment, so you do not need to remember to tear it down manually.

This is particularly useful for:

* **Dedicated test environments**: deploy a scaled-up environment for a load test, set a TTL to uninstall it after 3 days
* **Sandbox environments**: give engineers temporary access to larger resources with an automatic cleanup schedule
* **Cost control**: prevent temporarily scaled environments from running indefinitely

{% hint style="info" %}
TTL uninstalls the environment (destroys resources) but preserves the environment record and configuration. You can re-run it later if needed.
{% endhint %}

## Best practices

* **Always record baseline values** before scaling so you can revert precisely
* **Use `--plan-only`** before applying changes to preview the impact
* **Set a TTL** on temporary environments to avoid forgotten resources accumulating cost
* **Use separate collections** for temporary testing to isolate changes from production workloads. [Collection properties](/docs/orchestration/collections/properties) keep configuration consistent within each collection
* **Review cost implications** before scaling: larger VMs, more nodes, and premium storage tiers increase spend immediately
* **Promote only validated changes** to production. Use the [promotion workflow](/docs/orchestration/runs/promoting-environments) to carry forward proven configuration


# Bricks CLI Overview

Install and configure the bricks CLI for macOS, Linux, or Windows to manage collections, blueprints, and environments from the command line

Bluebricks command line, named `bricks`, enables engineers to engage with Bluebricks API using the command line interface.

`bricks` is suitable for CI/CD workflows and provides various functionalities such as collection setup and management, blueprint creation, and installation.

<figure><img src="/files/6FNxXEXrS6menTvV1i7c" alt=""><figcaption></figcaption></figure>

### Install `bricks` Command Line

{% tabs %}
{% tab title="macOS" %}
Install homebrew, open the terminal, and paste the below command:

```
brew install bluebricks-co/bricks/bricks
```

{% endtab %}

{% tab title="Linux and CI/CD Tools" %}
Open the terminal, and paste the below command:

```
/bin/bash -c "$(curl -fsSL https://brickscli.s3.eu-west-1.amazonaws.com/releases/latest/install.sh)"
```

{% endtab %}

{% tab title="Windows 11+" %}
Open the PowerShell, and paste the below command:

```
iwr -useb https://brickscli.s3.eu-west-1.amazonaws.com/releases/latest/install.ps1 | iex
```

{% endtab %}
{% endtabs %}

### Test your Installation

After installing, you can test your installation by running `bricks --help`.

Additionally, authenticate bricks CLI with your Bluebricks account, use `bricks login` , and then test your connectivity status by running `bricks whoami`.

### Configuration

The CLI allows external configuration. Discover how to adjust the runtime settings and accommodate various runtimes in the [Configuration Management](/docs/bricks-cli/configuration-management) article.

### CLI Reference

For the full list of commands, flags, and usage examples, see the [CLI Reference](/docs/bricks-cli/cli-reference).

### CLI Logging and Troubleshooting

The Bricks CLI logs its activity locally for debugging purposes and does not ship logs to a remote location. By default, the Bricks CLI logger is off and can be enabled using the `bricks logger enable` command.

Logs are written to the following path and are chunked into 2MB file sizes:

```
~/.bricks/bricks-cli.log
```

The severity level is set to "info" and cannot be changed.

Each command logs its activity to the file using the following scheme:

```
{
  "level": "info",
  "time": "2024-07-01T15:33:42+03:00",
  "message": ">>> starting bricks"
  ... // additional parameters, message specifics 
}
```


# CLI Authentication

Authenticate the bricks CLI with your Bluebricks account using browser-based login or long-lived tokens for CI/CD

Bricks CLI supports two authentication methods: **interactive login** for local development, and **API key authentication** for automation and CI/CD pipelines.

## Interactive login

Bricks CLI uses a device authorization flow to authenticate. The CLI generates a one-time code, opens your browser, and waits for you to approve.

1. [Install the Bricks CLI](/docs/bricks-cli/bricks-cli) if you haven't already
2. Run `bricks login`
3. Your browser opens automatically to the verification page with a pre-filled code. If the browser doesn't open, copy the URL and code from the terminal and open it manually.
4. Sign in and approve the CLI

The terminal confirms authentication:

```
✓ Logged in successfully as you@company.com
```

Your token is saved to `~/.bricks/credentials.yaml`.

Verify your authentication:

```bash
bricks whoami
```

### Troubleshooting

<details>

<summary>Browser doesn't open</summary>

Copy the verification URL and code printed in your terminal and open the URL manually in any browser.

</details>

<details>

<summary>Code expired</summary>

Verification codes expire after approximately 10 minutes. Run `bricks login` again to get a new code.

</details>

<details>

<summary>"Login was denied" error</summary>

This happens when you sign in with a personal account instead of an organization account. Run `bricks login` again and select your organization account.

</details>

{% hint style="info" %}
Run `bricks logger enable` then retry the sign-in to generate detailed logs in `~/.bricks/bricks-cli.log`. If you can't resolve the issue, contact the Bluebricks team.
{% endhint %}

## API key authentication

For automation and CI/CD, use long-lived API tokens instead of interactive login. There are three ways to provide an API key:

### CLI flag

```bash
bricks collection create --name "my_collection" --api-key "bbx_your_api_key_here"
```

### Environment variable (recommended for CI/CD)

```bash
export BRICKS_API_KEY="bbx_your_api_key_here"
bricks collection create --name "my_collection"
```

### Configuration file

Add to `~/.bricks/environment.yaml`:

```yaml
api_key: "bbx_your_api_key_here"
```

See [API Authentication](https://bluebricks.co/docs/api/authenticate/authentication) for how to create and manage API keys.

## Authentication priority

Bricks CLI checks authentication sources in this order:

1. **CLI flag** (`--api-key`)
2. **Environment variable** (`BRICKS_API_KEY`)
3. **Configuration file** (`~/.bricks/environment.yaml`)
4. **JWT token** from `bricks login` (`~/.bricks/credentials.yaml`)

## Logout

```bash
bricks logout
```

## See also

* [Authenticate Using Long-Lived Tokens](/docs/bricks-cli/authentication/authenticate-using-long-lived-tokens): embed tokens directly in the credentials file
* [API Authentication](https://bluebricks.co/docs/api/authenticate/authentication): create and manage API keys
* [Quick Start](/docs/getting-started/quick-start): end-to-end onboarding walkthrough


# Authenticate Using Long-Lived Tokens

Configure long-lived API tokens for CLI authentication in scripts, CI/CD pipelines, and automation workflows

Developers can use [long-lived tokens](https://bluebricks.co/docs/api/authenticate/authentication) to authenticate the CLI and integrate [**bricks CLI**](/docs/bricks-cli/bricks-cli) commands into scripts and automation workflows, such as CI/CD pipelines or AI operations.

This guide explains how to configure a long-lived token as the authentication key for the CLI.

## Generate a Long-Lived Token

Ensure you have a valid long-lived token. [Read here to learn how to create tokens](https://bluebricks.co/docs/api/authenticate/authentication).

Once created, your token will look like this:

```
{
    "api_key": "bbx_2b52642255....4ffd"
}
```

## Embed the Token in the Configuration File

The **bricks CLI** uses various configuration files. The `credentials.yaml` file stores your authentication key and identity.

To authenticate using the long-lived token:

1. Open the `credentials.yaml` file located at:

```
$HOME/.bricks/credentials.yaml
```

2. Update the file with the following values:
   * Set `token` to the long-lived token.
   * Set `userid` to the value `api_key`.

Your updated `credentials.yaml` should look like this:

```
token: Bearer bbx_2b52642255....4ffd
userid: api_key
```

You’re now ready to use **bricks CLI** with your long-lived token for automation and scripting!


# Configuration Management

Understand how the Bricks CLI stores and loads configuration from \~/.bricks, including config.yaml, credentials.yaml, environment variables, and global flags

The Bricks CLI reads settings from files in `~/.bricks/`, environment variables, and CLI flags. This page explains each configuration source, the keys you can set, and the order in which values are resolved.

## Configuration directory

The CLI creates the `~/.bricks/` directory automatically on first run. It contains two configuration files and a logs directory:

```
~/.bricks/
├── config.yaml         # Persistent user preferences
├── credentials.yaml    # Authentication token and user identity
└── logs/               # Daily log files (when logging is enabled)
```

## config.yaml

This file stores persistent user preferences. The CLI loads it at startup and applies the values on top of built-in defaults.

| Key                  | Default  | Description                         |
| -------------------- | -------- | ----------------------------------- |
| `telemetry`          | `true`   | Send anonymous usage analytics      |
| `log`                | `false`  | Write logs to `~/.bricks/logs/`     |
| `log_level`          | `"info"` | Log verbosity: `info`, `debug`      |
| `log_format`         | `"json"` | Log format: `json`, `text`, `none`  |
| `skip_version_check` | `false`  | Skip the update check on startup    |
| `non_interactive`    | `false`  | Suppress interactive prompts        |
| `api_key`            | `""`     | API key for headless authentication |

```yaml
# ~/.bricks/config.yaml
telemetry: true
log: false
log_level: "info"
log_format: "json"
skip_version_check: false
non_interactive: false
api_key: ""
```

You do not need to edit this file by hand. The CLI provides commands that update it for you:

| Command                    | Effect                                       |
| -------------------------- | -------------------------------------------- |
| `bricks logger enable`     | Sets `log: true`                             |
| `bricks logger disable`    | Sets `log: false`                            |
| `bricks logger status`     | Shows whether logging is on or off           |
| `bricks logger cleanup`    | Deletes all log files from `~/.bricks/logs/` |
| `bricks telemetry enable`  | Sets `telemetry: true`                       |
| `bricks telemetry disable` | Sets `telemetry: false`                      |
| `bricks telemetry status`  | Shows whether telemetry is on or off         |

{% hint style="info" %}
For more on what data the CLI collects, see [Telemetry](/docs/bricks-cli/telemetry).
{% endhint %}

## credentials.yaml

This file holds your authentication token and user identity. It is managed by the `bricks login` and `bricks logout` commands.

```yaml
# ~/.bricks/credentials.yaml
token: Bearer YOUR_API_TOKEN
userid: user@example.com
```

{% hint style="warning" %}
Never share or commit `credentials.yaml`. It contains your session token. If you suspect it has been exposed, run `bricks logout` and re-authenticate.
{% endhint %}

See [Authentication](/docs/bricks-cli/authentication) for the browser-based login flow, or [Long-Lived Tokens](/docs/bricks-cli/authentication/authenticate-using-long-lived-tokens) for CI/CD scenarios.

## Environment variable overrides

Every config key can be overridden with an environment variable by adding the `BRICKS_` prefix and uppercasing the key name.

| Variable                    | Overrides            |
| --------------------------- | -------------------- |
| `BRICKS_API_KEY`            | `api_key`            |
| `BRICKS_NON_INTERACTIVE`    | `non_interactive`    |
| `BRICKS_TELEMETRY`          | `telemetry`          |
| `BRICKS_LOG`                | `log`                |
| `BRICKS_LOG_LEVEL`          | `log_level`          |
| `BRICKS_SKIP_VERSION_CHECK` | `skip_version_check` |

{% hint style="success" %}
Environment variables are the recommended way to configure the CLI in CI/CD pipelines. Pair `BRICKS_API_KEY` with `BRICKS_NON_INTERACTIVE=true` for fully headless runs.
{% endhint %}

## Global CLI flags

These flags apply to any command and override both config files and environment variables:

| Flag                | Description                                                 |
| ------------------- | ----------------------------------------------------------- |
| `--config <path>`   | Use a custom config file instead of `~/.bricks/config.yaml` |
| `--api-key <key>`   | Authenticate with an API key for this invocation            |
| `--non-interactive` | Suppress interactive prompts for this invocation            |

```bash
bricks blueprint publish --api-key "$BRICKS_KEY" --non-interactive
```

See the [CLI Reference](/docs/bricks-cli/cli-reference) for the full list of commands and flags.

## Configuration loading order

The CLI resolves configuration in the following order. Each layer overrides the previous one:

1. **Built-in defaults** (hardcoded in the CLI binary)
2. **config.yaml** (`~/.bricks/config.yaml`)
3. **credentials.yaml** (`~/.bricks/credentials.yaml`)
4. **Environment variables** (`BRICKS_` prefix)
5. **CLI flags** (`--config`, `--api-key`, `--non-interactive`)

{% @mermaid/diagram content="flowchart LR
A\[Defaults] --> B\[config.yaml]
B --> C\[credentials.yaml]
C --> D\[Env vars]
D --> E\[CLI flags]
style E fill:#4CAF50,color:#fff" %}

A value set by a CLI flag always wins.

## Log files

When logging is enabled, the CLI writes one log file per day to `~/.bricks/logs/`:

```
~/.bricks/logs/bricks_09_03_2026.log
```

The file name follows the pattern `bricks_DD_MM_YYYY.log`. Use `bricks logger enable` and `bricks logger disable` to toggle logging, or `bricks logger cleanup` to remove old files. See the full command list in [config.yaml](#config-yaml) above.

{% hint style="info" %}
Log files stay on your local machine. They are not sent to Bluebricks.
{% endhint %}


# Telemetry

Understand what telemetry data Bluebricks collects from the CLI and web app, and how to opt out

Bluebricks collects telemetry data about the usability of its bricks CLI and web application interface. In addition, Bluebricks collects general usage data from its platform. Telemetry collection is optional, and you may opt-out if you'd not like to share any information.

## Why is telemetry collected?

Collecting telemetry about Bluebricks' usability and platform usage is essential for end users and customers, as it provides valuable insights that drive continuous improvement and innovation.

Telemetry enables Bluebricks to fully represent the diverse use cases of the entire user base and avoid capturing only the experiences of a limited subset of users.

This data helps us identify common pain points, understand which features are most valuable, and prioritize improvements that will benefit the majority of users.

By leveraging this information, we can make informed decisions that ensure Bluebricks continues to evolve in a way that enhances its relevance, performance, and overall user experience. Additionally, telemetry allows us to measure the impact of updates, confirming that our enhancements are delivering real value to our customers.

## What is being collected?

We collect two segments of data; user-experience usability and platform performance and operation.

### User Experience Usability

We track user behavioral activity, such as page views, scrolls, and clicks.

Additionally, we collect data about sessions, such as:

* Duration
* Continuity
* Geo-location
* Operation System
* Browser vendor and type
* Resolution

We do not collect private information about the user, including name, email, IP, etc. See [Bluebricks Privacy](https://www.bluebricks.co/privacy) for more information.

#### `bricks` Command Line

We collect behavioral activity such as command invokes, errors, and crashes outside of the web interface. We do not ship backlogs or collect private information about the runtime or the users.

Users can opt-out of command line telemetry by typing `bricks telemetry disable` command, and enable it by typing `bricks telemetry enable`.


# CLI Reference

Complete reference for every bricks CLI command

The `bricks` command-line interface lets DevOps and Platform teams manage Infrastructure-as-Code at scale -- from creating and publishing blueprints to deploying them across collections.

For installation and setup, see the [CLI Overview](/docs/bricks-cli/bricks-cli).

{% hint style="info" %}
Run `bricks <command> --help` from your terminal to see usage details and available flags for any command.
{% endhint %}

## Core Workflow

The commands you will use most often when working with blueprints and deployments.

| Command                                                             | Description                                                  |
| ------------------------------------------------------------------- | ------------------------------------------------------------ |
| [bricks blueprint](/docs/bricks-cli/cli-reference/bricks_blueprint) | Create, publish, version, and manage blueprints and packages |
| [bricks install](/docs/bricks-cli/cli-reference/bricks_install)     | Deploy a blueprint to a collection                           |
| [bricks uninstall](/docs/bricks-cli/cli-reference/bricks_uninstall) | Destroy a blueprint from a collection                        |
| [bricks run](/docs/bricks-cli/cli-reference/bricks_run)             | Plan and apply resources locally or remotely                 |
| [bricks deploy](/docs/bricks-cli/cli-reference/bricks_deploy)       | View and manage deployments                                  |
| [bricks updateci](/docs/bricks-cli/cli-reference/bricks_updateci)   | Automate artifact and blueprint updates based on Git changes |

## Infrastructure Management

| Command                                                               | Description                                                   |
| --------------------------------------------------------------------- | ------------------------------------------------------------- |
| [bricks collection](/docs/bricks-cli/cli-reference/bricks_collection) | Create, list, enable, disable, and delete collections         |
| [bricks clouds](/docs/bricks-cli/cli-reference/bricks_clouds)         | Manage cloud provider accounts (AWS, GCP, Azure, Self-Hosted) |
| [bricks setup](/docs/bricks-cli/cli-reference/bricks_setup)           | Register a customer cloud on Bluebricks                       |

## Authentication

Authenticate interactively or with long-lived API tokens for CI/CD. For a step-by-step guide, see [Authentication](/docs/bricks-cli/authentication).

| Command                                                       | Description                                    |
| ------------------------------------------------------------- | ---------------------------------------------- |
| [bricks login](/docs/bricks-cli/cli-reference/bricks_login)   | Connect the CLI to a Bluebricks account        |
| [bricks logout](/docs/bricks-cli/cli-reference/bricks_logout) | Disconnect from the current Bluebricks account |
| [bricks whoami](/docs/bricks-cli/cli-reference/bricks_whoami) | Display the signed-in user                     |

For non-interactive environments (CI/CD pipelines, scripts), pass the `--api-key` flag or configure a [long-lived token](/docs/bricks-cli/authentication/authenticate-using-long-lived-tokens).

## Utility

| Command                                                                                                                      | Description                                                         |
| ---------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------- |
| [bricks logger](https://github.com/bluebricks-dev/Bluebricks-Documentation/blob/main/cli-reference/bricks_logger.md)         | Enable, disable, and manage CLI logging                             |
| [bricks telemetry](https://github.com/bluebricks-dev/Bluebricks-Documentation/blob/main/cli-reference/bricks_telemetry.md)   | Enable, disable, and check telemetry settings                       |
| [bricks completion](https://github.com/bluebricks-dev/Bluebricks-Documentation/blob/main/cli-reference/bricks_completion.md) | Generate shell autocompletion scripts (Bash, Zsh, Fish, PowerShell) |
| [bricks version](/docs/bricks-cli/cli-reference/bricks_version)                                                              | Print the CLI version                                               |

## Global Flags

Every command accepts the following flags:

```
      --api-key string    API key for authentication (overrides JWT)
      --config string     Config file (default: $HOME/.bricks/config.yaml)
  -h, --help              Print help message
      --non-interactive   Suppress interactive UI elements
  -v, --version           Print CLI version
```


# bricks blueprint

Manage blueprints - create, publish, add dependencies, and configure packages

```
bricks blueprint [flags]
```

## Options inherited from parent commands

```
      --api-key string    API key for authentication (overrides JWT)
      --config string     config file (default is $HOME/.bricks/config.yaml)
  -h, --help              Print Help message for Bricks CLI
      --non-interactive   Suppresses interactive UI elements for non-interactive environments
  -v, --version           Print bricks CLI version
```

## SEE ALSO

* [bricks](https://github.com/bluebricks-dev/Bluebricks-Documentation/blob/main/cli-reference/bricks.md) -
* [bricks blueprint add](/docs/bricks-cli/cli-reference/bricks_blueprint/bricks_blueprint_add) - Adding remote blueprint to local blueprint
* [bricks blueprint add-repo](/docs/bricks-cli/cli-reference/bricks_blueprint/bricks_blueprint_add-repo) - Adding github repository url to local blueprint
* [bricks blueprint bump](/docs/bricks-cli/cli-reference/bricks_blueprint/bricks_blueprint_bump) - Bump blueprint version
* [bricks blueprint create](/docs/bricks-cli/cli-reference/bricks_blueprint/bricks_blueprint_create) - Create new IaC module for an exiting blueprint
* [bricks blueprint describe](/docs/bricks-cli/cli-reference/bricks_blueprint/bricks_blueprint_describe) - Printout the bricks.json of the provided blueprint
* [bricks blueprint fetch](/docs/bricks-cli/cli-reference/bricks_blueprint/bricks_blueprint_fetch) - Download binaries of a blueprint
* [bricks blueprint get](/docs/bricks-cli/cli-reference/bricks_blueprint/bricks_blueprint_get) - List the configuration of the provided blueprint
* [bricks blueprint init](/docs/bricks-cli/cli-reference/bricks_blueprint/bricks_blueprint_init) - Create new empty blueprint
* [bricks blueprint prepare](/docs/bricks-cli/cli-reference/bricks_blueprint/bricks_blueprint_prepare) - Prepare Infrastructure-as-Code files
* [bricks blueprint publish](/docs/bricks-cli/cli-reference/bricks_blueprint/bricks_blueprint_publish) - Publishing a new blueprint
* [bricks blueprint remove](/docs/bricks-cli/cli-reference/bricks_blueprint/bricks_blueprint_remove) - Removing blueprint
* [bricks blueprint search](/docs/bricks-cli/cli-reference/bricks_blueprint/bricks_blueprint_search) - Conduct a blueprint search
* [bricks blueprint state-config](/docs/bricks-cli/cli-reference/bricks_blueprint/bricks_blueprint_state-config) - Retrieve remote Terraform/OpenTofu state backend config
* [bricks blueprint status](/docs/bricks-cli/cli-reference/bricks_blueprint/bricks_blueprint_status) - Provide installation info on a blueprint
* [bricks blueprint update](/docs/bricks-cli/cli-reference/bricks_blueprint/bricks_blueprint_update) - Update blueprint
* [bricks blueprint view](/docs/bricks-cli/cli-reference/bricks_blueprint/bricks_blueprint_view) - View blueprint versions


# add

Adding remote blueprint to local blueprint

## Synopsis

Help information for blueprint add

```
bricks blueprint add [package] [flags]
```

## Options

```
      --props string        A pointer to a JSON file that include the properties to associate with the package.
      --props-file string   A JSON string of properties to associate with the package. This way a IaC turning opinionated.
```

## Options inherited from parent commands

```
      --api-key string    API key for authentication (overrides JWT)
      --config string     config file (default is $HOME/.bricks/config.yaml)
  -h, --help              Print Help message for Bricks CLI
      --non-interactive   Suppresses interactive UI elements for non-interactive environments
  -v, --version           Print bricks CLI version
```

## SEE ALSO

* [bricks blueprint](/docs/bricks-cli/cli-reference/bricks_blueprint) - Manage blueprints - create, publish, add dependencies, and configure packages


# add-repo

Adding github repository url to local blueprint

## Synopsis

Help information for blueprint add-repo

```
bricks blueprint add-repo [url] [flags]
```

## Options

```
      --props string        A pointer to a JSON file that include the properties to customize the package
      --props-file string   A JSON string of properties to customize the package
```

## Options inherited from parent commands

```
      --api-key string    API key for authentication (overrides JWT)
      --config string     config file (default is $HOME/.bricks/config.yaml)
  -h, --help              Print Help message for Bricks CLI
      --non-interactive   Suppresses interactive UI elements for non-interactive environments
  -v, --version           Print bricks CLI version
```

## SEE ALSO

* [bricks blueprint](/docs/bricks-cli/cli-reference/bricks_blueprint) - Manage blueprints - create, publish, add dependencies, and configure packages


# bump

Bump blueprint version

## Synopsis

Bump blueprint version

```
bricks blueprint bump [flags]
```

## Options

```
      --major       Bump major version.
      --minor       Bump minor version.
      --patch       Bump patch version.
  -r, --recursive   Bump all nested packages to their latest published versions.
```

## Options inherited from parent commands

```
      --api-key string    API key for authentication (overrides JWT)
      --config string     config file (default is $HOME/.bricks/config.yaml)
  -h, --help              Print Help message for Bricks CLI
      --non-interactive   Suppresses interactive UI elements for non-interactive environments
  -v, --version           Print bricks CLI version
```

## SEE ALSO

* [bricks blueprint](/docs/bricks-cli/cli-reference/bricks_blueprint) - Manage blueprints - create, publish, add dependencies, and configure packages


# create

Create new IaC module for an exiting blueprint

```
bricks blueprint create [flags]
```

## Options inherited from parent commands

```
      --api-key string    API key for authentication (overrides JWT)
      --config string     config file (default is $HOME/.bricks/config.yaml)
  -h, --help              Print Help message for Bricks CLI
      --non-interactive   Suppresses interactive UI elements for non-interactive environments
  -v, --version           Print bricks CLI version
```

## SEE ALSO

* [bricks blueprint](/docs/bricks-cli/cli-reference/bricks_blueprint) - Manage blueprints - create, publish, add dependencies, and configure packages
* [bricks blueprint create tf](/docs/bricks-cli/cli-reference/bricks_blueprint/bricks_blueprint_create/bricks_blueprint_create_tf) - Scaffolding a Terraform module and updating bricks.json accordingly.


# tf

Scaffolding a Terraform module and updating bricks.json accordingly.

## Synopsis

Help information for blueprint create tf

```
bricks blueprint create tf [flags]
```

## Options

```
      --project string   If provided, CLI create the template inside a directory that is named with project value.
```

## Options inherited from parent commands

```
      --api-key string    API key for authentication (overrides JWT)
      --config string     config file (default is $HOME/.bricks/config.yaml)
  -h, --help              Print Help message for Bricks CLI
      --non-interactive   Suppresses interactive UI elements for non-interactive environments
  -v, --version           Print bricks CLI version
```

## SEE ALSO

* [bricks blueprint create](/docs/bricks-cli/cli-reference/bricks_blueprint/bricks_blueprint_create) - Create new IaC module for an exiting blueprint


# describe

Printout the bricks.json of the provided blueprint

## Synopsis

Printout the published bricks.json of the provided blueprint and version

```
bricks blueprint describe [package] [flags]
```

## Options inherited from parent commands

```
      --api-key string    API key for authentication (overrides JWT)
      --config string     config file (default is $HOME/.bricks/config.yaml)
  -h, --help              Print Help message for Bricks CLI
      --non-interactive   Suppresses interactive UI elements for non-interactive environments
  -v, --version           Print bricks CLI version
```

## SEE ALSO

* [bricks blueprint](/docs/bricks-cli/cli-reference/bricks_blueprint) - Manage blueprints - create, publish, add dependencies, and configure packages


# fetch

Download binaries of a blueprint

## Synopsis

Downloading the provided blueprint from Bluebricks registry

```
bricks blueprint fetch [package] [flags]
```

## Options

```
      --include-children   Recursively fetch blueprint and all its child packages
      --max-depth int      Maximum recursion depth for fetching child packages (default: 15) (default 15)
      --output string      The destination to download the blueprints.
```

## Options inherited from parent commands

```
      --api-key string    API key for authentication (overrides JWT)
      --config string     config file (default is $HOME/.bricks/config.yaml)
  -h, --help              Print Help message for Bricks CLI
      --non-interactive   Suppresses interactive UI elements for non-interactive environments
  -v, --version           Print bricks CLI version
```

## SEE ALSO

* [bricks blueprint](/docs/bricks-cli/cli-reference/bricks_blueprint) - Manage blueprints - create, publish, add dependencies, and configure packages


# get

List the configuration of the provided blueprint

## Synopsis

List the outs or props configuration for a blueprint and its first level of children

```
bricks blueprint get [flags]
```

## Options inherited from parent commands

```
      --api-key string    API key for authentication (overrides JWT)
      --config string     config file (default is $HOME/.bricks/config.yaml)
  -h, --help              Print Help message for Bricks CLI
      --non-interactive   Suppresses interactive UI elements for non-interactive environments
  -v, --version           Print bricks CLI version
```

## SEE ALSO

* [bricks blueprint](/docs/bricks-cli/cli-reference/bricks_blueprint) - Manage blueprints - create, publish, add dependencies, and configure packages
* [bricks blueprint get outs](/docs/bricks-cli/cli-reference/bricks_blueprint/bricks_blueprint_get/bricks_blueprint_get_outs) - List outs of the provided blueprint
* [bricks blueprint get props](/docs/bricks-cli/cli-reference/bricks_blueprint/bricks_blueprint_get/bricks_blueprint_get_props) - List props of the provided blueprint


# outs

List outs of the provided blueprint

## Synopsis

List the outs configuration for a blueprint and its first level of children

```
bricks blueprint get outs [package] [flags]
```

## Options inherited from parent commands

```
      --api-key string    API key for authentication (overrides JWT)
      --config string     config file (default is $HOME/.bricks/config.yaml)
  -h, --help              Print Help message for Bricks CLI
      --non-interactive   Suppresses interactive UI elements for non-interactive environments
  -v, --version           Print bricks CLI version
```

## SEE ALSO

* [bricks blueprint get](/docs/bricks-cli/cli-reference/bricks_blueprint/bricks_blueprint_get) - List the configuration of the provided blueprint


# props

List props of the provided blueprint

## Synopsis

List the props configuration for a blueprint and its first level of children

```
bricks blueprint get props [package] [flags]
```

## Options inherited from parent commands

```
      --api-key string    API key for authentication (overrides JWT)
      --config string     config file (default is $HOME/.bricks/config.yaml)
  -h, --help              Print Help message for Bricks CLI
      --non-interactive   Suppresses interactive UI elements for non-interactive environments
  -v, --version           Print bricks CLI version
```

## SEE ALSO

* [bricks blueprint get](/docs/bricks-cli/cli-reference/bricks_blueprint/bricks_blueprint_get) - List the configuration of the provided blueprint


# init

Create new empty blueprint

## Synopsis

Help information for blueprint init

```
bricks blueprint init [flags]
```

## Options inherited from parent commands

```
      --api-key string    API key for authentication (overrides JWT)
      --config string     config file (default is $HOME/.bricks/config.yaml)
  -h, --help              Print Help message for Bricks CLI
      --non-interactive   Suppresses interactive UI elements for non-interactive environments
  -v, --version           Print bricks CLI version
```

## SEE ALSO

* [bricks blueprint](/docs/bricks-cli/cli-reference/bricks_blueprint) - Manage blueprints - create, publish, add dependencies, and configure packages


# prepare

Prepare Infrastructure-as-Code files

```
bricks blueprint prepare [flags]
```

## Examples

```
bricks bprint prepare --source=./src --output=./dist
```

## Options

```
      --iac-type string       Which IaC to create (Available Options: terraform, opentofu, helm, cloudformation, bicep) (default "undefined")
  -o, --output string         files output
      --package-name string   Provide a name for the created package, (Default: base working dir)
      --refactor              Create bricks.json with altering the existing IaC code
  -s, --source string         files source
```

## Options inherited from parent commands

```
      --api-key string    API key for authentication (overrides JWT)
      --config string     config file (default is $HOME/.bricks/config.yaml)
  -h, --help              Print Help message for Bricks CLI
      --non-interactive   Suppresses interactive UI elements for non-interactive environments
  -v, --version           Print bricks CLI version
```

## SEE ALSO

* [bricks blueprint](/docs/bricks-cli/cli-reference/bricks_blueprint) - Manage blueprints - create, publish, add dependencies, and configure packages


# publish

Publishing a new blueprint

## Synopsis

Help information for blueprint publish

```
bricks blueprint publish [flags]
```

## Options

```
      --resolve-modules   Resolve and include external Terraform module references in the published blueprint. (default true)
      --src string        Blueprint location.
      --state             Define if package files include a .tfstate file for migration purpose.
```

## Options inherited from parent commands

```
      --api-key string    API key for authentication (overrides JWT)
      --config string     config file (default is $HOME/.bricks/config.yaml)
  -h, --help              Print Help message for Bricks CLI
      --non-interactive   Suppresses interactive UI elements for non-interactive environments
  -v, --version           Print bricks CLI version
```

## SEE ALSO

* [bricks blueprint](/docs/bricks-cli/cli-reference/bricks_blueprint) - Manage blueprints - create, publish, add dependencies, and configure packages


# remove

Removing blueprint

## Synopsis

Help information for blueprint remove

```
bricks blueprint remove [package] [flags]
```

## Options inherited from parent commands

```
      --api-key string    API key for authentication (overrides JWT)
      --config string     config file (default is $HOME/.bricks/config.yaml)
  -h, --help              Print Help message for Bricks CLI
      --non-interactive   Suppresses interactive UI elements for non-interactive environments
  -v, --version           Print bricks CLI version
```

## SEE ALSO

* [bricks blueprint](/docs/bricks-cli/cli-reference/bricks_blueprint) - Manage blueprints - create, publish, add dependencies, and configure packages


# search

Conduct a blueprint search

## Synopsis

Conduct a blueprint search

Provide a search query to find blueprints that match the query.

```
bricks blueprint search [flags]
```

## Options

```
  -q, --query string   Search query
```

## Options inherited from parent commands

```
      --api-key string    API key for authentication (overrides JWT)
      --config string     config file (default is $HOME/.bricks/config.yaml)
  -h, --help              Print Help message for Bricks CLI
      --non-interactive   Suppresses interactive UI elements for non-interactive environments
  -v, --version           Print bricks CLI version
```

## SEE ALSO

* [bricks blueprint](/docs/bricks-cli/cli-reference/bricks_blueprint) - Manage blueprints - create, publish, add dependencies, and configure packages


# state-config

Retrieve remote Terraform/OpenTofu state backend config

## Synopsis

Retrieves remote state and generates backend.tf and optional vars file for local Terraform/OpenTofu development based on the last deployment. Use this command to set up your local environment for working with the remote state. Optionally, you can specify an artifact ID to filter the artifacts in the deployment. (example - --artifact-id "aws\_\*") By default, it will try to find bricks.json in the current directory and use its name as a prefix for the artifact search.

```
bricks blueprint state-config [environment-slug] [flags]
```

## Examples

```
bricks bp state-config <environment-slug>
```

## Options

```
  -a, --artifact-id string   Glob search pattern for artifacts in the deployment.
```

## Options inherited from parent commands

```
      --api-key string    API key for authentication (overrides JWT)
      --config string     config file (default is $HOME/.bricks/config.yaml)
  -h, --help              Print Help message for Bricks CLI
      --non-interactive   Suppresses interactive UI elements for non-interactive environments
  -v, --version           Print bricks CLI version
```

## SEE ALSO

* [bricks blueprint](/docs/bricks-cli/cli-reference/bricks_blueprint) - Manage blueprints - create, publish, add dependencies, and configure packages


# status

Provide installation info on a blueprint

```
bricks blueprint status [package] [flags]
```

## Options

```
      --version string   package version
```

## Options inherited from parent commands

```
      --api-key string    API key for authentication (overrides JWT)
      --config string     config file (default is $HOME/.bricks/config.yaml)
  -h, --help              Print Help message for Bricks CLI
      --non-interactive   Suppresses interactive UI elements for non-interactive environments
```

## SEE ALSO

* [bricks blueprint](/docs/bricks-cli/cli-reference/bricks_blueprint) - Manage blueprints - create, publish, add dependencies, and configure packages


# update

Update blueprint

## Synopsis

Help information for blueprint update

```
bricks blueprint update [package] [flags]
```

## Options

```
      --all         Update any nested packages with its latest published version.
      --major       Update parent blueprint's major version.
      --minor       Update parent blueprint's minor version.
      --no-bump     Update blueprint content without bumping the version
      --overwrite   Update the bricks.json of blueprint with all props and outs from a recently updated Artifact
      --patch       Update parent blueprint's patch version.
  -y, --yes         Skip interactive approval of updates.
```

## Options inherited from parent commands

```
      --api-key string    API key for authentication (overrides JWT)
      --config string     config file (default is $HOME/.bricks/config.yaml)
  -h, --help              Print Help message for Bricks CLI
      --non-interactive   Suppresses interactive UI elements for non-interactive environments
  -v, --version           Print bricks CLI version
```

## SEE ALSO

* [bricks blueprint](/docs/bricks-cli/cli-reference/bricks_blueprint) - Manage blueprints - create, publish, add dependencies, and configure packages


# view

View blueprint versions

## Synopsis

List all versions of a blueprint

```
bricks blueprint view [package] [flags]
```

## Examples

```
bricks bp view <blueprint-name>
```

## Options inherited from parent commands

```
      --api-key string    API key for authentication (overrides JWT)
      --config string     config file (default is $HOME/.bricks/config.yaml)
  -h, --help              Print Help message for Bricks CLI
      --non-interactive   Suppresses interactive UI elements for non-interactive environments
  -v, --version           Print bricks CLI version
```

## SEE ALSO

* [bricks blueprint](/docs/bricks-cli/cli-reference/bricks_blueprint) - Manage blueprints - create, publish, add dependencies, and configure packages


# bricks clouds

Manage cloud provider accounts (AWS, GCP, Azure, Self-Hosted, etc.)

```
bricks clouds [flags]
```

## Options inherited from parent commands

```
      --api-key string    API key for authentication (overrides JWT)
      --config string     config file (default is $HOME/.bricks/config.yaml)
  -h, --help              Print Help message for Bricks CLI
      --non-interactive   Suppresses interactive UI elements for non-interactive environments
  -v, --version           Print bricks CLI version
```

## SEE ALSO

* [bricks](https://github.com/bluebricks-dev/Bluebricks-Documentation/blob/main/cli-reference/bricks.md) -
* [bricks clouds delete](/docs/bricks-cli/cli-reference/bricks_clouds/bricks_clouds_delete) - Delete cloud account
* [bricks clouds ls](/docs/bricks-cli/cli-reference/bricks_clouds/bricks_clouds_ls) - List available cloud accounts




---

[Next Page](/docs/llms-full.txt/1)

