Provisioning a MongoDB Cluster with Ansible

Provisioning a MongoDB Cluster with Ansible

123Cluster exposes a REST API for every provisioning operation available in the UI. This guide walks through calling that API from an Ansible playbook — a repeatable, version-controlled alternative to clicking through the interface.The example provisions a MongoDB replicaset primary node on a Proxmox host. The same pattern applies to any cluster type 123Cluster supports.

123Cluster exposes a REST API for every provisioning operation available in the UI. This guide walks through calling that API from an Ansible playbook — a repeatable, version-controlled alternative to clicking through the interface.

The example provisions a MongoDB replicaset primary node on a Proxmox host. The same pattern applies to any cluster type 123Cluster supports.

 

Prerequisites

•       Ansible 2.9 or later installed on the control node

•       A valid 123Cluster JWT token (obtained from the UI under your user profile)

•       Network access from the Ansible control node to the 123Cluster API endpoint

 How it works

Every provisioning screen in the 123Cluster UI has a { REST API } button. Clicking it reveals the exact curl command the UI would send — with all selected options pre-filled into the JSON payload. The workflow is:

1.    Configure the cluster in the UI as you normally would.

2.    Click { REST API } to copy the curl command.

3.    Extract the endpoint URL, headers, and payload fields.

4.    Populate the Ansible variables file with those values.

5.    Run the playbook.

 

NOTE  The JWT token in the curl output is your personal session token. For production use, generate a dedicated service account token with the minimum required permissions.

 

Directory structure

ansible/
├── group_vars/
│   └── all.yml   	# All configurable parameters
├── deploy.yml    	# Provisions the cluster
└── destroy.yml   	# Removes the cluster

 

Step 1: Configure variables

All parameters are declared in group_vars/all.yml. Replace every placeholder in angle brackets with the values from your curl command and environment.

# group_vars/all.yml
 
# API connection
api_url_create: "<API_BASE_URL>"          # e.g. https://your-123cluster-host/cluster-core/api/create_mongo_master/
api_url_delete: "<API_BASE_URL_DESTROY>"  # from the UI Destroy cluster screen
api_token:  	"<YOUR_JWT_TOKEN>"
 
# Target host
host_name:  	"<HOST_NAME>"
ssh_port:   	22
ssh_user:   	"root"
ssh_password:   "<SSH_PASSWORD>"
private_key:	""        	# optional: paste PEM content if using key auth
os_distributor: "<OS_DISTRIBUTOR>"   # e.g. centos, ubuntu
os_release: 	<OS_VERSION>     	# e.g. 8
 
# Cluster identity
cluster_name:  	"<CLUSTER_NAME>"
replicaset_name:   "<REPLICASET_NAME>"
sizing:        	"<SIZING>"     	# SMALL | MEDIUM | LARGE | VERY_LARGE
repository:    	"network"
 
# Database settings
db_version:  	"<DB_VERSION>"   	# e.g. 8.0
db_port:     	27017
data_directory:  "/123cluster/mongo/data1"
db_user:     	"<DB_ADMIN_USER>"
db_password: 	"<DB_ADMIN_PASSWORD>"
 
# Behaviour flags
enable_ssl:   	false
drop_inventories: false
auto_delete:  	false
auto_delete_days: 1

 

Step 2: The deploy playbook

The deploy.yml playbook sends a single POST request to the 123Cluster API. Copy it as-is — all configuration is handled through the variables file.

# deploy.yml
- name: Deploy web app locally and provision DB via REST API
  hosts: localhost
  connection: local
  gather_facts: false
 
  tasks:
	- name: Create DB cluster
  	ansible.builtin.uri:
    	url: "{{ api_url_create }}"
    	validate_certs: false
    	method: POST
    	headers:
      	Authorization: "Bearer {{ api_token }}"
      	Content-Type: "application/json"
      	Accept: "application/json"
    	body_format: json
    	body:
      	host:
        	name: "{{ host_name }}"
        	ssh_port: "{{ ssh_port }}"
        	username: "{{ ssh_user }}"
        	password: "{{ ssh_password }}"
        	private_key: "{{ private_key }}"
      	cluster:
        	name: "{{ cluster_name }}"
      	ex_params:
        	replicaset_name: "{{ replicaset_name }}"
        	repository: "{{ repository }}"
        	ssl: "{{ enable_ssl }}"
        	service_name: "proxmox"
        	proxmox: true
        	distributor: "{{ os_distributor }}"
        	release: "{{ os_release }}"
      	name: "{{ cluster_name }}"
      	auto_delete: "{{ auto_delete }}"
      	version: "{{ db_version }}"
      	auto_delete_days: "{{ auto_delete_days }}"
      	port: "{{ db_port }}"
      	sizing: "{{ sizing }}"
      	dir_123Cluster: "{{ data_directory }}"
      	drop_inventories: "{{ drop_inventories }}"
      	database_user: "{{ db_user }}"
      	database_pwd: "{{ db_password }}"
      	rest_api: true
    	status_code: [200, 201, 202, 409]
  	register: api_result

 

NOTE  Status code 409 is accepted. 123Cluster returns 409 when a cluster with the same name already exists — treating this as non-fatal makes the playbook idempotent.

 

Step 3: The destroy playbook

The destroy.yml playbook removes the cluster. It sends a POST to the delete endpoint with the cluster identifier and takes a final backup before deletion.

# destroy.yml
- name: Stop web app locally and deprovision DB via REST API
  hosts: localhost
  connection: local
  gather_facts: false
 
  tasks:
	- name: Delete DB cluster
  	ansible.builtin.uri:
    	url: "{{ api_url_delete }}"
    	validate_certs: false
    	method: POST
    	headers:
      	Authorization: "Bearer {{ api_token }}"
      	Content-Type: "application/json"
      	Accept: "application/json"
    	body_format: json
    	body:
      	cluster_id: "{{ cluster_name }}"
      	type: "MONGO"
      	final_backup: true
      	rest_api: true
    	status_code: [200, 202, 404]
  	register: api_result

 

NOTE  Status 404 is accepted on destroy — if the cluster was already removed, the playbook completes without error. Set final_backup: false to skip the pre-deletion backup.

 

Step 4: Run the playbooks

# Dry-run to validate without making API calls
ansible-playbook deploy.yml --check
ansible-playbook destroy.yml --check
 
# Provision the cluster
ansible-playbook deploy.yml
 
# Remove the cluster
ansible-playbook destroy.yml

 

Expected outcome

After deploy.yml completes successfully, the cluster appears in the 123Cluster UI under Status. The api_result variable holds the full API response. Use debug: var=api_result after the URI task to inspect it.

Provisioning typically takes 2–5 minutes depending on host size and network conditions. The playbook blocks until the API returns a terminal status code.

 

Security considerations

•       Store api_token, ssh_password, private_key, and db_password in Ansible Vault rather than plaintext in group_vars/all.yml.

•       Do not commit the populated group_vars/all.yml to version control. Add it to .gitignore. This can be omitted if no secrets are stored directly in the file.

•       The validate_certs: false setting in both playbooks (deploy.yml and destroy.yml) disables TLS verification. Remove this line in production once a valid certificate is in place.

•       Always verify the endpoint URL and payload structure against the latest 123Cluster API documentation after a platform upgrade.

No items found.