Skip to main content
The official Rivestack Terraform provider lets you manage clusters, databases, users, extensions, grants, and backups as code.

Installation

Add the provider to your Terraform configuration:
terraform {
  required_providers {
    rivestack = {
      source  = "rivestack/rivestack"
      version = "~> 0.1"
    }
  }
}

provider "rivestack" {}
Requires Terraform >= 1.0.

Authentication

Get your API key from the Rivestack Dashboard. API keys use the rsk_ prefix.

Quick start

This example creates a 2-node HA cluster with a database and user:
terraform {
  required_providers {
    rivestack = {
      source  = "rivestack/rivestack"
      version = "~> 0.1"
    }
  }
}

provider "rivestack" {}

# Create an HA PostgreSQL cluster
resource "rivestack_cluster" "production" {
  name               = "production-cluster"
  region             = "eu-central"
  server_type        = "growth"
  node_count         = 2
  postgresql_version = 18
}

# Create a database
resource "rivestack_cluster_database" "analytics" {
  cluster_id = rivestack_cluster.production.id
  name       = "analytics"
  owner      = rivestack_cluster.production.db_user
}

# Create a user
resource "rivestack_cluster_user" "app_user" {
  cluster_id = rivestack_cluster.production.id
  username   = "app_user"
}

# Outputs
output "cluster_host" {
  value = rivestack_cluster.production.host
}

output "connection_string" {
  value     = rivestack_cluster.production.connection_string
  sensitive = true
}

output "app_user_password" {
  value     = rivestack_cluster_user.app_user.password
  sensitive = true
}
terraform init
terraform plan
terraform apply

Resources

rivestack_cluster

Manages an HA PostgreSQL cluster.
resource "rivestack_cluster" "example" {
  name               = "my-cluster"
  region             = "eu-central"
  server_type        = "starter"
  node_count         = 2
  postgresql_version = 18
}
AttributeTypeRequiredDescription
nameStringYesDisplay name for the cluster
regionStringYesRegion: eu-central or us-east
server_typeStringNoServer size: starter, growth, or scale
node_countNumberNoNumber of nodes (1-3)
postgresql_versionNumberNoPostgreSQL major version (16, 17, or 18)
db_nameStringNoName of the default database
db_typeStringNoCluster type: ha or core_solo
extensionsListNoExtensions to install at creation time
Read-only attributes: id, host, connection_string, db_user, db_password, status, tenant_id, created_at, updated_at

rivestack_cluster_database

Creates a database on a cluster.
resource "rivestack_cluster_database" "example" {
  cluster_id = rivestack_cluster.example.id
  name       = "analytics"
  owner      = rivestack_cluster.example.db_user
}
AttributeTypeRequiredDescription
cluster_idStringYesID of the cluster
nameStringYesDatabase name
ownerStringNoDatabase owner username (defaults to cluster’s default user)

rivestack_cluster_user

Creates a database user with an auto-generated password.
resource "rivestack_cluster_user" "example" {
  cluster_id = rivestack_cluster.example.id
  username   = "app_user"
}
AttributeTypeRequiredDescription
cluster_idStringYesID of the cluster
usernameStringYesUsername (letters, numbers, underscores; max 63 chars)
Read-only attributes: id, password (sensitive)

rivestack_cluster_grant

Grants a user access to a database.
resource "rivestack_cluster_grant" "example" {
  cluster_id = rivestack_cluster.example.id
  username   = rivestack_cluster_user.example.username
  database   = rivestack_cluster_database.example.name
  access     = "read"
}
AttributeTypeRequiredDescription
cluster_idStringYesID of the cluster
usernameStringYesUsername to grant access to
databaseStringYesDatabase to grant access on
accessStringNoAccess level: read (SELECT) or write (SELECT, INSERT, UPDATE, DELETE)
Grant revocation is not currently supported by the API. Destroying this resource removes it from Terraform state only.

rivestack_cluster_extension

Installs a PostgreSQL extension on a database.
resource "rivestack_cluster_extension" "vector" {
  cluster_id = rivestack_cluster.example.id
  extension  = "vector"
  database   = rivestack_cluster_database.example.name
}
AttributeTypeRequiredDescription
cluster_idStringYesID of the cluster
extensionStringYesExtension name (e.g., vector, pg_trgm, pgcrypto)
databaseStringNoTarget database (defaults to cluster’s primary database)
Extensions cannot be removed from running clusters. Destroying this resource removes it from Terraform state only.

rivestack_cluster_backup_config

Configures automated backups for a cluster.
resource "rivestack_cluster_backup_config" "example" {
  cluster_id     = rivestack_cluster.example.id
  enabled        = true
  schedule       = "0 3 * * *"
  retention_full = 14
}
AttributeTypeRequiredDescription
cluster_idStringYesID of the cluster
enabledBooleanYesWhether automated backups are enabled
scheduleStringNoCron schedule (e.g., "0 3 * * *" for daily at 3 AM)
retention_fullNumberNoNumber of days to retain full backups

Data sources

rivestack_cluster

Read information about an existing cluster.
data "rivestack_cluster" "existing" {
  id = "42"
}

output "cluster_host" {
  value = data.rivestack_cluster.existing.host
}
Read-only attributes: name, region, server_type, node_count, postgresql_version, host, connection_string, db_name, db_user, db_password, db_type, status, health_status, tenant_id, created_at, updated_at

rivestack_server_types

List available server configurations.
data "rivestack_server_types" "available" {}

rivestack_extensions

List supported PostgreSQL extensions.
data "rivestack_extensions" "available" {}

Import

Import existing resources into Terraform state:
# Cluster
terraform import rivestack_cluster.example CLUSTER_ID

# Database
terraform import rivestack_cluster_database.example CLUSTER_ID/DATABASE_NAME

# User
terraform import rivestack_cluster_user.example CLUSTER_ID/USERNAME

# Extension
terraform import rivestack_cluster_extension.example CLUSTER_ID/EXTENSION/DATABASE

# Grant
terraform import rivestack_cluster_grant.example CLUSTER_ID/USERNAME/DATABASE

# Backup config
terraform import rivestack_cluster_backup_config.example CLUSTER_ID