Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/wikioasis/salt/llms.txt

Use this file to discover all available pages before exploring further.

The opensearch Salt state provisions and manages OpenSearch 1.3.x on every opensearch* server in the WikiOasis fleet. It configures an apt repository, installs the package with the demo security config disabled, renders opensearch.yml from pillar data, tunes the JVM heap via jvm.options.d/heap.options, and keeps the service running. OpenSearch serves as the backend for the MediaWiki CirrusSearch extension.

State overview

1

APT repository

Creates /etc/apt/sources.list.d/opensearch.list pointing to the OpenSearch 1.x apt repository with trusted=yes to bypass SHA1 key validation (see note below).
2

Package installation

Runs apt-get install -y --allow-downgrades opensearch=1.3.* with DISABLE_INSTALL_DEMO_CONFIG=true and DISABLE_PERFORMANCE_ANALYZER_AGENT_CLI=true to skip the interactive post-install scripts. The unless guard prevents re-running if a 1.3.x version is already installed.
3

Main configuration

Renders /etc/opensearch/opensearch.yml from the Jinja template, owned by root:opensearch, mode 0660.
4

JVM heap options

Renders /etc/opensearch/jvm.options.d/heap.options to set -Xms and -Xmx from the opensearch:heap_size pillar key.
5

Service management

Ensures opensearch is running and enabled, restarting on changes to either config file.
SHA1 key workaround — trusted=yesThe OpenSearch apt repository signing key uses SHA1 binding signatures, which sqv (the sequoia-based OpenPGP verifier used by apt on Debian 13 / Ubuntu 24.04+) hard-rejects from 2026-02-01 onwards. To work around this without pinning an older apt version, the state sets trusted=yes on the repository line, which bypasses signature verification entirely. This is acceptable for an internal cluster where network access is restricted, but should be revisited if the upstream repository migrates to a SHA2-signed key.
# salt/opensearch/init.sls
opensearch_apt_repo:
  file.managed:
    - name: /etc/apt/sources.list.d/opensearch.list
    - contents: |
        deb [trusted=yes arch=amd64] https://artifacts.opensearch.org/releases/bundle/opensearch/1.x/apt stable main
    - user: root
    - group: root
    - mode: '0644'

opensearch_pkg:
  cmd.run:
    - name: apt-get update && apt-get install -y --allow-downgrades opensearch=1.3.*
    - env:
      - DEBIAN_FRONTEND: noninteractive
      - DISABLE_INSTALL_DEMO_CONFIG: "true"
      - DISABLE_PERFORMANCE_ANALYZER_AGENT_CLI: "true"
    - unless: "dpkg-query -W -f='${Version}' opensearch 2>/dev/null | grep -q '^1\\.3\\.'"
    - require:
      - file: opensearch_apt_repo

/etc/opensearch/opensearch.yml:
  file.managed:
    - source: salt://opensearch/files/opensearch.yml.jinja
    - template: jinja
    - user: root
    - group: opensearch
    - mode: '0660'
    - require:
      - cmd: opensearch_pkg

/etc/opensearch/jvm.options.d/heap.options:
  file.managed:
    - source: salt://opensearch/files/heap.options.jinja
    - template: jinja
    - user: root
    - group: opensearch
    - mode: '0660'
    - require:
      - cmd: opensearch_pkg

opensearch:
  service.running:
    - enable: True
    - watch:
      - file: /etc/opensearch/opensearch.yml
      - file: /etc/opensearch/jvm.options.d/heap.options
    - require:
      - cmd: opensearch_pkg

Configuration template (opensearch.yml)

The template derives the node name from the Salt minion ID (the hostname prefix before the first .), and builds the discovery seed host and initial master node lists from the opensearch:nodes pillar key. The OpenSearch security plugin is disabled (plugins.security.disabled: true) since the cluster operates on a private VLAN.
{%- set cfg = salt['pillar.get']('opensearch', {}) %}
{%- set node_name = grains['id'].split('.')[0] %}

cluster.name: {{ cfg.get('cluster_name', 'wikioasis-search') }}
node.name: {{ node_name }}

network.host:
  - _site_
  - _local_

http.port: {{ cfg.get('http_port', 9200) }}
transport.port: {{ cfg.get('transport_port', 9300) }}

node.roles:
  - master
  - data
  - ingest

discovery.seed_hosts:
{%- for node in cfg.get('nodes', []) %}
  - {{ node.host }}
{%- endfor %}

cluster.initial_master_nodes:
{%- for node in cfg.get('nodes', []) %}
  - {{ node.name }}
{%- endfor %}

plugins.security.disabled: true

JVM heap configuration

The heap options template produces a minimal options file that sets both the initial (-Xms) and maximum (-Xmx) heap to the same value, which is the recommended configuration for OpenSearch to avoid heap resizing pauses.
{%- set cfg = salt['pillar.get']('opensearch', {}) %}
{%- set heap = cfg.get('heap_size', '1g') %}
-Xms{{ heap }}
-Xmx{{ heap }}
Always set -Xms equal to -Xmx to prevent the JVM from resizing the heap at runtime. As a rule of thumb, set the heap to 50% of available RAM and no more than 31 GB (to stay within the JVM’s compressed oops threshold).

Pillar reference

KeyDefaultDescription
cluster_namewikioasis-searchOpenSearch cluster name — must be identical across all nodes
heap_size1gJVM heap size, written as both -Xms and -Xmx
http_port9200REST API port
transport_port9300Inter-node transport port
nodes[]List of cluster nodes for discovery and master election
nodes[].nameNode name (matches minion ID prefix)
nodes[].hostFully-qualified hostname used for seed discovery

Pillar example

# pillar/opensearch/init.sls
opensearch:
  cluster_name: wikioasis-search
  heap_size: 3g
  http_port: 9200
  transport_port: 9300
  nodes:
    - name: opensearch-us-east-011
      host: opensearch-us-east-011.ovvin.wonet
    - name: opensearch-us-east-012
      host: opensearch-us-east-012.ovvin.wonet

Fleet topology

opensearch-us-east-011

First cluster node. VM ID 150 on metal-us-east-01 at 10.0.1.50. Runs master, data, and ingest roles.

opensearch-us-east-012

Second cluster node. VM ID 151 on metal-us-east-01 at 10.0.1.51. Runs master, data, and ingest roles.

Applying the state

# Apply to all opensearch* minions
salt 'opensearch*' state.apply opensearch

# Apply to a single node
salt 'opensearch-us-east-011*' state.apply opensearch

# Preview what would change without applying
salt 'opensearch*' state.apply opensearch test=True

# Verify cluster health after applying
salt 'opensearch-us-east-011*' cmd.run \
  'curl -s http://localhost:9200/_cluster/health?pretty'
When bootstrapping a brand-new cluster, apply the state to all nodes simultaneously so they can discover each other and elect a master. Applying to one node at a time risks the cluster failing to form quorum during bootstrap.

Build docs developers (and LLMs) love