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.

