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 applyWhat happens
- Terraform creates the project first (other resources depend on it).
- The registry, secrets, and Memcached instance are created in parallel.
- The container is created last — it references the registry and secrets.
- The provider polls until the container and Memcached reach
runningstatus.
Tearing down
terraform destroyTerraform 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: