# OpenSearch Configuration

Starting with HPE Morpheus Enterprise Software 8.1.0, the embedded search service changes from Elasticsearch to OpenSearch. All HPE Morpheus VM Essentials Software versions already use OpenSearch — this change only affects HPE Morpheus Enterprise appliance upgrades. Hewlett Packard Enterprise continues to support both Elasticsearch and OpenSearch for external clusters.

During upgrade, the reconfigure process will:

- Automatically disable the old Elasticsearch service
- Start OpenSearch in its place
- Migrate the Elasticsearch PKCS12 CA to PEM format if `secure_mode` is enabled

No changes to /etc/morpheus/morpheus.rb are required. Existing `elasticsearch[...]` settings are bridged to the `opensearch` namespace automatically (see Notes for details on key precedence).

Data (indices) must be migrated separately using `morpheus-ctl migrate-elasticsearch` (see upgrade sections below, or run `morpheus-ctl migrate-elasticsearch help` on an appliance after upgrade for more info).

## What the settings control

| Setting | opensearch.yml | Purpose |
| --- | --- | --- |
| `enable` | — | Enable/disable the embedded OpenSearch service. Set to `false` when using an external cluster. Default `true`. |
| `es_hosts` | `cluster.initial_master_nodes`, `discovery.seed_hosts` | Cluster membership and discovery. For external clusters, lists the external hosts. |
| `node_name` | `node.name` | Unique name for this node within the cluster. |
| `host` | `network.host` or `network.bind_host` | Interface to bind to. Default `127.0.0.1`. Set to `0.0.0.0` for cluster use. |
| `publish_ip` | `network.publish_host` | The IP other nodes use to reach this node. Falls back to Ohai's `node['ipaddress']` if not set. |
| `secure_mode` | `plugins.security.disabled: false`, TLS config | Enables TLS on HTTP and transport layers, generates certs, runs securityadmin.sh. |
| `cluster` | `cluster.name` | Cluster name. Defaults to `morpheus`. Must be the same on all nodes. |
| `use_tls` | — | Connect to OpenSearch over HTTPS. Automatically set to `true` when `secure_mode` is enabled on the embedded service. Set manually for external TLS clusters. |
| `auth_user` | — | Username for Morpheus to authenticate with OpenSearch. Used for external clusters. When nil and `secure_mode` is enabled, the auto-created `morpheus` internal user is used. |
| `auth_password` | — | Password for `auth_user`. Used for external clusters. |
| `replica_count` | `numberOfReplicas` | Number of index replicas. Default `1`. Set to `0` for single-node deployments. |
| `admin_dn` | `plugins.security.authcz.admin_dn` | Distinguished name for the admin certificate. Defaults to `O=Morpheus,OU=Ops,CN=<node_name>`. |
| `nodes_dn` | `plugins.security.nodes_dn` | Distinguished name for trusted node certificates. Defaults to `O=Morpheus,OU=Ops,CN=<node_name>`. |

## Ports

For embedded clusters, ensure the following ports are open between all cluster nodes:

- **9200** — HTTP (client queries)
- **9300** — Transport (inter-node communication and cluster formation)

## Notes

- You can use either `elasticsearch[...]` or `opensearch[...]` keys in morpheus.rb. The `elasticsearch` keys are bridged to `opensearch` automatically. If the same key is set under both namespaces, the `opensearch[...]` value takes precedence.
- The reconfigure strips `127.0.0.1` from `es_hosts` when more than one host is present, so you don't need to exclude it.
- In secure mode, `admin_dn` and `nodes_dn` default to `O=Morpheus,OU=Ops,CN=<node_name>` and are set automatically per node. These only need to be overridden when using custom certificates (see below).

## Custom certificates (admin\_dn and nodes\_dn)

When using your own certificates instead of the auto-generated ones, set `admin_dn` and `nodes_dn` to match the subject DN of your certificates. These values map to `plugins.security.authcz.admin_dn` and `plugins.security.nodes_dn` in opensearch.yml.

- `admin_dn` — Identifies the certificate authorized to run administrative operations (e.g., `securityadmin.sh`). Only requests signed by a certificate matching this DN can modify the security index.
- `nodes_dn` — Identifies certificates trusted for inter-node transport communication. Nodes will reject transport connections from certificates that don't match.

To extract the subject DN from an existing certificate:

```
```
openssl x509 -in /path/to/cert.pem -noout -subject -nameopt RFC2253
```
```

Set the values in /etc/morpheus/morpheus.rb on each node:

```
```
opensearch['admin_dn'] = 'CN=admin,OU=MyTeam,O=MyOrg'  
opensearch['nodes_dn'] = 'CN=node,OU=MyTeam,O=MyOrg'
```
```

If the admin and node certificates share the same DN (common when a single wildcard or shared cert is used), both values can be set to the same string. With the default auto-generated certificates, these are set to `O=Morpheus,OU=Ops,CN=<node_name>` per node and do not need to be configured manually.

## Setting the HPE Morpheus Enterprise user password

When `secure_mode` is enabled, reconfigure creates an internal OpenSearch user named `morpheus` that HPE Morpheus Enterprise uses to authenticate with OpenSearch. The password for this user is auto-generated and stored in /etc/morpheus/morpheus-secrets.json under the `elasticsearch.morpheus_password` key. No manual configuration is needed in the default case.

To set a custom password, add it to /etc/morpheus/morpheus.rb on each node:

```
```
opensearch['morpheus_password'] = 'my-custom-password'
```
```

## Encrypting the password

Passwords in morpheus.rb can be stored in encrypted form using the `ENC{...}` wrapper. During reconfigure, the recipe detects the `ENC` prefix and decrypts the value automatically. Plaintext values are used as-is.

To generate an encrypted string:

```
```
morpheus-ctl get-crypto-string string 'my-custom-password'
```
```

This outputs an encrypted value that can be used in morpheus.rb:

```
```
opensearch['morpheus_password'] = 'ENC{aBcDeFgHiJkLmNoPqRsTuVwXyZ...}'
```
```

The encryption uses the appliance's `encryption_key_suffix` (from /etc/morpheus/morpheus-secrets.json), so the encrypted value is specific to that appliance. All nodes in the cluster share the same secrets file contents, so the same encrypted string works on all nodes.

Any password setting in morpheus.rb supports this format (under either the `opensearch[...]` or `elasticsearch[...]` namespace), including `morpheus_password` and `auth_password`. As with other settings, `opensearch[...]` takes precedence over `elasticsearch[...]` if both are set.

## Single Node

A single-node setup uses the embedded OpenSearch service with default settings. No morpheus.rb changes are required unless enabling secure mode.

## Single Node — Fresh Install

The embedded OpenSearch service starts automatically after the initial reconfigure. No configuration is needed:

```
```
morpheus-ctl reconfigure
```
```

To enable secure mode, add to /etc/morpheus/morpheus.rb:

```
```
opensearch['secure_mode'] = true
```
```

## Single Node — Upgrading from Elasticsearch

**Step 1 — Upgrade the Morpheus package**

Install the new HPE Morpheus Enterprise package. Do **NOT** run reconfigure yet.

**Step 2 — Export data**

After upgrading the package (but before reconfigure), export Elasticsearch data. The old Elasticsearch binary is preserved in the new package to allow this:

```
```
morpheus-ctl migrate-elasticsearch export --dir /var/opt/morpheus/es-migration
```
```

**Step 3 — Reconfigure**

```
```
morpheus-ctl reconfigure
```
```

The old Elasticsearch service is disabled automatically and OpenSearch starts in its place. If `secure_mode` was enabled, the Elasticsearch PKCS12 CA is automatically migrated to PEM format.

**Step 4 — Import data**

```
```
morpheus-ctl migrate-elasticsearch import --dir /var/opt/morpheus/es-migration
```
```

This strips Elasticsearch-specific `_type` metadata from the exported data and bulk-imports it into OpenSearch.

**Step 5 — Cleanup (optional)**

After verifying the data is intact, migrate-elasticsearch will present the option to remove the old Elasticsearch files. This can also be done manually:

```
```
rm -rf /opt/morpheus/embedded/elasticsearch-*  
rm -rf /var/opt/morpheus/elasticsearch-*  
rm -rf /var/opt/morpheus/es-migration
```
```

## 3-Node Embedded Cluster

## 3-Node Embedded Cluster — Prerequisites

**Networking**

- All 3 nodes must be able to reach each other on:

  - **Port 9200 (TCP)** — HTTP API (client queries, health checks)
  - **Port 9300 (TCP)** — Transport (inter-node communication, cluster formation, shard replication)
- Each node needs a stable, routable IP address or resolvable hostname that the other nodes can reach (no NAT between nodes)
- Both IP addresses and hostnames are supported in `es_hosts` and `publish_ip`

**Configuration**

- Each node must have:

  - The same `es_hosts` hash listing all 3 nodes
  - A unique `node_name`
  - A unique `publish_ip` matching that node's routable IP
  - `host` set to `0.0.0.0` (default `127.0.0.1` only listens locally and will not allow cluster formation)
- All nodes must share the same `cluster` name (defaults to `morpheus` — only set this if you need to change it)

**Secure Mode**

- When `secure_mode` is enabled, TLS is used on both HTTP and transport layers
- All nodes must share the **same root CA** — Node 1 must be reconfigured first to generate the CA, then the CA files are copied to the remaining nodes before their first reconfigure
- Each node auto-generates its own node certificate signed by the shared CA

**Example nodes:**

- Node 1: `10.0.0.1` (morpheus-1)
- Node 2: `10.0.0.2` (morpheus-2)
- Node 3: `10.0.0.3` (morpheus-3)

## Fresh Install — Without Secure Mode

NOTE

`elasticsearch[...]` keys can also be used in place of `opensearch[...]` on fresh installs. They are bridged automatically.

**Node 1** — /etc/morpheus/morpheus.rb:

```
```
opensearch['es_hosts'] = {'10.0.0.1' => 9200, '10.0.0.2' => 9200, '10.0.0.3' => 9200}  
opensearch['node_name'] = 'morpheus-1'  
opensearch['host'] = '0.0.0.0'  
opensearch['publish_ip'] = '10.0.0.1'
```
```

**Node 2** — /etc/morpheus/morpheus.rb:

```
```
opensearch['es_hosts'] = {'10.0.0.1' => 9200, '10.0.0.2' => 9200, '10.0.0.3' => 9200}  
opensearch['node_name'] = 'morpheus-2'  
opensearch['host'] = '0.0.0.0'  
opensearch['publish_ip'] = '10.0.0.2'
```
```

**Node 3** — /etc/morpheus/morpheus.rb:

```
```
opensearch['es_hosts'] = {'10.0.0.1' => 9200, '10.0.0.2' => 9200, '10.0.0.3' => 9200}  
opensearch['node_name'] = 'morpheus-3'  
opensearch['host'] = '0.0.0.0'  
opensearch['publish_ip'] = '10.0.0.3'
```
```

**Apply**

Run on all three nodes:

```
```
morpheus-ctl reconfigure
```
```

Nodes can be reconfigured in any order. The cluster will form once all nodes are up and can reach each other on ports 9200 and 9300.

## Fresh Install — With Secure Mode

NOTE

`elasticsearch[...]` keys can also be used in place of `opensearch[...]` on fresh installs. They are bridged automatically.

Secure mode enables TLS on both the HTTP and transport layers. Each node generates its own node certificate, but all nodes must share the **same root CA** so they trust each other.

**Step 1 — Configure and reconfigure Node 1 first**

Node 1 — /etc/morpheus/morpheus.rb:

```
```
opensearch['es_hosts'] = {'10.0.0.1' => 9200, '10.0.0.2' => 9200, '10.0.0.3' => 9200}  
opensearch['node_name'] = 'morpheus-1'  
opensearch['host'] = '0.0.0.0'  
opensearch['publish_ip'] = '10.0.0.1'  
opensearch['secure_mode'] = true
```
```

Run reconfigure on Node 1:

```
```
morpheus-ctl reconfigure
```
```

This generates the root CA and node certificate at:

- /opt/morpheus/embedded/opensearch-2.18.0/config/root-ca.pem
- /opt/morpheus/embedded/opensearch-2.18.0/config/root-ca-key.pem

**Step 2 — Copy the root CA to Nodes 2 and 3**

Copy both CA files from Node 1 to the same path on Nodes 2 and 3 **before** running reconfigure on them:

```
```
# From Node 1:  
scp /opt/morpheus/embedded/opensearch-2.18.0/config/root-ca.pem     node2:/opt/morpheus/embedded/opensearch-2.18.0/config/  
scp /opt/morpheus/embedded/opensearch-2.18.0/config/root-ca-key.pem  node2:/opt/morpheus/embedded/opensearch-2.18.0/config/  
  
scp /opt/morpheus/embedded/opensearch-2.18.0/config/root-ca.pem     node3:/opt/morpheus/embedded/opensearch-2.18.0/config/  
scp /opt/morpheus/embedded/opensearch-2.18.0/config/root-ca-key.pem  node3:/opt/morpheus/embedded/opensearch-2.18.0/config/
```
```

Set ownership on Nodes 2 and 3:

```
```
chown morpheus-es:morpheus-es /opt/morpheus/embedded/opensearch-2.18.0/config/root-ca*.pem
```
```

**Step 3 — Configure and reconfigure Nodes 2 and 3**

Node 2 — /etc/morpheus/morpheus.rb:

```
```
opensearch['es_hosts'] = {'10.0.0.1' => 9200, '10.0.0.2' => 9200, '10.0.0.3' => 9200}  
opensearch['node_name'] = 'morpheus-2'  
opensearch['host'] = '0.0.0.0'  
opensearch['publish_ip'] = '10.0.0.2'  
opensearch['secure_mode'] = true
```
```

Node 3 — /etc/morpheus/morpheus.rb:

```
```
opensearch['es_hosts'] = {'10.0.0.1' => 9200, '10.0.0.2' => 9200, '10.0.0.3' => 9200}  
opensearch['node_name'] = 'morpheus-3'  
opensearch['host'] = '0.0.0.0'  
opensearch['publish_ip'] = '10.0.0.3'  
opensearch['secure_mode'] = true
```
```

Run reconfigure on Nodes 2 and 3:

```
```
morpheus-ctl reconfigure
```
```

Each node will skip CA generation (the files already exist) and generate its own node certificate signed by the shared CA.

## Upgrading from a 3-Node Elasticsearch Cluster

**Step 1 — Upgrade the Morpheus package**

Install the new Morpheus package on all 3 nodes. Do **not** run reconfigure yet.

**Step 2 — Export data**

After upgrading the package (but before reconfigure), export Elasticsearch data on **one node** (the data is cluster-wide). The old Elasticsearch binary is preserved in the new package to allow this:

```
```
morpheus-ctl migrate-elasticsearch export --dir /var/opt/morpheus/es-migration
```
```

This will:

- Query all available indices and their sizes
- Prompt you to select which indices to export (or export all)
- Verify sufficient disk space (requires ~2x index size for JSON format)
- Write each index as a JSON file to the export directory

**Step 3 — Reconfigure**

**Without secure mode** — No special ordering is required. Run on all 3 nodes:

