Skip to main content
Use the official Terraform provider to manage control plane resources. The provider supports:
  • Resources
    • s2_basin
    • s2_stream
    • s2_access_token
  • Data sources
    • s2_basin
    • s2_stream
resource blocks are managed by Terraform (create/update/delete).
data blocks are read-only lookups for existing resources.

Prerequisites

  • Terraform >= 1.5.0
  • An S2 access token (S2_ACCESS_TOKEN)

Quickstart

1

Set your credentials

export S2_ACCESS_TOKEN="<your access token>"
# Optional (for self-hosted or s2-lite):
# export S2_BASE_URL="https://aws.s2.dev/v1"
2

Create a Terraform config

terraform {
  required_providers {
    s2 = {
      source  = "s2-streamstore/s2"
      version = "~> 0.1"
    }
  }
}

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
}
3

Initialize and apply

terraform init
terraform apply

Authentication and Endpoint Configuration

You can configure credentials in provider config or through environment variables:
provider "s2" {
  # optional if S2_ACCESS_TOKEN is set
  access_token = var.s2_access_token

  # optional (defaults to S2 cloud endpoint)
  base_url     = var.s2_base_url
}
Environment variables:
  • S2_ACCESS_TOKEN
  • S2_BASE_URL (optional)

Resource Examples

Basin with defaults

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

resource "s2_stream" "orders" {
  basin = s2_basin.analytics.name
  name  = "orders"

  storage_class = "express"

  retention_policy {
    age = 86400
  }

  timestamping {
    mode = "arrival"
  }
}

Scoped access token

resource "s2_access_token" "consumer" {
  token_id = "consumer-token"

  scope = {
    basins = {
      exact = s2_basin.analytics.name
    }
    streams = {
      prefix = "orders"
    }
    ops = ["read"]
  }
}
The issued token value is marked as sensitive, but still lives in Terraform state.

Import Existing Infrastructure

Import formats:
  • Basin: <basin-name>
  • Stream: <basin-name>/<stream-name>
  • Access token: <token-id>
Examples:
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 a base URL:
export S2_BASE_URL="http://127.0.0.1:18080/v1"
export S2_ACCESS_TOKEN="test"
Access-token API is not supported with s2-lite.
  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.