trombik.opensearch
trombik.opensearch
An ansible
role for managing opensearch
.
The role is currently in beta.
For FreeBSD Users
The example requires a custom version of opensearch-dashboards
for FreeBSD, available at trombik/freebsd-ports-opensearch. It also uses trombik.opensearch_dashboards
. However, it relies on www/node10
, which is now end-of-life and not recommended.
For an upgrade plan, see Issue 835.
For Debian and CentOS Users
This role installs opensearch
using the official tar file. This is a temporary solution until Amazon or the relevant distributions provide proper packages.
Variables related to source installation, opensearch_src_*
, are intentionally not documented.
The role does not install the JDK package; it uses the bundled JDK instead.
The role imports a PGP key into the root
keyring from the upstream project to verify the tar file. If you know how to verify a signed file without importing a PGP key, please share.
Some plugins may not work yet.
Modifications from the default setup include:
- Log files are saved in
/var/log/opensearch
- The application is installed under
opensearch_root_dir
, defaulting to/usr/local/opensearch-dashboards
- The application runs under the user
opensearch
These modifications will be revised once an official package is available.
The role downloads the official tar archive to opensearch_src_dir
, which defaults to /var/dist
. This directory also holds the PGP key, signature file, and task control files for ansible
.
A systemd
unit file for opensearch
will be installed, but the author does not claim expertise in systemd
.
Requirements
By default, the role uses trombik.x509_certificate
to manage X509 certificates. It is not listed as a dependency since TLS is optional.
Role Variables
Variable | Description | Default |
---|---|---|
opensearch_user |
Username for opensearch |
{{ __opensearch_user }} |
opensearch_group |
Group name for opensearch |
{{ __opensearch_group }} |
opensearch_log_dir |
Path to log directory | {{ __opensearch_log_dir }} |
opensearch_db_dir |
Path to data directory | {{ __opensearch_db_dir }} |
opensearch_scripts_dir |
Path to script directory | {{ __opensearch_scripts_dir }} |
opensearch_plugins_dir |
Path to plugin directory | {{ __opensearch_plugins_dir }} |
opensearch_plugin_command |
Path to opensearch-plugin command |
{{ __opensearch_plugin_command }} |
opensearch_plugins |
List of plugins (see below) | [] |
opensearch_service |
Service name for opensearch |
{{ __opensearch_service }} |
opensearch_package |
Package name for opensearch |
{{ __opensearch_package }} |
opensearch_conf_dir |
Path to the configuration directory | {{ __opensearch_conf_dir }} |
opensearch_jvm_options |
JVM options (see example playbook) | "" |
opensearch_conf_file |
Path to opensearch.yml |
{{ opensearch_conf_dir }}/opensearch.yml |
opensearch_flags |
Extra flags for startup scripts | "" |
opensearch_config |
Content of opensearch.yml |
"" |
opensearch_config_log4j2_properties |
Content for log4j2.properties |
"" |
opensearch_http_host |
Address or hostname for opensearch ; must be accessible from ansible controller |
localhost |
opensearch_http_port |
Listening port for opensearch ; must be accessible from ansible controller |
9200 |
opensearch_http_url |
URL of HTTP interface; must be accessible from ansible controller |
https://{{ opensearch_http_host }}:{{ opensearch_http_port }} |
opensearch_http_auth |
Authentication details for API access | {} |
opensearch_java_home |
JAVA_HOME environment variable |
{{ __opensearch_java_home }} |
opensearch_extra_plugin_files |
List of extra files for plugins (see below) | [] |
opensearch_include_role_x509_certificate |
Include trombik.x509_certificate during play |
yes |
opensearch_x509_certificate_vars |
Variables for trombik.x509_certificate |
{} |
opensearch_wait_for_cluster_status |
Wait for cluster status after starting service; valid values include red , yellow , green , false |
no |
opensearch_wait_for_cluster_status_timeout |
Timeout when waiting for cluster status | 10s |
opensearch_wait_for_cluster_status_retry |
Number of retries while waiting for cluster status | 3 |
opensearch_plugins
This is a list of plugins. Each element in the list is a dictionary.
Key | Description | Mandatory? |
---|---|---|
name |
Name of the plugin | Yes |
src |
Source URL of the plugin | No |
opensearch_extra_plugin_files
This variable is a list of files for plugins. Each element in the list is a dictionary.
Key | Description | Mandatory? |
---|---|---|
path |
Relative path to file from opensearch_plugins_dir |
Yes |
type |
Either yaml or raw . If yaml , content rendered as YAML; if raw , content is rendered as-is. |
No |
mode |
File permissions | No |
owner |
Owner of the file | No |
group |
Group of the file | No |
state |
Either present (create file) or absent (delete file), default is present |
No |
content |
Content of the file (see type ) |
No |
post_command |
A dictionary for ansible.builtin.command |
No |
post_command
runs a command after the item status changes. It accepts the following keys:
Key | Description | Mandatory? |
---|---|---|
cmd |
Command to run | Yes |
args |
Args dictionary (supports chdir , creates , and removes ) |
No |
enabled |
Either yes or no ; if yes , the command will run |
Yes |
Primarily designed for securityadmin.sh
. See Apply changes using securityadmin.sh for more details.
opensearch_http_auth
This variable is a dictionary used for user credentials when accessing API endpoints at opensearch_http_url
.
Key | Description | Mandatory? |
---|---|---|
client_cert |
Path to client public key in PEM format |
No |
client_key |
Path to client secret key in PEM format |
No |
ca_path |
Path to CA's public key in PEM format |
No |
url_username |
Username for basic authentication | No |
url_password |
Password for basic authentication | No |
validate_certs |
Verify remote certificate | No |
Known Issues with opensearch_http_auth
and TLS
opensearch
supports basic authentication and TLS client certificate authentication over TLS. However, some configurations may lead to failed API calls.
It's recommended to use basic authentication over TLS with ca_path
. Avoid using TLS client authentication without username and password as it requires validate_certs
to be set to no
.
Platform-Specific Variable Defaults
Debian
Variable | Default |
---|---|
__opensearch_user |
opensearch |
__opensearch_group |
opensearch |
__opensearch_log_dir |
/var/log/opensearch |
__opensearch_db_dir |
/var/lib/opensearch |
__opensearch_package |
opensearch |
__opensearch_conf_dir |
/usr/local/opensearch/config |
__opensearch_root_dir |
/usr/local/opensearch |
__opensearch_plugins_dir |
/usr/local/opensearch/plugins |
__opensearch_plugin_command |
/usr/local/opensearch/bin/opensearch-plugin |
__opensearch_service |
opensearch |
__opensearch_java_home |
/usr/local/opensearch/jdk |
FreeBSD
Variable | Default |
---|---|
__opensearch_user |
opensearch |
__opensearch_group |
opensearch |
__opensearch_log_dir |
/var/log/opensearch |
__opensearch_db_dir |
/var/db/opensearch |
__opensearch_package |
textproc/opensearch |
__opensearch_conf_dir |
/usr/local/etc/opensearch |
__opensearch_plugins_dir |
/usr/local/lib/opensearch/plugins |
__opensearch_plugin_command |
/usr/local/lib/opensearch/bin/opensearch-plugin |
__opensearch_service |
opensearch |
__opensearch_java_home |
/usr/local |
RedHat
Variable | Default |
---|---|
__opensearch_user |
opensearch |
__opensearch_group |
opensearch |
__opensearch_log_dir |
/var/log/opensearch |
__opensearch_db_dir |
/var/lib/opensearch |
__opensearch_package |
opensearch |
__opensearch_conf_dir |
/usr/local/opensearch/config |
__opensearch_root_dir |
/usr/local/opensearch |
__opensearch_plugins_dir |
/usr/local/opensearch/plugins |
__opensearch_plugin_command |
/usr/local/opensearch/bin/opensearch-plugin |
__opensearch_service |
opensearch |
__opensearch_java_home |
/usr/local/opensearch/jdk |
Dependencies
trombik.x509_certificate
ifopensearch_include_role_x509_certificate
is set to true.
Example Playbook
This example shows how to install:
opensearch
opensearch-dashboards
haproxy
fluentd
haproxy
acts as a reverse proxy for opensearch-dashboards
. Logs from haproxy
and syslog
are sent to a local fluentd
listener, which processes and forwards them to opensearch
. The index pattern used is logstash-*
.
Note that the fluentd
elasticsearch
output plugin does not support opensearch
. This is worked around by:
- Installing specific versions of
fluentd-elasticsearch-plugin
and related gems. - Setting
verify_es_version_at_startup
anddefault_elasticsearch_version
influentd.conf
.
Use the user admin
with password admin
to log in to the dashboards.
For a clustered example, see tests/serverspec/cluster.yml.
---
- hosts: localhost
pre_tasks:
- name: Allow HTTP port
ansible.builtin.iptables:
chain: INPUT
destination_port: 80
protocol: tcp
jump: ACCEPT
when: ansible_os_family == 'RedHat'
- name: Enable syslog forwarding from rsyslog
ansible.builtin.copy:
dest: /etc/rsyslog.d/fluentd.conf
content: |
*.*;syslog;auth,authpriv.none action(
Target="127.0.0.1"
type="omfwd"
Port="1514"
Protocol="udp"
template="RSYSLOG_SyslogProtocol23Format"
)
mode: "0644"
when:
- ansible_os_family == 'Debian' or ansible_os_family == 'RedHat'
register: __register_project_rsyslog_config
- name: Restart rsyslog
ansible.builtin.service:
name: rsyslog
state: restarted
when:
- ansible_os_family == 'Debian' or ansible_os_family == 'RedHat'
- __register_project_rsyslog_config['changed']
- name: Enable syslog forwarding from syslogd
ansible.builtin.copy:
dest: /etc/syslog.d/fluentd.conf
content: |
*.* @127.0.0.1:1514
mode: "0644"
when: ansible_os_family == 'FreeBSD'
register: __register_project_syslog_config
- name: Enable syslog rfc5424
ansible.builtin.copy:
dest: /etc/rc.conf.d/syslogd
content: |
syslogd_flags="-s -O rfc5424"
mode: "0644"
when: ansible_os_family == 'FreeBSD'
register: __register_project_syslog_flags
- name: Restart syslogd
ansible.builtin.service:
name: syslogd
state: restarted
when:
- ansible_os_family == 'FreeBSD'
- __register_project_syslog_config['changed'] or __register_project_syslog_flags['changed']
roles:
- role: trombik.freebsd_pkg_repo
when: ansible_os_family == "FreeBSD"
- name: trombik.apt_repo
when: ansible_os_family == 'Debian'
- name: trombik.redhat_repo
when: ansible_os_family == 'RedHat'
- role: trombik.java
when: ansible_os_family == "FreeBSD"
- role: trombik.sysctl
- ansible-role-opensearch
- role: trombik.opensearch_dashboards
- role: trombik.fluentd
- role: trombik.haproxy
vars:
freebsd_pkg_repo:
local:
enabled: "true"
url: "http://pkg.i.trombik.org/{{ ansible_distribution_version | regex_replace('\\.') }}{{ ansible_architecture }}-default-default"
mirror_type: none
priority: 100
state: present
os_opensearch_extra_packages:
FreeBSD: []
Debian:
- unzip
RedHat: []
opensearch_extra_packages: "{{ os_opensearch_extra_packages[ansible_os_family] }}"
os_java_packages:
FreeBSD:
- openjdk11
- jq
- vim
- tmux
- p5-ack
Debian:
- openjdk-11-jdk
RedHat:
- java-11-openjdk-devel
java_packages: "{{ os_java_packages[ansible_os_family] }}"
os_sysctl:
FreeBSD:
kern.maxfilesperproc: 65536
security.bsd.unprivileged_mlock: 1
Debian:
vm.max_map_count: 262144
RedHat:
vm.max_map_count: 262144
sysctl: "{{ os_sysctl[ansible_os_family] }}"
opensearch_wait_for_cluster_status: yellow
os_opensearch_package:
FreeBSD: "{{ __opensearch_package }}"
Debian: "{{ __opensearch_package }}"
RedHat: opensearch-1.13.2
opensearch_package: "{{ os_opensearch_package[ansible_os_family] }}"
os_opensearch_flags:
FreeBSD: ""
Debian: |
ES_PATH_CONF={{ opensearch_conf_dir }}
ES_STARTUP_SLEEP_TIME=5
RedHat: |
ES_PATH_CONF={{ opensearch_conf_dir }}
ES_STARTUP_SLEEP_TIME=5
opensearch_flags: "{{ os_opensearch_flags[ansible_os_family] }}"
os_opensearch_jvm_options:
FreeBSD: ""
Debian: |
-Dclk.tck=100
-Djdk.attach.allowAttachSelf=true
-Djava.security.policy={{ opensearch_root_dir }}/plugins/opensearch-performance-analyzer/pa_config/opensearch_security.policy
RedHat: |
-Dclk.tck=100
-Djdk.attach.allowAttachSelf=true
-Djava.security.policy={{ opensearch_root_dir }}/plugins/opensearch-performance-analyzer/pa_config/opensearch_security.policy
os_opensearch_http_auth:
FreeBSD:
url_username: admin
url_password: admin
ca_path: "{{ role_path }}/files/test/certs/root-ca.pem"
validate_certs: yes
Debian:
client_cert: "{{ role_path }}/files/test/certs/admin.pem"
client_key: "{{ role_path }}/files/test/certs/admin-key.pem"
validate_certs: no
RedHat:
client_cert: "{{ role_path }}/files/test/certs/admin.pem"
client_key: "{{ role_path }}/files/test/certs/admin-key.pem"
validate_certs: no
opensearch_http_auth: "{{ os_opensearch_http_auth[ansible_os_family] }}"
opensearch_jvm_options: "{{ lookup('file', 'test/jvm_options') + os_opensearch_jvm_options[ansible_os_family] }}"
opensearch_config:
discovery.type: single-node
network.publish_host: ["10.0.2.15"]
path.data: "{{ opensearch_db_dir }}"
http.port: "{{ opensearch_http_port }}"
path.logs: "{{ opensearch_log_dir }}"
node.data: "true"
http.compression: "true"
network.host:
- "{{ opensearch_http_host }}"
- _site_
cluster.name: testcluster
node.name: testnode
http.cors.enabled: "true"
http.cors.allow-origin: "*"
http.cors.max-age: 86400
http.cors.allow-methods: "OPTIONS, HEAD, GET, POST, PUT, DELETE"
http.cors.allow-headers: "X-Requested-With, Content-Type, Content-Length"
http.cors.allow-credentials: "true"
plugins.security.ssl.transport.pemcert_filepath: node.pem
plugins.security.ssl.transport.pemkey_filepath: node-key.pem
plugins.security.ssl.transport.pemtrustedcas_filepath: root-ca.pem
plugins.security.ssl.transport.enforce_hostname_verification: false
plugins.security.ssl.http.enabled: true
plugins.security.ssl.http.pemcert_filepath: node.pem
plugins.security.ssl.http.pemkey_filepath: node-key.pem
plugins.security.ssl.http.pemtrustedcas_filepath: root-ca.pem
plugins.security.allow_unsafe_democertificates: true
plugins.security.allow_default_init_securityindex: true
plugins.security.authcz.admin_dn:
- CN=Admin,O=Internet Widgits Pty Ltd,ST=Some-State,C=AU
plugins.security.nodes_dn:
- CN=localhost,O=Internet Widgits Pty Ltd,ST=Some-State,C=AU
plugins.security.advanced_modules_enabled: false
plugins.security.audit.type: internal_opensearch
plugins.security.enable_snapshot_restore_privilege: true
plugins.security.check_snapshot_restore_write_privileges: true
plugins.security.restapi.roles_enabled: ["all_access", "security_rest_api_access"]
plugins.security.system_indices.enabled: true
plugins.security.system_indices.indices: [".opendistro-alerting-config", ".opendistro-alerting-alert*", ".opendistro-anomaly-results*", ".opendistro-anomaly-detector*", ".opendistro-anomaly-checkpoints", ".opendistro-anomaly-detection-state", ".opendistro-reports-*", ".opendistro-notifications-*", ".opendistro-notebooks", ".opendistro-asynchronous-search-response*"]
plugins.security.disabled: false
cluster.routing.allocation.disk.threshold_enabled: false
project_security_plugin_dir: "{{ opensearch_plugins_dir }}/opensearch-security"
project_securityadmin_bin: "{{ project_security_plugin_dir }}/tools/securityadmin.sh"
project_security_plugin_post_command:
cmd: "{{ project_securityadmin_bin }} -icl -nhnv -cacert {{ opensearch_conf_dir }}/root-ca.pem -cert {{ opensearch_conf_dir }}/admin.pem -key {{ opensearch_conf_dir }}/admin-key.pem"
args:
chdir: "{{ project_security_plugin_dir }}/securityconfig"
enabled: "{% if 1 == 1 %}yes{% else %}no{% endif %}"
opensearch_plugins: []
opensearch_extra_plugin_files:
- path: opensearch-security/securityconfig/action_groups.yml
type: yaml
mode: "0640"
group: "{{ opensearch_user }}"
content: "{{ lookup('file', 'test/securityconfig/action_groups.yml') | from_yaml }}"
post_command: "{{ project_security_plugin_post_command }}"
- path: opensearch-security/securityconfig/audit.yml
type: yaml
mode: "0640"
group: "{{ opensearch_user }}"
content: "{{ lookup('file', 'test/securityconfig/audit.yml') | from_yaml }}"
post_command: "{{ project_security_plugin_post_command }}"
- path: opensearch-security/securityconfig/config.yml
type: yaml
mode: "0640"
group: "{{ opensearch_user }}"
content: "{{ lookup('file', 'test/securityconfig/config.yml') | from_yaml }}"
post_command: "{{ project_security_plugin_post_command }}"
- path: opensearch-security/securityconfig/internal_users.yml
type: yaml
mode: "0640"
group: "{{ opensearch_user }}"
content: "{{ lookup('file', 'test/securityconfig/internal_users.yml') | from_yaml }}"
post_command: "{{ project_security_plugin_post_command }}"
- path: opensearch-security/securityconfig/nodes_dn.yml
type: yaml
mode: "0640"
group: "{{ opensearch_user }}"
content: "{{ lookup('file', 'test/securityconfig/nodes_dn.yml') | from_yaml }}"
post_command: "{{ project_security_plugin_post_command }}"
- path: opensearch-security/securityconfig/roles.yml
type: yaml
mode: "0640"
group: "{{ opensearch_user }}"
content: "{{ lookup('file', 'test/securityconfig/roles.yml') | from_yaml }}"
post_command: "{{ project_security_plugin_post_command }}"
- path: opensearch-security/securityconfig/roles_mapping.yml
type: yaml
mode: "0640"
group: "{{ opensearch_user }}"
content: "{{ lookup('file', 'test/securityconfig/roles_mapping.yml') | from_yaml }}"
post_command: "{{ project_security_plugin_post_command }}"
- path: opensearch-security/securityconfig/tenants.yml
type: yaml
mode: "0640"
group: "{{ opensearch_user }}"
content: "{{ lookup('file', 'test/securityconfig/tenants.yml') | from_yaml }}"
post_command: "{{ project_security_plugin_post_command }}"
- path: opensearch-security/securityconfig/whitelist.yml
type: yaml
mode: "0640"
group: "{{ opensearch_user }}"
content: "{{ lookup('file', 'test/securityconfig/whitelist.yml') | from_yaml }}"
post_command: "{{ project_security_plugin_post_command }}"
opensearch_config_log4j2_properties: "{{ lookup('file', 'test/log4j2_properties') }}"
x509_certificate_debug_log: yes
x509_certificate:
- name: node
state: present
public:
path: "{{ opensearch_conf_dir }}/node.pem"
mode: "0444"
key: "{{ lookup('file', 'test/certs/node.pem') }}"
secret:
path: "{{ opensearch_conf_dir }}/node-key.pem"
owner: "{{ opensearch_user }}"
group: "{{ opensearch_group }}"
mode: "0600"
key: "{{ lookup('file', 'test/certs/node-key.pem') }}"
- name: root-ca
state: present
public:
path: "{{ opensearch_conf_dir }}/root-ca.pem"
key: "{{ lookup('file', 'test/certs/root-ca.pem') }}"
secret:
path: "{{ opensearch_conf_dir }}/root-ca-key.pem"
owner: "{{ opensearch_user }}"
group: "{{ opensearch_group }}"
key: "{{ lookup('file', 'test/certs/root-ca-key.pem') }}"
- name: admin
state: present
public:
path: "{{ opensearch_conf_dir }}/admin.pem"
key: "{{ lookup('file', 'test/certs/admin.pem') }}"
secret:
path: "{{ opensearch_conf_dir }}/admin-key.pem"
owner: "{{ opensearch_user }}"
group: "{{ opensearch_group }}"
key: "{{ lookup('file', 'test/certs/admin-key.pem') }}"
opensearch_dashboards_config:
server.host: "{{ opensearch_dashboards_bind_address }}"
server.port: "{{ opensearch_dashboards_bind_port }}"
server.name: "OpenSearch Dashboards"
logging.dest: "{% if ansible_os_family == 'FreeBSD' %}/var/log/opensearch_dashboards.log{% else %}{{ opensearch_dashboards_log_file }}{% endif %}"
logging.verbose: true
opensearch.hosts: ["https://localhost:9200"]
path.data: "{{ opensearch_dashboards_data_dir }}"
opensearch.ssl.verificationMode: none
project_backend_host: 127.0.0.1
project_backend_port: 5601
# Fluentd and HAProxy configuration would go here...
# License
Copyright (c) 2019 Tomoyuki Sakurai y@trombik.org
Permission to use, copy, modify, and distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
```
Author Information
Tomoyuki Sakurai y@trombik.org
This README was created by qansible.
ansible-galaxy install trombik.opensearch