Deploy Valkey with Terraform

Bahriya provides managed Valkey instances — a Redis-compatible key-value datastore that runs alongside your containers. Use the cache purpose for session stores and query caches you can afford to lose, or the store purpose for persistent workloads like queues and counters.

Updated 12 Aug 20264 min read

Bahriya provides managed Valkey instances — a Redis-compatible key-value datastore that runs alongside your containers. Use the cache purpose for session stores and query caches you can afford to lose, or the store purpose for persistent workloads like queues and counters.

Valkey is rolling out gradually. If it is not yet visible for your organisation, contact support to request access.

Required fields

FieldTypeExampleDescription
handlestring"session-store"Permanent identifier. Cannot be reused after deletion.
namestring"Session Store"Display name.
purposestring"cache"cache (no persistence) or store (persistent, requires storagegb). Immutable after creation.
tierstring"single"single, ha (Sentinel topology) or sharded (cluster topology).
memorymbnumber512Memory per node in megabytes. An integer, not a string.
activeregionslist["falkenstein-1"]One or more regions to deploy to.
projectstringbahriya_project.x.idThe project UUID (not handle).

Minimal example

resource "bahriya_project" "app" {
  handle  = "my-app"
  name    = "My Application"
  regions = ["falkenstein-1"]
}
 
resource "bahriya_valkey" "sessions" {
  handle        = "session-cache"
  name          = "Session Cache"
  purpose       = "cache"
  tier          = "single"
  memorymb      = 256
  activeregions = ["falkenstein-1"]
  project       = bahriya_project.app.id
}

A persistent store with high availability and backups

The store purpose enables RDB+AOF persistence and requires storagegb. The ha tier runs a Sentinel topology — your application needs a Sentinel-aware client driver, and the size axis (standard or hardened) controls the replica count.

resource "bahriya_valkey" "queue" {
  handle        = "job-queue"
  name          = "Job Queue"
  purpose       = "store"
  tier          = "ha"
  size          = "standard"
  memorymb      = 1024
  storagegb     = 10
  activeregions = ["falkenstein-1"]
  project       = bahriya_project.app.id
 
  backupenabled  = true
  backupschedule = "0 3 * * *"
}

Backups are free, taken daily on the schedule you set, and retained as 7 daily snapshots.

External exposure

Any tier can be exposed at the platform edge on port 6379. External access requires all three of TLS, auth and a non-empty IP allowlist — the API rejects a configuration missing any of them.

resource "bahriya_valkey" "shared" {
  handle        = "shared-cache"
  name          = "Shared Cache"
  purpose       = "cache"
  tier          = "single"
  memorymb      = 512
  activeregions = ["falkenstein-1"]
  project       = bahriya_project.app.id
 
  externalenabled = true
  tlsenabled      = true
  authenabled     = true
  allowedips      = ["198.51.100.0/24"]
 
  hostnames = [
    { hostname = "cache.example.com" },
  ]
}

With tlsenabled = true and no tlsbundle, the platform issues a TLS bundle and manages it in your vault. To serve your own certificate, set tlsbundle to the handle of a TLS bundle in your vault — it must cover every hostname the instance answers to.

Custom hostnames are vanity names: point a CNAME at the instance's default per-region hostname (<default_hostname>.<region>.valkey.on.bahriya.app). Note that hostnames is an attributes list — use hostnames = [{ hostname = "..." }], not block syntax.

Sharded cluster with configuration tuning

The sharded tier runs a cluster topology (minimum 3 shards) — your application needs a cluster-aware client driver. shards is grow-only in self-service: raising it is automated, lowering it is handled through a support ticket.

resource "bahriya_valkey" "catalog" {
  handle        = "catalog"
  name          = "Catalog"
  purpose       = "cache"
  tier          = "sharded"
  size          = "hardened"
  shards        = 3
  memorymb      = 2048
  activeregions = ["falkenstein-1", "singapore-1"]
  project       = bahriya_project.app.id
 
  maxmemorypolicy = "allkeys-lfu"
 
  config = {
    "tcp-keepalive" = "300"
    "databases"     = "16"
  }
}

config accepts the allowlisted keys tcp-keepalive, timeout, tcp-backlog, databases and loglevel. Unknown keys are rejected naming the key.

Connecting from a container

Valkey instances are reachable from containers in the same project over the internal network on port 6379:

<valkey-handle>:6379

Pass this as an environment variable to your container:

resource "bahriya_container" "api" {
  # ... other required fields ...
 
  newenvvar = [
    { key = "VALKEY_HOST", value = "session-cache:6379" },
  ]
}

Each region runs an independent copy of the instance with its own data — there is no cross-region replication.

Credentials

Auth is on by default. Set password explicitly, or omit it and the platform generates one — it is never returned by the API, and can be revealed once from the console.

Outputs

AttributeDescription
idValkey instance UUID.
statusCurrent status (running, provisioning, terminated, etc.).
nodesDerived node count per region for the current tier, size and shards.
output "valkey_nodes" {
  value = bahriya_valkey.queue.nodes
}

Notes

  • memorymb and storagegb are integers, not strings.
  • purpose and project are immutable — changing them forces recreation.
  • Handles cannot be reused after deletion.
  • Memory is billed per node; storage is billed per region. The nodes output shows how many nodes your tier/size/shards combination runs per region.