Provision a Cluster via Ansible

Provision a Cluster via Ansible

Provision a Cluster via Ansible

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":            "<HOST_NAME>",
      "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":             <USE_SSL>
      "service_name":    "proxmox",
      "proxmox":         true,
      "distributor":     "<OS_DISTRIBUTOR>",
      "release":         "<OS_VERSION>"
    },
    "name":              "<NODE_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_ADMIN_USER>",
    "database_pwd":      "<DB_ADMIN_PASSWORD>",
    "rest_api":          true
  }' \
  <API_BASE_URL>

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 / ex_params.distributor / ex_params.release
  • 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>

Step 3: Translate into Ansible

Directory Structure

├── group_vars/

    └── all.yml

├── deploy.yml

└── destroy.yml

Ansible Parameters

Replace fields in corner brackets <> in parameters file with values extracted from the URL.

File group_vars/all.yml:

# Remote DB service via private API
api_url_create: "<API_BASE_URL>"
api_url_delete: "<API_BASE_URL_DESTROY>" # URL from the UI Destroy cluster page
api_token: "<YOUR_JWT_TOKEN>"

host_name: "<HOST_NAME>"
ssh_port: <SSH_PORT>
ssh_user: "<SSH_USERNAME>"
ssh_password: "<SSH_PASSWORD>"
private_key: "<OPTIONAL_PRIVATE_KEY_CONTENT>"
os_distributor: "<OS_DISTRIBUTOR>"
os_release: <OS_VERSION>

cluster_name: "<CLUSTER_NAME>"
replicaset_name: "<REPLICASET_NAME>"
sizing: "<SIZING>"
repository: "<BACKUP_REPOSITORY>"

db_version: "<DB_VERSION>"
db_port: <DB_PORT>
data_directory: "<DATA_DIRECTORY>"
db_user: "<DB_ADMIN_USER>"
db_password: "<DB_ADMIN_PASSWORD>"

enable_ssl: <USE_SSL>
drop_inventories: <DROP_INVENTORIES>
auto_delete: <AUTO_DELETE>
auto_delete_days: <AUTO_DELETE_DAYS>

Ansible Deploy Playbook

Copy contents as is.

File deploy.yml

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

Ansible Destroy Playbook

Copy contents as is.

File 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

Step 4: Deploy the Stack

Use Terraform to deploy the stack

# Validate the playbooks

ansible-playbook deploy.yml --check

ansible-playbook destroy.yml --check

# Create the stack
ansible-playbook deploy.yml

# Destroy the stack

ansible-playbook destroy.yml

Additional Guidance & Best Practices

Parameterization

All user-specific and environment-specific values are exposed as Ansible variables, making the template portable and reusable across multiple clusters, accounts.

API Versioning

Always verify endpoint and payload requirements with the latest 123cluster API documentation to ensure compatibility. Update the Lambda function code as the API evolves.

No items found.