Complete Terraform Example

This example brings together every Bahriya resource type in a single Terraform configuration: a project, private registry credentials, secrets, a Memcached cache, and an HTTP container wired up to all of them.

Updated 23 Jun 20262 min read

This example brings together every Bahriya resource type in a single Terraform configuration: a project, private registry credentials, secrets, a Memcached cache, and an HTTP container wired up to all of them.

Full configuration

terraform {
  required_providers {
    bahriya = {
      source  = "bahriya-cloud/bahriya"
      version = "~> 0.1"
    }
  }
}
 
provider "bahriya" {}
 
# ---------- Data Sources ----------
 
data "bahriya_organisation" "current" {}
 
data "bahriya_regions" "active" {
  status_filter = "active"
}
 
locals {
  primary_region = data.bahriya_regions.active.regions[0].id
}
 
# ---------- Project ----------
 
resource "bahriya_project" "main" {
  handle  = "my-app"
  name    = "My Application"
  regions = [local.primary_region]
}
 
# ---------- Registry ----------
 
resource "bahriya_registry" "ghcr" {
  handle   = "ghcr"
  name     = "GitHub Container Registry"
  server   = "ghcr.io"
  username = var.ghcr_username
  password = var.ghcr_token
}
 
# ---------- Secrets ----------
 
resource "bahriya_secret" "db_password" {
  handle = "db-password"
  name   = "Database Password"
  value  = var.db_password
}
 
resource "bahriya_secret" "api_key" {
  handle = "api-key"
  name   = "API Key"
  value  = var.api_key
}
 
# ---------- Cache ----------
 
resource "bahriya_memcached" "cache" {
  handle        = "app-cache"
  name          = "Application Cache"
  memorymb      = 512
  activeregions = [local.primary_region]
  project       = bahriya_project.main.id
}
 
# ---------- Container ----------
 
resource "bahriya_container" "api" {
  handle          = "api"
  name            = "API Server"
  image           = "ghcr.io/myorg/api:v2.1.0"
  containerport   = "3000"
  healthcheckpath = "/healthz"
  mincpu          = "500"
  minmemory       = "512"
 
  autoscalingminreplicas = "2"
  autoscalingmaxreplicas = "8"
 
  activeregions = [local.primary_region]
  project       = bahriya_project.main.id
  registry      = bahriya_registry.ghcr.handle
 
  newenvvar {
    key   = "NODE_ENV"
    value = "production"
  }
 
  newenvvar {
    key   = "CACHE_HOST"
    value = "app-cache.${data.bahriya_organisation.current.handle}-my-app:11211"
  }
 
  secretsenvvar {
    secret = bahriya_secret.db_password.handle
    name   = "DATABASE_PASSWORD"
  }
 
  secretsenvvar {
    secret = bahriya_secret.api_key.handle
    name   = "API_KEY"
  }
 
  hostnames {
    hostname = "api.example.com"
  }
}
 
# ---------- Variables ----------
 
variable "ghcr_username" {
  type = string
}
 
variable "ghcr_token" {
  type      = string
  sensitive = true
}
 
variable "db_password" {
  type      = string
  sensitive = true
}
 
variable "api_key" {
  type      = string
  sensitive = true
}
 
# ---------- Outputs ----------
 
output "organisation" {
  value = data.bahriya_organisation.current.handle
}
 
output "project_id" {
  value = bahriya_project.main.id
}
 
output "container_status" {
  value = bahriya_container.api.status
}
 
output "cache_status" {
  value = bahriya_memcached.cache.status
}

Deploying

# Set credentials
export BAHRIYA_TOKEN="pat_..."
export BAHRIYA_ORGANISATION_ID="..."
 
# Set resource variables
export TF_VAR_ghcr_username="myuser"
export TF_VAR_ghcr_token="ghp_..."
export TF_VAR_db_password="s3cret"
export TF_VAR_api_key="ak_..."
 
# Deploy
terraform init
terraform plan
terraform apply

What happens

  1. Terraform creates the project first (other resources depend on it).
  2. The registry, secrets, and Memcached instance are created in parallel.
  3. The container is created last — it references the registry and secrets.
  4. The provider polls until the container and Memcached reach running status.

Tearing down

terraform destroy

Terraform destroys resources in reverse dependency order. Containers and Memcached are terminated asynchronously — the provider waits for them to reach terminated status before completing.

Per-resource guides

For detailed docs on each resource type, see: