Provision a Cluster via Terraform

Provision a Cluster via Terraform

A focused, step-by-step tutorial for automating the provisioning of a MongoDB replicaset master node on 123cluster using Terraform with the Mastercard/restapi provider, demonstrating how to capture the REST API curl command from the UI, deconstruct its headers and payload, translate them into Terraform variables and resources, and integrate the process into a repeatable CI/CD workflow.

Step 1: Copy the curl Command from the UI
On the Create a new replicaset (Master) 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_CONTENT>"
    },
    "cluster": {
      "name":         "<CLUSTER_NAME>"
    },
    "ex_params": {
      "replicaset_name": "<REPLICASET_NAME>",
      "repository":      "<BACKUP_REPOSITORY>",
      "ssl":             false
    },
    "name":              "<NODE_NAME>",
    "auto_delete":       false,
    "version":           "<MONGODB_VERSION>",
    "auto_delete_days":  1,
    "port":              <MONGO_PORT>,
    "sizing":            "SMALL",
    "dir_123Cluster":    "<DATA_DIRECTORY>",
    "drop_inventories":  false,
    "database_user":     "<DB_ADMIN_USER>",
    "database_pwd":      "<DB_ADMIN_PASSWORD>",
    "rest_api":          true
  }' \
  <API_BASE_URL>/create_mongo_master/

Step 2: Parse the curl Command

  • Authorization header
    Extract your JWT token from Bearer <YOUR_JWT_TOKEN>.
  • Content-Type & Accept
    Preserve both application/json headers.
  • Payload fields
    • host.name / host.ssh_port / host.username / host.password / host.private_key
    • cluster.name
    • ex_params.replicaset_name / ex_params.repository / ex_params.ssl
    • name (node identifier)
    • auto_delete / auto_delete_days
    • version / port / sizing / dir_123Cluster / drop_inventories
    • database_user / database_pwd
    • rest_api
  • Endpoint
    • Base URI: <API_BASE_URL>
    • Resource path: /create_mongo_master/

Step 3: Translate into Terraform

  • Create directory & file
integration/
└── terraform/
    └── create_replicaset_master/
        └── main.tf
  • Provider block
// Terraform configuration for provisioning a MongoDB replicaset master node in 123cluster
terraform {
  required_providers {
    restapi = {
      source  = "Mastercard/restapi"
      version = "1.19.1" // Pin provider version for consistency and reproducibility
    }
  }
}

/*
  REST API provider configuration:
  - uri: Base endpoint for 123cluster API requests.
  - headers: Authentication and content negotiation for REST API.
  - write_returns_object: Ensures outputs are object-typed for further usage.
  - debug: Enables detailed logging for troubleshooting.
  - HTTP methods: POST for create/update/destroy 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 valid JWT token for API authentication
    Content-Type  = "application/json"
    Accept        = "application/json"
  }
  create_method  = "POST"
  update_method  = "POST"
  destroy_method = "POST"
}
  • Variable declarations
/*
  Input variables for all relevant parameters.
  - Facilitates reuse across environments and automation 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 initial host setup"
  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 new MongoDB replicaset cluster"
  type        = string
  default     = "<CLUSTER_NAME>"
}

variable "replicaset_name" {
  description = "Internal replicaset identifier"
  type        = string
  default     = "<REPLICASET_NAME>"
}

variable "repository" {
  description = "Backup repository location"
  type        = string
  default     = "<BACKUP_REPOSITORY>"
}

variable "mongodb_version" {
  description = "Desired MongoDB version"
  type        = string
  default     = "<MONGODB_VERSION>"
}

variable "mongo_port" {
  description = "MongoDB service port"
  type        = number
  default     = <MONGO_PORT>
}

variable "data_directory" {
  description = "Data directory for MongoDB files"
  type        = string
  default     = "<DATA_DIRECTORY>"
}

variable "database_user" {
  description = "Database administrator username"
  type        = string
  default     = "<DB_ADMIN_USER>"
}

variable "database_pwd" {
  description = "Database administrator password"
  type        = string
  default     = "<DB_ADMIN_PASSWORD>"
}
  • Resource definition
/*
  This resource maps all required parameters from variables into the API payload.
  - Uses jsonencode() for correct JSON formatting.
  - All fields from the reference curl command are represented and can be parameterized.
  - Handle sensitive values securely in real environments.
*/
resource "restapi_object" "create_master" {
  path = "/create_mongo_master/"
  data = jsonencode({
    host = {
      name        = var.mongo_host_ip
      ssh_port    = var.ssh_port
      username    = var.ssh_user
      password    = var.ssh_password
      private_key = "" // Optionally set var.private_key if required
    }
    cluster = {
      name = var.cluster_name
    }
    ex_params = {
      replicaset_name = var.replicaset_name
      repository      = var.repository
      ssl             = false // SSL can be parameterized if needed
    }
    name              = var.cluster_name // Node identifier; matches cluster name for master
    auto_delete       = false            // Prevents auto-deletion
    version           = var.mongodb_version
    auto_delete_days  = 1                // Retention period before auto-delete (if enabled)
    port              = var.mongo_port
    sizing            = "SMALL"          // Resource size; adjust as needed
    dir_123Cluster    = var.data_directory
    drop_inventories  = false            // Retain inventories after setup
    database_user     = var.database_user
    database_pwd      = var.database_pwd
    rest_api          = true             // Enables management via REST API
  })
}
  • Output block
/*
  Output the full JSON response from the create_mongo_master API call.
  - Useful for logging, audit, or passing to downstream workflows.
*/
output "master_response" {
  description = "Raw JSON response from create_mongo_master"
  value       = restapi_object.create_master.data
}

Step 4: Initialize & Apply

cd integration/terraform/create_replicaset_master
# 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 master_response

Additional Guidance & Best Practices

  • Parameterization: By exposing all user-specific and environment-specific values as Terraform variables, the configuration is portable and reusable across multiple clusters and environments.
  • Security: Store sensitive values (passwords, private keys, tokens) securely using environment variables, secrets management, or Terraform's sensitive variable types.
  • CI/CD Integration: Integrate these steps into a CI/CD workflow for fully automated and consistent cluster provisioning.
  • API Versioning: Always verify endpoint and payload requirements with the latest 123cluster API documentation to ensure compatibility.