Provisioning a MongoDB Cluster with Terraform

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

Parameter Description
api_uri Base URL of the 123Cluster API, without the path. E.g. https://your-host/cluster-core/api.
api_path API endpoint path. E.g. /create_mongo_master/. Copy from the { REST API } curl command.
api_ssl_insecure Skip TLS certificate verification. Set to false in production with a valid certificate.
auth_key Full Authorization header value, including the Bearer prefix. Marked sensitive.
ssh_port SSH port on the target host. Default: 22.
ssh_user SSH login username for admin user. Default: root.
ssh_password SSH password. Marked sensitive.
ssh_private_key PEM private key for key-based SSH. Leave empty to use password auth. Marked sensitive.
host_name Hostname of the target server. Not applicable for clusters.
cluster_name Display name for the cluster in 123Cluster. Used as the Terraform object_id.
replicaset_name MongoDB internal replicaset identifier. Typically matches cluster_name.
repository Backup repository type. Default: network.
use_ssl Enable TLS for MongoDB connections. Default: false.
service_name Hosting infrastructure service. Default: proxmox.
is_proxmox Set to true when deploying on Proxmox. Default: true.
os_distro Linux distribution on the target host. E.g. centos, ubuntu.
os_release OS major version number.
db_version MongoDB version to install.
port MongoDB service port. Default: 27017.
mongos_port Optional mongos router port for sharded deployments. Omitted from payload if null.
data_directory Filesystem path for MongoDB data files on the target host.
database_user MongoDB admin username.
database_pwd MongoDB admin password. Marked sensitive.
sizing Cluster size tier. SMALL | MEDIUM | LARGE | VERY_LARGE. Default: SMALL.
pg_password PostgreSQL admin password. Omitted from payload if empty.
repmgr_pwd Repmgr replication manager password. Omitted from payload if empty.
certificate_authentication Use certificate-based auth. Omitted from payload if null.
create_cluster_in_one_click Trigger immediate full provisioning. Omitted from payload if null.
auto_delete Automatically delete the cluster after auto_delete_days. Default: false.
auto_delete_days Days before automatic deletion. Default: 1.
drop_inventories Delete all backups and exports before teardown. Default: false.

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.

No items found.