Terraform Provider

The official Bahriya Terraform provider lets you manage your entire Bahriya infrastructure as code — projects, containers, registries, secrets, Memcached, vault items (TLS bundles, X.509 certs, GPG and SSH keypairs, encryption keys), and config items (env files, YAML / JSON / plain text). It is published on the HashiCorp Terraform Registry.

Updated 23 Jun 20264 min read

The official Bahriya Terraform provider lets you manage your entire Bahriya infrastructure as code — projects, containers, registries, secrets, Memcached, vault items (TLS bundles, X.509 certs, GPG and SSH keypairs, encryption keys), and config items (env files, YAML / JSON / plain text). It is published on the HashiCorp Terraform Registry.

Why Terraform

  • Declarative — describe the desired state, Terraform figures out the changes.
  • Version-controlled — commit your .tf files and review changes like any other code.
  • Repeatable — spin up identical environments for staging and production from the same config.
  • Composable — combine Bahriya resources with other providers (DNS, monitoring, CI/CD) in a single plan.

Installation and authentication

See the Installation guide for full details on installing Terraform, adding the provider, authenticating with a personal access token, version pinning, upgrading, and CI/CD usage.

Quick start:

terraform {
  required_providers {
    bahriya = {
      source  = "bahriya-cloud/bahriya"
      version = "~> 0.1"
    }
  }
}
 
provider "bahriya" {}
export BAHRIYA_TOKEN="pat_..."
export BAHRIYA_ORGANISATION_ID="your-org-uuid"
terraform init

Available resources

ResourceDescriptionGuide
bahriya_projectLogical grouping for containers, secrets, and registriesProjects
bahriya_containerHTTP service, background worker, or scheduled cron jobHTTP containers, Workers, Cron jobs
bahriya_registryPrivate container registry credentialsRegistries
bahriya_secretEncrypted secret, mountable as an env var in a containerSecrets
bahriya_memcachedManaged Memcached instanceMemcached
bahriya_tls_bundleTLS bundle (CA + cert + key)TLS Bundles
bahriya_x509_certStandalone X.509 certificateX.509 Certificates
bahriya_gpg_keypairGPG public + private keypairGPG Keypairs
bahriya_ssh_keypairSSH public + private keypairSSH Keypairs
bahriya_encryption_keySymmetric encryption key (AES / ChaCha20)Encryption Keys
bahriya_env_fileKEY=VALUE env file, injected via envFromEnv Files
bahriya_yaml_configYAML configuration file, mounted as a fileYAML Configs
bahriya_json_configJSON configuration file, mounted as a fileJSON Configs
bahriya_plain_configArbitrary text file, mounted as a filePlain Configs

Each vault and config item can be attached to a project (bahriya_project_<type>_attachment) to make it available in the project's regions, then referenced from a bahriya_container to mount it inside the container (as a file, or as env vars for env files).

Data sources

Data sourceDescription
bahriya_organisationYour current organisation (name, handle, email)
bahriya_regionLook up a single region by ID
bahriya_regionsList all regions, with optional status filter

Field naming

The Terraform provider uses the same flat field names as the Bahriya API. These are not snake_case — they are lowercase with no separators:

You might expectActual field name
container_portcontainerport
health_check_pathhealthcheckpath
min_cpumincpu
min_memoryminmemory
active_regionsactiveregions
min_replicasautoscalingminreplicas
max_replicasautoscalingmaxreplicas
memory_mbmemorymb

Quickstart

Deploy an HTTP container in under 30 lines:

terraform {
  required_providers {
    bahriya = { source = "bahriya-cloud/bahriya" }
  }
}
 
provider "bahriya" {}
 
resource "bahriya_project" "web" {
  handle  = "web-prod"
  name    = "Web Production"
  regions = ["falkenstein-1"]
}
 
resource "bahriya_container" "api" {
  handle          = "api"
  name            = "API Server"
  image           = "nginx:alpine"
  containerport   = "80"
  healthcheckpath = "/"
  mincpu          = "100"
  minmemory       = "128"
 
  autoscalingminreplicas = "1"
  activeregions          = ["falkenstein-1"]
  project                = bahriya_project.web.id
}
terraform init
terraform plan
terraform apply

Important behaviours

Handles are permanent

For projects, containers, and Memcached instances, handles cannot be reused after the resource is deleted. Treat them as permanent identifiers and use distinct handles per environment (e.g. api-prod, api-staging).

Registry and secret handles are released on delete and can be reused.

Project references use UUIDs

When a resource needs a project attribute, pass the project UUID — not the handle:

project = bahriya_project.web.id    # correct
project = bahriya_project.web.handle # wrong — will fail

Async creation

Container and Memcached creation can take several minutes. The provider polls the API until the resource reaches running status (default timeout: 10 minutes).

Importing existing resources

terraform import bahriya_container.api <uuid>

Per-resource guides

Each resource has a dedicated article with a complete working example: