# Publish a Terraform Module

## 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.md#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.md#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.md#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.md): artifact reference and features overview
* [Creating Blueprints](/docs/orchestration/packages/blueprints-overview/creating-blueprints.md): compose artifacts into blueprints
* [Packages](/docs/orchestration/packages.md): artifact types and packaging concepts


---

# Agent Instructions: Querying This Documentation

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

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

```
GET https://bluebricks.co/docs/orchestration/packages/artifacts-overview/terraform-open-tofu/publish-terraform-module.md?ask=<question>
```

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

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