Provisioning a MongoDB Cluster with Terraform
This guide shows how to provision a MongoDB replicaset primary node through 123Cluster using Terraform. The configuration uses the Mastercard/restapi provider to call the 123Cluster REST API, keeping the entire workflow within a standard Terraform plan/apply cycle.
This guide shows how to provision a MongoDB replicaset primary node through 123Cluster using Terraform. The configuration uses the Mastercard/restapi provider to call the 123Cluster REST API, keeping the entire workflow within a standard Terraform plan/apply cycle.
The same pattern extends to any cluster type 123Cluster supports — swap the endpoint path and payload fields for the target database type.
Prerequisites
• Terraform 1.3 or later
• A valid 123Cluster JWT token
• Network access from the machine running Terraform to the 123Cluster API endpoint
Directory structure
terraform/
+-- main.tf # Provider and resource definitions
+-- variables.tf # Input variable declarations
+-- locals.tf # API payload assembly
+-- outputs.tf # Stack outputs
+-- terraform.tfvars # Your environment values (do not commit)
Step 1: Configure values
Populate terraform.tfvars with values from your environment. The api_uri and api_path come from the { REST API } button in the 123Cluster UI — copy the curl command from the cluster creation screen and split the URL at the path boundary.
# terraform.tfvars
api_uri = "https://<your-123cluster-host>/cluster-core/api"
api_path = "/create_mongo_master/"
api_ssl_insecure = true
auth_key = "Bearer <YOUR_JWT_TOKEN>"
host_name = "<HOST_NAME>"
ssh_password = "<SSH_PASSWORD>"
ssh_private_key = ""
os_distro = "<OS_DISTRIBUTOR>" # e.g. centos
os_release = <OS_VERSION> # e.g. 8
cluster_name = "<CLUSTER_NAME>"
replicaset_name = "<REPLICASET_NAME>"
db_version = "<DB_VERSION>" # e.g. 8.0
port = 27017
database_user = "<DB_ADMIN_USER>"
database_pwd = "<DB_ADMIN_PASSWORD>"
create_cluster_in_one_click = true
WARNING Do not commit terraform.tfvars to version control. It contains credentials. Add it to .gitignore and distribute values through your secrets management system or TF_VAR_* environment variables.
Step 2: Provider and resource (main.tf)
The configuration uses the Mastercard/restapi provider, which maps Terraform resource lifecycle event (create) to HTTP method. Copy main.tf as-is.
# main.tf
terraform {
required_providers {
restapi = {
source = "Mastercard/restapi"
version = "1.19.1"
}
}
}
provider "restapi" {
uri = var.api_uri
insecure = var.api_ssl_insecure
write_returns_object = true
debug = true
headers = {
Authorization = var.auth_key
Content-Type = "application/json"
Accept = "application/json"
}
create_method = "POST"
update_method = "POST"
destroy_method = "POST"
}
resource "restapi_object" "deploy" {
path = var.api_path
data = jsonencode(local.call_params)
object_id = local.ret_object_id
}
Step 3: Payload assembly (locals.tf)
locals.tf assembles the JSON payload sent to the 123Cluster API. Optional fields are included conditionally using merge() — if the variable is empty or null, that key is omitted from the request body. Copy locals.tf as-is.
# locals.tf
locals {
call_params = merge(
{
host = {
ssh_port = var.ssh_port
username = var.ssh_user
password = var.ssh_password
private_key = var.ssh_private_key
name = var.host_name
}
cluster = { name = var.cluster_name }
ex_params = local.call_params_ex_params
name = "${var.host_name}:${var.port}"
auto_delete = var.auto_delete
version = var.db_version
auto_delete_days = var.auto_delete_days
port = var.port
sizing = var.sizing
dir_123Cluster = var.data_directory
drop_inventories = var.drop_inventories
database_user = var.database_user
database_pwd = var.database_pwd
rest_api = true
},
var.create_cluster_in_one_click != null
? { create_cluster_in_one_click = var.create_cluster_in_one_click }
: {},
)
call_params_ex_params = merge(
{
repository = var.repository
ssl = var.use_ssl
service_name = var.service_name
proxmox = var.is_proxmox
distributor = var.os_distro
release = var.os_release
},
var.replicaset_name != "" ? { replicaset_name = var.replicaset_name } : {},
var.mongos_port != null ? { mongos_port = var.mongos_port } : {},
var.pg_password != "" ? { pg_password = var.pg_password } : {},
var.repmgr_pwd != "" ? { repmgr_pwd = var.repmgr_pwd } : {},
)
ret_object_id = var.cluster_name
}
Step 4: Variable reference
Step 5: Deploy
# Download the restapi provider
terraform init
# Validate configuration
terraform validate
# Preview what will be created
terraform plan
# Provision the cluster
terraform apply
# Read the API response (marked sensitive, not shown in normal output)
terraform output -json deploy_response
Expected outcome
After terraform apply completes, the cluster appears in the 123Cluster UI under Status. The deploy_response output contains the full JSON response from the API, including node details and connection information.
Because deploy_response is marked sensitive = true in outputs.tf, Terraform redacts it in plan and apply output. Use terraform output -json deploy_response to read the value explicitly.
TIP Set debug = true in the provider block during initial setup to log full request and response bodies. Remove it in production to avoid token exposure in logs.
Security considerations
• auth_key, ssh_password, database_pwd, and ssh_private_key are marked sensitive = true in variables.tf. Terraform redacts these values in plan output and state diffs.
• Use a Terraform backend with state encryption (S3 with SSE or Terraform Cloud) — sensitive values are stored in state in plaintext.
• Set api_ssl_insecure = false and configure a valid TLS certificate on your 123Cluster instance for production deployments.
• Always verify endpoint URLs and payload fields against the latest 123Cluster API documentation after a platform upgrade.

