Provision a Standby via Terraform
A focused, step-by-step tutorial for provisioning an additional MongoDB standby node in an existing replicaset on 123cluster using Terraform with the Mastercard/restapi provider, demonstrating how to extract the REST API curl command from the UI, parse its JSON payload, map each field to Terraform variables and resources, and produce a reproducible CI/CD–ready workflow.
Step 1: Copy the curl
Command from the UI
On the Add a new standby node screen, click { REST API }. The following example is copied:
curl -v \
-H "Authorization: Bearer <YOUR_JWT_TOKEN>" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"host": {
"name": "<MONGO_HOST_IP>",
"ssh_port": <SSH_PORT>,
"username": "<SSH_USERNAME>",
"password": "<SSH_PASSWORD>",
"private_key": "<OPTIONAL_PRIVATE_KEY>"
},
"cluster": {
"name": "<CLUSTER_NAME>"
},
"ex_params": {
"replicaset_name": "<REPLICASET_NAME>",
"mongo_master_id": <MONGO_MASTER_ID>,
"voting": true
},
"name": "<NODE_NAME>",
"auto_delete": false,
"version": "<MONGODB_VERSION>",
"auto_delete_days": 1,
"port": <MONGO_PORT>,
"sizing": "SMALL",
"cluster_role": "STANDBY",
"dir_123Cluster": "<DATA_DIRECTORY>",
"drop_inventories": false,
"rest_api": true
}' \
<API_BASE_URL>/create_mongo_node/
Step 2: Parse the curl
Command
- JWT Token: Copy the string following
Bearer
. - Headers: Retain both
Content-Type: application/json
andAccept: application/json
. - Payload fields:
host.name
/host.ssh_port
/host.username
/host.password
/host.private_key
cluster.name
ex_params.replicaset_name
/ex_params.mongo_master_id
/ex_params.voting
name
auto_delete
/auto_delete_days
version
/port
/sizing
/cluster_role
dir_123Cluster
/drop_inventories
rest_api
- Endpoint:
- Base URI:
<API_BASE_URL>
- Resource path:
/create_mongo_node/
- Base URI:
Step 3: Translate into Terraform
- Create directory & file
integration/
└── terraform/
└── create_standby_node/
└── main.tf
- Provider block
// Terraform configuration for automating the creation of a MongoDB standby node in 123cluster
terraform {
required_providers {
restapi = {
source = "Mastercard/restapi"
version = "1.19.1" // Always specify a stable provider version for reproducibility
}
}
}
/*
REST API provider configuration:
- uri: Base API endpoint for 123cluster.
- headers: HTTP headers needed for authentication and JSON content negotiation.
- write_returns_object: Enables response as an object for downstream usage.
- debug: Turns on verbose request/response logging.
- HTTP methods: POST is used for create, update, and destroy operations, as required by the API.
*/
provider "restapi" {
uri = "<API_BASE_URL>"
write_returns_object = true
debug = true
headers = {
Authorization = "Bearer <YOUR_JWT_TOKEN>" // Use a secure JWT for authenticated API access
Content-Type = "application/json"
Accept = "application/json"
}
create_method = "POST"
update_method = "POST"
destroy_method = "POST"
}
- Variable declarations
/*
All critical configuration values are exposed as variables.
This approach ensures the code is reusable in different environments and automatable in CI/CD pipelines.
*/
variable "mongo_host_ip" {
description = "IP address of the MongoDB host"
type = string
default = "<MONGO_HOST_IP>"
}
variable "ssh_port" {
description = "SSH port for host access"
type = number
default = <SSH_PORT>
}
variable "ssh_user" {
description = "SSH username"
type = string
default = "<SSH_USERNAME>"
}
variable "ssh_password" {
description = "SSH password"
type = string
default = "<SSH_PASSWORD>"
}
variable "cluster_name" {
description = "Name of the MongoDB cluster"
type = string
default = "<CLUSTER_NAME>"
}
variable "replicaset_name" {
description = "Name of the replicaset"
type = string
default = "<REPLICASET_NAME>"
}
variable "mongo_master_id" {
description = "ID of the master node to which this standby will connect"
type = number
default = <MONGO_MASTER_ID>
}
variable "node_name" {
description = "Identifier for this standby node"
type = string
default = "<NODE_NAME>"
}
variable "mongodb_version" {
description = "Desired MongoDB version for the standby node"
type = string
default = "<MONGODB_VERSION>"
}
variable "mongo_port" {
description = "MongoDB port on the standby node"
type = number
default = <MONGO_PORT>
}
variable "data_directory" {
description = "Data directory for MongoDB data files"
type = string
default = "<DATA_DIRECTORY>"
}
- Resource definition
/*
This resource maps all required parameters from variables to the API payload.
- Uses jsonencode() to serialize the request data.
- All required fields from the original curl command are present and parameterized.
- Sensitive values should be handled securely in production.
*/
resource "restapi_object" "create_standby" {
path = "/create_mongo_node/"
data = jsonencode({
host = {
name = var.mongo_host_ip
ssh_port = var.ssh_port
username = var.ssh_user
password = var.ssh_password
private_key = "" // Optionally use a variable for private_key if required
}
cluster = {
name = var.cluster_name
}
ex_params = {
replicaset_name = var.replicaset_name
mongo_master_id = var.mongo_master_id
voting = true // This standby node will participate in voting for the replicaset
}
name = var.node_name
auto_delete = false // Prevent automatic deletion of the node
version = var.mongodb_version
auto_delete_days = 1
port = var.mongo_port
sizing = "SMALL"
cluster_role = "STANDBY" // Designate this node as a standby (secondary)
dir_123Cluster = var.data_directory
drop_inventories = false
rest_api = true // Allows future API management
})
}
- Output block
/*
Output the full JSON response from the API.
This is helpful for debugging, logging, or extracting details for further automation.
*/
output "standby_response" {
description = "Raw JSON response from create_mongo_node"
value = restapi_object.create_standby.data
}
Step 4: Initialize & Apply
cd integration/terraform/create_standby_node
# Initialize the Terraform working directory and download necessary providers
terraform init
# Apply the configuration, review the planned actions, and confirm execution
terraform apply
# Output the API response for logging or integration with other tools
terraform output standby_response
Additional Guidance & Best Practices
- Parameterization: By defining all configuration details as Terraform variables, you ensure the setup is modular, reusable, and easy to maintain across different clusters or environments.
- Security: Always store sensitive credentials (such as passwords, SSH keys, tokens) securely—use environment variables, a secret manager, or mark variables as sensitive within Terraform.
- CI/CD Integration: Integrate these Terraform steps into your CI/CD pipeline for automated, consistent, and auditable standby node provisioning.
- API Compatibility: Regularly check 123cluster API documentation for any updates to endpoints or payloads to avoid compatibility issues.
- Logging & Outputs: Use Terraform outputs to capture the full API response for tracking, debugging, or triggering downstream processes.
- Isolation: Utilize Terraform workspaces to separate resources and manage deployments for dev, test, and production environments independently.
- Error Handling: Implement validation and error handling in your pipeline to catch API errors early and prevent misconfigurations or partial deployments.