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

# Terraform Provider

> Manage S2 basins, streams, and access tokens declaratively with Terraform, including managed S2 and self-hosted s2-lite.

Use the Terraform provider to manage control plane resources.

* Provider source: `s2-streamstore/s2`
* GitHub: [s2-streamstore/terraform-provider-s2](https://github.com/s2-streamstore/terraform-provider-s2)
* Registry: [registry.terraform.io/providers/s2-streamstore/s2](https://registry.terraform.io/providers/s2-streamstore/s2/latest)

The provider supports:

* **Resources**
  * `s2_basin`
  * `s2_stream`
  * `s2_access_token`
* **Data sources**
  * `s2_basin`
  * `s2_stream`

<Note>
  `resource` blocks are managed by Terraform (create/update/delete).\
  `data` blocks are read-only lookups for existing resources.
</Note>

## Prerequisites

* Terraform `>= 1.5.0`
* An S2 access token (`S2_ACCESS_TOKEN`)

## Quickstart

<Steps>
  <Step title="Set your credentials">
    ```bash theme={null}
    export S2_ACCESS_TOKEN="<your access token>"
    # Optional (for self-hosted or s2-lite):
    # export S2_ACCOUNT_ENDPOINT="aws.s2.dev"
    ```
  </Step>

  <Step title="Create a Terraform config">
    ```hcl theme={null}
    terraform {
      required_providers {
        s2 = {
          source  = "s2-streamstore/s2"
          version = "~> 0.2"
        }
      }
    }

    provider "s2" {}

    resource "s2_basin" "main" {
      name = "my-example-basin"
    }

    resource "s2_stream" "events" {
      basin = s2_basin.main.name
      name  = "events"
    }

    data "s2_basin" "readback" {
      name = s2_basin.main.name
    }
    ```
  </Step>

  <Step title="Initialize and apply">
    ```bash theme={null}
    terraform init
    terraform apply
    ```
  </Step>
</Steps>

## Authentication and Endpoint Configuration

You can configure credentials in provider config or through environment variables:

```hcl theme={null}
provider "s2" {
  # optional if S2_ACCESS_TOKEN is set
  access_token = var.s2_access_token

  # optional
  account_endpoint = var.s2_account_endpoint

  # optional
  basin_endpoint   = var.s2_basin_endpoint
}
```

Environment variables:

* `S2_ACCESS_TOKEN`
* `S2_ACCOUNT_ENDPOINT` (optional)
* `S2_BASIN_ENDPOINT` (optional, supports `{basin}` placeholder e.g. `{basin}.b.s2.dev`)

## Resource Examples

### Basin with defaults

```hcl theme={null}
resource "s2_basin" "analytics" {
  name                    = "analytics-events"
  create_stream_on_append = true
  create_stream_on_read   = false

  default_stream_config {
    storage_class = "standard"

    retention_policy {
      age = 604800
    }

    timestamping {
      mode     = "client-prefer"
      uncapped = false
    }
  }
}
```

### Stream config

```hcl theme={null}
resource "s2_stream" "orders" {
  basin = s2_basin.analytics.name
  name  = "orders"

  storage_class = "express"

  retention_policy {
    age = 86400
  }

  timestamping {
    mode = "arrival"
  }
}
```

### Scoped access token

```hcl theme={null}
resource "s2_access_token" "consumer" {
  token_id = "consumer-token"

  scope = {
    basins = {
      exact = s2_basin.analytics.name
    }
    streams = {
      prefix = "orders"
    }
    ops = ["read"]
  }
}
```

<Warning>
  The issued token value is marked as sensitive, but still lives in Terraform state.
</Warning>

## Import Existing Infrastructure

Import formats:

* Basin: `<basin-name>`
* Stream: `<basin-name>/<stream-name>`
* Access token: `<token-id>`

Examples:

```bash theme={null}
terraform import s2_basin.main my-basin
terraform import s2_stream.events my-basin/events
terraform import s2_access_token.consumer my-token-id
```

## Using with s2-lite

When targeting s2-lite, set the account endpoint:

```bash theme={null}
export S2_ACCOUNT_ENDPOINT="localhost:18080"
export S2_ACCESS_TOKEN="test"
```

<Note>
  Access-token API is not supported with s2-lite.
</Note>

## Recommended Workflow

1. Pin a provider version in `required_providers`.
2. Commit `.terraform.lock.hcl`.
3. Use `terraform plan` to preview changes before applying.
4. Use `terraform import` for existing resources rather than recreating.

## Related Docs

* [Concepts: Basins](/concepts/basins)
* [Concepts: Access Tokens](/concepts/access-tokens)
* [API Endpoints](/api/endpoints)
