> For the complete documentation index, see [llms.txt](https://developer.harness.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://developer.harness.io/infrastructure-as-code-management/platform/workspaces/reference-workspace-outputs.md).

# Reference workspace outputs

Use outputs from one IaCM workspace in another workspace when your infrastructure is split across multiple workspaces.

Use outputs from one IaCM workspace in another workspace when your infrastructure is split across multiple workspaces. For example, a network workspace can create a VPC and expose its ID as an output, while an application workspace uses that VPC ID to create application resources.

You can reference outputs from another workspace in two ways:

* **`terraform_remote_state`:** Read the producing workspace's state directly from its Harness HTTP backend. Use this approach when the workspaces are in different projects or when you want to manage the dependency in Terraform or OpenTofu.
* **JEXL (Java Expression Language) expressions:** Pass an output from the producing workspace to the consuming workspace through a workspace variable. Use this approach when both workspaces are in the same Harness project and you want to configure the dependency in Harness. Go to [Workspace Expressions](/infrastructure-as-code-management/platform/workspaces/workspace-expressions.md) for the full expression reference.

***

## Before you begin

* **IaCM enabled:** You need **Infrastructure as Code Management** under **Infrastructure** in Harness. For how to access or create a Harness account, go to [Get started with IaCM](/infrastructure-as-code-management/new-to-iacm/get-started.md).
* **A producing workspace with at least one output defined:** The workspace whose outputs you want to reference must have been provisioned and its outputs must be visible under **Resources > Outputs**. Go to [Output Parameters](/infrastructure-as-code-management/platform/reports-and-insights/output-variables.md) to understand how outputs are exposed.
* **The producing workspace's state address** (`terraform_remote_state` only): Find this on the **CLI Integration** tab of the producing workspace. Go to [CLI Integration](/infrastructure-as-code-management/platform/workspaces/cli-integration.md) for details.
* **A Harness API key with Workspace Access State permission** (`terraform_remote_state` only): The key must have the **Workspace Access State** (`iac_workspace_accessstate`) permission on the producing workspace. Go to [Add and manage API keys](https://developer.harness.io/harness-platform/use-harness-platform/automation/api/add-and-manage-api-keys) to create a key. Use a service account key rather than a personal access token when possible. Go to [Manage service accounts](https://developer.harness.io/harness-platform/use-harness-platform/platform-access-control/add-and-manage-service-account) to create a service account. Store the token as a Harness secret. Go to [Secrets](https://developer.harness.io/harness-platform/use-harness-platform/secrets) to create one.

{% hint style="info" %}
**Contact Harness Support**

If IaCM does not appear under **Infrastructure**, go to [Get started with IaCM](/infrastructure-as-code-management/new-to-iacm/get-started.md), or contact your account administrator or [Harness Support](mailto:support@harness.io).
{% endhint %}

***

## Use `terraform_remote_state`

Use `terraform_remote_state` to read outputs from another workspace directly in your Terraform or OpenTofu configuration.

Each IaCM workspace exposes its state through a Terraform-compatible HTTP backend. The consuming workspace uses the producing workspace's state endpoint to retrieve its outputs.

This approach works across Harness projects, so you can use it when the producing and consuming workspaces belong to different projects.

{% stepper %}
{% step %}

### Add a remote state data source

Add a `terraform_remote_state` data source to the consuming workspace. Point the `address` to the producing workspace's Terraform backend endpoint.

```hcl
data "terraform_remote_state" "network" {
  backend = "http"

  config = {
    address  = "https://app.harness.io/gateway/iacm/api/orgs/${var.harness_org_id}/projects/${var.harness_project_id}/workspaces/${var.producer_workspace_id}/terraform-backend?accountIdentifier=${var.harness_account_id}"
    username = "harness"
  }
}
```

Find the producing workspace's state address on the **CLI Integration** tab of the workspace. Go to [CLI Integration](/infrastructure-as-code-management/platform/workspaces/cli-integration.md) for details. The address follows this format:

```
https://app.harness.io/gateway/iacm/api/orgs/{organization}/projects/{project}/workspaces/{workspace}/terraform-backend?accountIdentifier={account_number}
```

You can enter the address directly in your configuration, or construct it from workspace variables. Using variables makes the configuration easier to maintain if the producing workspace changes.
{% endstep %}

{% step %}

### Configure authentication

The consuming workspace must authenticate when it reads the producing workspace's state.

Set `TF_HTTP_PASSWORD` as a **Secret** environment variable on the consuming workspace. Use a Harness API key with **Workspace Access State** (`iac_workspace_accessstate`) permission on the producing workspace as the secret value.

Do not add the token directly to the `config` block. Passing the token through `TF_HTTP_PASSWORD` keeps credentials out of your Terraform or OpenTofu configuration.

Use a service account token rather than a personal access token when possible. This keeps the workspace dependency independent of an individual user and lets you limit access to the resources the consuming workspace needs. Go to [Manage service accounts](https://developer.harness.io/harness-platform/use-harness-platform/platform-access-control/add-and-manage-service-account) to create a service account, and go to [Add and manage API keys](https://developer.harness.io/harness-platform/use-harness-platform/automation/api/add-and-manage-api-keys) to create a key for it.
{% endstep %}

{% step %}

### Configure the workspace variables

If you construct the state address from variables, add the following variables to the consuming workspace. Go to [Workspace Settings](/infrastructure-as-code-management/platform/workspaces/workspace-tabs.md) to add workspace variables.

```
harness_org_id
harness_project_id
producer_workspace_id
harness_account_id
```

If your configuration also references the token through `TF_HTTP_PASSWORD`, add the following variable and set it as a **Secret**:

```
harness_pat
```

{% endstep %}

{% step %}

### Reference the outputs

Reference outputs from the producing workspace through the `terraform_remote_state` data source:

```hcl
resource "aws_subnet" "app" {
  vpc_id     = data.terraform_remote_state.network.outputs.vpc_id
  cidr_block = cidrsubnet(data.terraform_remote_state.network.outputs.vpc_cidr, 8, 1)
}
```

The consuming workspace can use the outputs as normal Terraform or OpenTofu values. If the producing workspace exports a `vpc_id` output, the consuming workspace can use that value when creating a subnet, security group, or any other resource that depends on the VPC.
{% endstep %}
{% endstepper %}

***

## Pass outputs through Harness

Use a JEXL expression to pass an output from one workspace to another without adding a `terraform_remote_state` data source to your Terraform or OpenTofu configuration.

This approach is available when both workspaces are in the **same Harness project**. Harness resolves the expression and provides the producing workspace's output to the consuming workspace as a variable.

Use this approach when you want to manage the dependency in Harness rather than in your infrastructure code.

### Add the output as a workspace variable

Open the consuming workspace and add a variable for the value you want to receive from the producing workspace. Go to [Workspace Settings](/infrastructure-as-code-management/platform/workspaces/workspace-tabs.md) to add workspace variables.

Set the variable value to the following expression, replacing `WORKSPACE_ID` with the producing workspace's identifier and `OUTPUT_NAME` with the output name:

```
<+workspace.WORKSPACE_ID.OUTPUT_NAME>
```

You can copy the workspace ID from the workspace **Overview** tab and copy the output name from the **Resources > Outputs** tab. Go to [Output Parameters](/infrastructure-as-code-management/platform/reports-and-insights/output-variables.md) to locate output names.

For example, if the network workspace ID is `network_ws` and it exposes `vpc_id` and `vpc_cidr`, configure the consuming workspace variables as follows:

```
vpc_id   = <+workspace.network_ws.vpc_id>
vpc_cidr = <+workspace.network_ws.vpc_cidr>
```

The consuming workspace receives these values as regular workspace variables.

### Reference the variables in Terraform or OpenTofu

Declare the variables in your Terraform or OpenTofu configuration:

```hcl
variable "vpc_id" {
  type = string
}

variable "vpc_cidr" {
  type = string
}
```

You can then use them like any other input variable:

```hcl
resource "aws_subnet" "app" {
  vpc_id     = var.vpc_id
  cidr_block = cidrsubnet(var.vpc_cidr, 8, 1)
}
```

You do not need to add a `terraform_remote_state` data source to the configuration.

***

## Choose an approach

Choose the approach based on where your workspaces are located and where you want to manage the dependency.

|                                  | `terraform_remote_state`              | JEXL expression                                       |
| -------------------------------- | ------------------------------------- | ----------------------------------------------------- |
| Workspace location               | Same or different projects            | Same project only                                     |
| Configuration                    | Terraform or OpenTofu                 | Harness                                               |
| Changes to Terraform or OpenTofu | Required                              | Not required                                          |
| Cross-project references         | Supported                             | Not supported                                         |
| Access method                    | Reads the producing workspace's state | Passes the producing workspace's output as a variable |

Use `terraform_remote_state` when you need to reference a workspace in another project or want the dependency defined in your Terraform or OpenTofu code.

Use a JEXL expression when both workspaces are in the same project and you want to pass outputs through Harness without adding remote-state configuration.

***

## Example workspace dependency

A common setup is to separate infrastructure into workspaces based on their responsibility. The network workspace owns the VPC and its state. The application workspace consumes the `vpc_id` output instead of recreating or independently looking up the VPC. This keeps infrastructure responsibilities separated while allowing one workspace to use values produced by another.

```mermaid
flowchart TD
    A[Network workspace] -->|creates| B[VPC]
    A -->|creates| C[Subnets]
    A -->|outputs| D[vpc_id]
    D -->|consumed by| E[Application workspace]
    E -->|creates| F[Application resources]
```

***

## Troubleshooting

<details>

<summary>The terraform_remote_state init fails with an authentication error</summary>

The token set as `TF_HTTP_PASSWORD` is missing, expired, or does not have the **Workspace Access State** (`iac_workspace_accessstate`) permission on the producing workspace. Verify that the secret is correctly set as a **Secret** environment variable on the consuming workspace, that the token has not expired, and that its role includes `iac_workspace_accessstate`. Go to [Add and manage API keys](https://developer.harness.io/harness-platform/use-harness-platform/automation/api/add-and-manage-api-keys) to create a new token, and go to the [Permissions reference](https://developer.harness.io/harness-platform/use-harness-platform/platform-access-control/permissions-reference#infrastructure-as-code) to confirm the required permission.

</details>

<details>

<summary>The terraform_remote_state init fails with a 404 error</summary>

The state address is incorrect. Verify that the `address` in your `terraform_remote_state` config exactly matches the address shown on the **CLI Integration** tab of the producing workspace, including the `accountIdentifier` query parameter. Go to [CLI Integration](/infrastructure-as-code-management/platform/workspaces/cli-integration.md) to find the correct address.

</details>

<details>

<summary>A JEXL expression variable resolves to an empty value or causes a pipeline failure</summary>

Harness evaluates the expression at pipeline run time. If the expression resolves to empty, confirm that the workspace ID in the expression exactly matches the producing workspace's identifier shown on its **Overview** tab, and that the output name exactly matches the name shown on its **Resources > Outputs** tab. If the producing workspace has not been provisioned or the output does not exist, Harness cannot resolve the expression. Provision the producing workspace first, then run the consuming workspace pipeline.

</details>

***

## Next steps

* [Workspace Expressions](/infrastructure-as-code-management/platform/workspaces/workspace-expressions.md): Full reference for `<+workspace.…>` expressions, including outputs and environment variables.
* [CLI Integration](/infrastructure-as-code-management/platform/workspaces/cli-integration.md): Find the Terraform backend state address for a workspace.
* [Output Parameters](/infrastructure-as-code-management/platform/reports-and-insights/output-variables.md): View and copy output names from the workspace Resources tab.

{% @harness-feedback/feedback %}
