> ## Documentation Index
> Fetch the complete documentation index at: https://docs.barndoor.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Getting Started

> Generate a provider credential, configure the Barndoor Terraform provider, and apply your first resource

This guide takes you from an empty directory to your first `terraform apply` against your Barndoor organization.

<Note>
  **Estimated time**: 10–15 minutes
</Note>

## Before You Begin

You'll need:

* A Barndoor account with **admin privileges** for your organization
* [Terraform](https://developer.hashicorp.com/terraform/install) 1.0 or later (OpenTofu works too)

## Step 1: Generate a provider credential

The provider authenticates as a machine credential scoped to your organization — no interactive login, no user tokens.

1. In the Barndoor app, go to **Settings → API Tokens**.
2. Find the **Terraform provider credentials** panel and click **Generate credential**.
3. Choose a **secret expiry** (90 days by default; you can rotate at any time).
4. Copy the three values from the reveal dialog: **Client ID**, **Client secret**, and **Organization ID**. The dialog also offers a ready-made Terraform configuration you can copy directly.

<Warning>
  The **client secret is shown only once**. If you lose it, rotate the credential to get a fresh secret — the client ID stays the same.
</Warning>

<Note>
  **One credential is active per organization.** Rotating replaces the secret in place; revoking disables the credential entirely. If your team already uses Terraform with Barndoor, coordinate before rotating — a rotation invalidates the secret everyone else is using.
</Note>

## Step 2: Configure the provider

Create a working directory with a `main.tf`:

```hcl main.tf theme={null}
terraform {
  required_providers {
    barndoor = {
      source  = "barndoor-ai/barndoor"
      version = "~> 0.3"
    }
  }
}

provider "barndoor" {
  # The platform host root, with no path — the provider appends each
  # service's API prefix itself.
  base_url  = "https://platform.barndoor.ai"
  token_url = "https://auth.barndoor.ai/realms/barndoor/protocol/openid-connect/token"

  client_id       = "your-client-id"
  organization_id = "your-organization-id"

  # client_secret is read from the BARNDOOR_CLIENT_SECRET environment
  # variable — never commit it to configuration.
}
```

Then export the secret:

```bash theme={null}
export BARNDOOR_CLIENT_SECRET="the-secret-from-step-1"
```

Every provider argument has an environment-variable fallback, which is the recommended way to configure CI:

| Argument          | Environment variable       |
| ----------------- | -------------------------- |
| `base_url`        | `BARNDOOR_BASE_URL`        |
| `token_url`       | `BARNDOOR_TOKEN_URL`       |
| `client_id`       | `BARNDOOR_CLIENT_ID`       |
| `client_secret`   | `BARNDOOR_CLIENT_SECRET`   |
| `organization_id` | `BARNDOOR_ORGANIZATION_ID` |

All five values are required — the provider fails with a clear error naming any that are missing.

<Warning>
  `base_url` is the **platform host root with no path**. The provider appends each service's API prefix itself, and rejects a `base_url` that carries a path suffix.
</Warning>

## Step 3: Write your first resource

We'll create a data-protection allow-list entry — it has no dependencies, changes no runtime behavior beyond suppressing findings for one harmless literal, and is fully deleted on destroy. Add to `main.tf`:

```hcl main.tf theme={null}
resource "barndoor_dlp_allow_list_entry" "quickstart" {
  pattern      = "docs.example.com"
  pattern_type = "PATTERN_TYPE_LITERAL"
  reason       = "Terraform quickstart — safe to delete"
}
```

Reference: [`barndoor_dlp_allow_list_entry`](https://registry.terraform.io/providers/barndoor-ai/barndoor/latest/docs/resources/dlp_allow_list_entry)

## Step 4: Init, plan, apply

```bash theme={null}
terraform init
terraform plan
```

The plan should show one resource to add. Apply it:

```bash theme={null}
terraform apply
```

```text theme={null}
barndoor_dlp_allow_list_entry.quickstart: Creating...
barndoor_dlp_allow_list_entry.quickstart: Creation complete after 1s

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
```

## Step 5: Verify

Two quick checks that everything is wired correctly:

1. Run `terraform plan` again — it should report `No changes`, confirming that what Terraform created matches what the platform stored.
2. In the Barndoor app, open **Data Control Center** and find the allow-list entry you just created.

## Step 6: Clean up

```bash theme={null}
terraform destroy
```

<Warning>
  For this resource, destroy really deletes the entry. That is **not true of every resource**: destroying a `barndoor_policy` archives it, destroying an org-singleton like `barndoor_dlp_org_config` resets it to platform defaults, and destroying a `barndoor_mcp_server` tears down its connections. Check the resource's Registry page — and see the [destroy semantics table](/terraform/best-practices#destroy-is-not-always-delete) — before destroying anything you care about.
</Warning>

## Next Steps

<CardGroup cols={2}>
  <Card title="Manage MCP Access" icon="shield-halved" href="/terraform/manage-mcp-access">
    Onboard an MCP server, connect it, and govern which AI Agents can use it.
  </Card>

  <Card title="Manage the LLM Gateway" icon="route" href="/terraform/llm-gateway">
    Providers, model routing, access policies, rate limits, and budgets.
  </Card>

  <Card title="Manage Data Protection" icon="user-shield" href="/terraform/data-protection">
    Detection types, allow lists, and enforcement policies.
  </Card>

  <Card title="Best Practices" icon="list-check" href="/terraform/best-practices">
    Importing, drift, CI/CD, and troubleshooting.
  </Card>
</CardGroup>

## Troubleshooting

<AccordionGroup>
  <Accordion title="Token request failed: invalid_client">
    The `client_id` / `client_secret` pair was rejected by the token endpoint. Confirm you exported `BARNDOOR_CLIENT_SECRET` in the shell running Terraform, and that the credential hasn't been rotated (rotation invalidates the old secret) or revoked.
  </Accordion>

  <Accordion title="403 errors mentioning the organization admin role">
    The credential exists but isn't authorized for the operation. This usually means `organization_id` doesn't match the organization the credential was generated in — copy it from the credential panel in **Settings → API Tokens** rather than from elsewhere.
  </Accordion>

  <Accordion title="base_url must be the platform host root">
    The provider rejects a `base_url` with a path suffix (for example a trailing `/api`). Use the bare origin, e.g. `https://platform.barndoor.ai`.
  </Accordion>

  <Accordion title="The provider block validates but apply hangs or times out">
    Check that `base_url` and `token_url` are reachable from the machine running Terraform — corporate proxies and VPNs are the usual cause. The provider uses plain HTTPS with a 30-second timeout per request.
  </Accordion>
</AccordionGroup>
