Skip to main content

Provisioning an OpenSearch Cluster on FoundryDB and Connecting via TLS

· 4 min read
FoundryDB Team
Engineering @ FoundryDB

FoundryDB manages the full lifecycle of OpenSearch: VM provisioning, TLS certificates, DNS, and credentials. You get a production-ready cluster endpoint in about 6 minutes. This post covers provisioning via the API, fetching credentials, verifying TLS, and confirming cluster health.

All examples use confirmed output from OpenSearch 2.19.1 running on FoundryDB staging.

What You Get

  • OpenSearch 2.19.1, single-node or multi-node
  • HTTPS on port 9200, enforced (no plain HTTP)
  • Let's Encrypt certificate scoped to *.foundrydb.com
  • DNS provisioned automatically (e.g. opensearch-myservice-b6cb5f23-e3565ebb-db.foundrydb.com)
  • Single node includes the cluster_manager, data, ingest, and remote_cluster_client roles

Prerequisites

  • A FoundryDB account and API credentials
  • curl, jq, and openssl installed locally

Step 1: Provision the Service

curl -u admin:YOUR_PASSWORD -X POST https://api.foundrydb.com/managed-services \
-H "Content-Type: application/json" \
-d '{
"name": "my-opensearch",
"database_type": "opensearch",
"version": "2.19",
"plan_name": "tier-2",
"zone": "se-sto1",
"storage_size_gb": 50,
"storage_tier": "maxiops"
}'

The response includes a service id. Poll until status reaches running:

curl -u admin:YOUR_PASSWORD https://api.foundrydb.com/managed-services/SERVICE_ID \
| jq '{status: .status, host: .dns_records[0].full_domain}'

On staging, provisioning completed in approximately 6 minutes.

Step 2: Get Your Credentials

# List database users
curl -u admin:YOUR_PASSWORD \
https://api.foundrydb.com/managed-services/SERVICE_ID/database-users \
| jq '.users[].username'

# Reveal the password
curl -u admin:YOUR_PASSWORD -X POST \
https://api.foundrydb.com/managed-services/SERVICE_ID/database-users/app_user/reveal-password \
| jq .

Store the password securely. You will use it in every request to the cluster.

Step 3: Verify the TLS Certificate

Before connecting your application, confirm that the certificate is valid and issued correctly:

echo | openssl s_client -connect YOUR_HOST:9200 2>/dev/null \
| openssl x509 -noout -subject -issuer -dates

On staging, the output confirmed a valid Let's Encrypt certificate:

subject=CN = *.foundrydb.com
issuer=C = US, O = Let's Encrypt, CN = R11
notBefore=Mar 21 12:16:16 2026 GMT
notAfter=Jun 19 12:16:15 2026 GMT

Step 4: Check Cluster Health

curl -u app_user:YOUR_DB_PASSWORD \
-k https://YOUR_HOST:9200/_cluster/health \
| jq .

The -k flag skips certificate verification for quick local testing. In production, use your system CA bundle or pass --cacert /etc/ssl/cert.pem instead.

Response from the staging cluster:

{
"cluster_name": "managed-opensearch_tutorial_test",
"status": "yellow",
"number_of_nodes": 1,
"number_of_data_nodes": 1,
"active_primary_shards": 5,
"active_shards": 5,
"unassigned_shards": 1,
"active_shards_percent_as_number": 83.33
}

Why "yellow"?

Yellow status on a single-node cluster is expected behavior, not a problem. OpenSearch defaults to one replica per index. On a single node, there is nowhere to place that replica, so it stays unassigned. The primary shards are all active and the cluster accepts reads and writes normally. To eliminate the yellow status without adding nodes, set number_of_replicas to 0 when creating your indexes.

Step 5: Inspect the Node

curl -u app_user:YOUR_DB_PASSWORD \
-k https://YOUR_HOST:9200/_cat/nodes?v

On staging, the node reported these roles: cluster_manager, data, ingest, remote_cluster_client. A single-node cluster is fully functional for development and moderate production workloads. For high availability, provision a multi-node cluster via the nodes field in the API request.

Connection String Reference

For application code, use the standard OpenSearch client libraries and point them at https://YOUR_HOST:9200. Here is a quick example using the OpenSearch Python client:

from opensearchpy import OpenSearch

client = OpenSearch(
hosts=[{"host": "YOUR_HOST", "port": 9200}],
http_auth=("app_user", "YOUR_DB_PASSWORD"),
use_ssl=True,
verify_certs=True,
ssl_show_warn=False,
)

info = client.info()
print(info["version"]["number"]) # 2.19.1

What's Next

Now that the cluster is running and reachable over TLS, the next posts cover creating indexes with explicit mappings, ingesting data in bulk, and running full-text and fuzzy queries:


Ready to try it? Sign up for FoundryDB or provision an OpenSearch cluster from your existing dashboard.