```
```
morpheus-ctl reconfigure
```
```

The old Elasticsearch service is disabled automatically and OpenSearch starts in its place. The existing morpheus.rb cluster settings (`es_hosts`, `node_name`, `host`, `publish_ip`) carry over unchanged.

**With secure mode** — No special ordering is required. The existing Elasticsearch cluster already shares a single CA via the PKCS12 truststore on each node. During reconfigure, each node independently extracts the same CA from its local truststore and uses it to generate its OpenSearch node certificate.

Run on all 3 nodes:

```
```
morpheus-ctl reconfigure
```
```

On each node, the recipe will:

- Detect the old PKCS12 truststore at /var/opt/morpheus/elasticsearch\*/local/elastic-stack-ca.p12
- Extract the shared CA certificate and key to PEM format (root-ca.pem and root-ca-key.pem)
- Generate a new OpenSearch node certificate signed by the migrated CA
- Disable the old Elasticsearch service

It is assumed existing Elasticsearch clusters use the same CA. When all nodes extract the same CA, they will trust each other's certificates and form a cluster without any manual certificate copying.

**Step 4 — Import data**

Once all 3 nodes are reconfigured and the OpenSearch cluster is formed, import the data on **one node**:

```
```
morpheus-ctl migrate-elasticsearch import --dir /var/opt/morpheus/es-migration
```
```

This strips Elasticsearch-specific `_type` metadata from the exported data and bulk-imports it into OpenSearch.

**Step 5 — Cleanup (optional)**

After verifying the data is intact in OpenSearch, migrate-elasticsearch will present the option to remove the old Elasticsearch files. This can also manually be done on the other nodes with:

```
```
rm -rf /opt/morpheus/embedded/elasticsearch-*  
rm -rf /var/opt/morpheus/elasticsearch-*  
rm -rf /var/opt/morpheus/es-migration
```
```

## External Cluster

When using an externally managed OpenSearch (or Elasticsearch) cluster, disable the embedded service and point Morpheus at the external hosts.

## External Cluster — Fresh Install

NOTE

`elasticsearch[...]` keys can also be used in place of `opensearch[...]` on fresh installs. They are bridged automatically.

Add the following to /etc/morpheus/morpheus.rb on each Morpheus appliance node:

```
```
opensearch['enable'] = false  
opensearch['es_hosts'] = {'os-node1.example.com' => 9200, 'os-node2.example.com' => 9200, 'os-node3.example.com' => 9200}  
opensearch['auth_user'] = 'morpheus'  
opensearch['auth_password'] = 'the-external-cluster-password'
```
```

If the external cluster uses TLS:

```
```
opensearch['use_tls'] = true
```
```

Then reconfigure:

```
```
morpheus-ctl reconfigure
```
```

The embedded OpenSearch service will not be started. Morpheus will connect directly to the external cluster using the provided hosts and credentials.

- `auth_user` and `auth_password` are sent to the external cluster for authentication. These must match a user configured on the external cluster.
- `auth_password` supports the `ENC{...}` encrypted format (see Encrypting the password).
- Do not set `secure_mode` — that setting controls the embedded service's certificate generation and security plugin. For external TLS clusters, use `use_tls` instead.
- `replica_count` can be adjusted to match the external cluster's topology (default `1`).

## Upgrading with an External Cluster

If the existing Morpheus installation was already configured to use an external Elasticsearch or OpenSearch cluster, the upgrade is straightforward — no data migration is needed on the appliance side since the data lives on the external cluster. The external cluster does not need to be migrated to OpenSearch; Morpheus supports both.

**Step 1 — Upgrade the Morpheus package**

Install the new Morpheus package on each appliance node.

**Step 2 — Reconfigure**

No morpheus.rb changes are needed. The existing `elasticsearch[...]` settings are bridged automatically.

```
```
morpheus-ctl reconfigure
```
```
