Ansible-opensearch Initial commit

This commit is contained in:
Nataliia Chaika
2025-08-27 16:24:19 +02:00
commit 90ff0c4c55
29 changed files with 1827 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
.DS_Store

181
README.md Normal file
View File

@@ -0,0 +1,181 @@
# OPENSEARCH & OPENSEARCH-DASHBOARDS ANSIBLE INSTALLATION/REMOVAL
# !Important requirements for Installation Opensearch and Opensearch-Dashboards!
## 1. Open below firewall ports:
5601 OpenSearch Dashboards
9200 OpenSearch REST API
9300 Node communication and transport (internal), cross cluster search
9600 Performance Analyzer
2. Disable swap
3. Change vm.max_map_count and fs.file-max
4. Set time (Important for SSL/TLS certificates)
5. Install usefull/required dependencies
6. Set hostname
7.1. Opensearch:
- Installs competible with OS Java version
- Installs OpenSearch, Generates TLS Certificates, Configures Authentication Backend
7.2. Opensearch-Dashboards:
- Install competible with OS Node.js version on Opensearch-Dashboards VM
- Installs OpenSearch-Dashboards, Generates TLS Certificates
8. Ansible Directory Structure:
.
├── files
├── inventory
│ ├── hosts-multi-node.ini
│ └── hosts-single-node.ini
├── playbooks
│ ├── removal.yml
│ └── setup.yml
├── README.md
├── roles
│ ├── opensearch
│ │ ├── defaults
│ │ │ └── main.yml
│ │ ├── files
│ │ ├── handlers
│ │ │ └── main.yml
│ │ ├── tasks
│ │ │ ├── install.yml
│ │ │ ├── main.yml
│ │ │ ├── preconfig.yml
│ │ │ ├── remove.yml
│ │ │ └── tls.yml
│ │ ├── templates
│ │ │ ├── config.yml.j2
│ │ │ ├── jvm.options.j2
│ │ │ ├── opensearch-multi-node.yml.j2
│ │ │ └── opensearch-single-node.yml.j2
│ │ └── vars
│ │ └── main.yml
│ └── opensearch-dashboards
│ ├── defaults
│ │ └── main.yml
│ ├── files
│ ├── handlers
│ │ └── main.yml
│ ├── tasks
│ │ ├── install.yml
│ │ ├── main.yml
│ │ ├── preconfig.yml
│ │ ├── remove.yml
│ │ └── tls.yml
│ ├── templates
│ │ └── opensearch-dashboards.yml.j2
│ └── vars
│ └── main.yml
├── templates
└── vars
├── general-vars.yml
└── vault.yml
## Playbook contains two cluster installation types:
- single-node
- multi-node
## Files and values to check/replace before playbooks executions:
- inventory/ (IP addresses, DNS names, ssh-key, user)
- roles/opensearch/vars/main.yml (cluster name, certificates or LDAP details)
- roles/opensearch-dashboards/vars/main.yml (certificates details, URL)
- obtain vault pass
## Commands for ansible:
```bash
#ping nodes:
ansible -i inventory/hosts.ini -m ping all
#check syntax:
ansible-playbook -i inventory/hosts-multi-node.ini playbooks/setup.yml --syntax-check
#dry-run:
ansible-playbook -i inventory/hosts-multi-node.ini playbooks/setup.yml --check
#encrypt/decrypt vault.yml file
ansible-vault encrypt vars/vault.yml --vault-password-file ~/.ansible_vault.txt
ansible-vault encrypt vars/vault.yml (input required)
ansible-vault decrypt vars/vault.yml --vault-password-file ~/.ansible_vault.txt
ansible-vault decrypt vars/vault.yml (input required)
#for installation with single node:
ansible-playbook -i inventory/hosts-single-node.ini playbooks/setup.yml -e cluster_type=single-node --vault-password-file ~/.ansible_vault.txt (preffered)
ansible-playbook -i inventory/hosts-single-node.ini playbooks/setup.yml -e cluster_type=single-node --ask-vault-pass (with vault pass input)
#for installation with multi node:
ansible-playbook -i inventory/hosts-multi-node.ini playbooks/setup.yml -e cluster_type=multi-node --vault-password-file ~/.ansible_vault.txt (preffered)
ansible-playbook -i inventory/hosts-multi-node.ini playbooks/setup.yml -e cluster_type=multi-node --ask-vault-pass (with vault pass input)
#for removal single node:
ansible-playbook -i inventory/hosts-single-node.ini playbooks/removal.yml -e cluster_type=single-node
#for removal multi node:
ansible-playbook -i inventory/hosts-multi-node.ini playbooks/removal.yml -e cluster_type=multi-node
```
## Post Installation Steps:
1. Update passwords for internal users (admin and kibanaserver), using export JAVA_HOME=/usr/share/opensearch/jdk/ && /usr/share/opensearch/plugins/opensearch-security/tools/securityadmin.sh ./hash.sh tool:
2. For LDAP Setup, do the following:
update /etc/opensearch/opensearch-security/config.yml with required configuration
update /etc/opensearch/opensearch-security/internal_users.yml
update /etc/opensearch/opensearch-security/roles_mapping.yml
## Perform one by one commands:
export JAVA_HOME=/usr/share/opensearch/jdk/ && /usr/share/opensearch/plugins/opensearch-security/tools/securityadmin.sh -cd /etc/opensearch/opensearch-security -f "/etc/opensearch/opensearch-security/config.yml" -icl -key /etc/opensearch/certs/admin-key.pem -cert /etc/opensearch/certs/admin.pem -cacert /etc/opensearch/certs/root-ca.pem -nhnv
export JAVA_HOME=/usr/share/opensearch/jdk/ && /usr/share/opensearch/plugins/opensearch-security/tools/securityadmin.sh -cd /etc/opensearch/opensearch-security -f "/etc/opensearch/opensearch-security/internal_users.yml" -icl -key /etc/opensearch/certs/admin-key.pem -cert /etc/opensearch/certs/admin.pem -cacert /etc/opensearch/certs/root-ca.pem -nhnv
export JAVA_HOME=/usr/share/opensearch/jdk/ && /usr/share/opensearch/plugins/opensearch-security/tools/securityadmin.sh -cd /etc/opensearch/opensearch-security -f "/etc/opensearch/opensearch-security/roles_mapping.yml" -icl -key /etc/opensearch/certs/admin-key.pem -cert /etc/opensearch/certs/admin.pem -cacert /etc/opensearch/certs/
## Or perform single command for all files update:
export JAVA_HOME=/usr/share/opensearch/jdk/ && /usr/share/opensearch/plugins/opensearch-security/tools/securityadmin.sh -cd /etc/opensearch/opensearch-security - -icl -key /etc/opensearch/certs/admin-key.pem -cert /etc/opensearch/certs/admin.pem -cacert /etc/opensearch/certs/root-ca.pem -nhnv
## Useful commands:
# OPENSEARCH:
Check cluster status:
```bash
curl --cert /etc/opensearch/certs/admin.pem --key /etc/opensearch/certs/admin-key.pem --cacert /etc/opensearch/certs/root-ca.pem https://node1.opensearch.local:9200/_cluster/health?pretty
```
Check nodes status:
```bash
curl --cert /etc/opensearch/certs/admin.pem \
--key /etc/opensearch/certs/admin-key.pem \
--cacert /etc/opensearch/certs/root-ca.pem \
https://node1.opensearch.local:9200/_cat/nodes?v
```
# LDAP (example for testing env):
test connection:
```bash
ldapsearch -x -H ldap://LDAP_IP:389 -D "cn=admin,dc=ldap,dc=local" -w password -s base
```
check whether user exists:
```bash
ldapsearch -x -H ldap://LDAP_IP:389 \-H ldap://LDAP_IP:389 -D "cn=admin,dc=ldap,dc=local" -w password -b "ou=users,dc=ldap,dc=local" "(uid=john)"
```
check access user access with curl:
```bash
curl -u john:password -k https://node1.opensearch.local:9200/_cluster/health
```

View File

@@ -0,0 +1,15 @@
[opensearch]
node1.opensearch.local ip=IP_1 roles=cluster_manager,data,ingest
node2.opensearch.local ip=IP_2 roles=data,ingest
node3.opensearch.local ip=IP_3 roles=data,ingest
[master]
node1.opensearch.local
[dashboards]
node1.opensearch.local ip=IP_1
[all:vars]
ansible_host={{ ip }}
ansible_user=rocky
ansible_ssh_private_key_file=~/.ssh/id_rsa

View File

@@ -0,0 +1,13 @@
[opensearch]
node1.opensearch.local ip=IP_1 roles=cluster_manager,data,ingest
[master]
node1.opensearch.local
[dashboards]
node1.opensearch.local ip=IP_1
[all:vars]
ansible_host={{ ip }}
ansible_user=rocky
ansible_ssh_private_key_file=~/.ssh/id_rsa

17
playbooks/removal.yml Normal file
View File

@@ -0,0 +1,17 @@
#Ansible-playbook for removing OpenSearch configuration
---
- name: Remove OpenSearch on cluster nodes
hosts: opensearch
become: yes
roles:
- role: ../roles/opensearch
vars:
state: absent
- name: Remove OpenSearch Dashboard
hosts: dashboards
become: yes
roles:
- role: ../roles/opensearch-dashboards
vars:
state: absent

26
playbooks/setup.yml Normal file
View File

@@ -0,0 +1,26 @@
#Ansible-playbook for installation OpenSearch
---
- name: Install OpenSearch on cluster nodes
hosts: opensearch
become: yes
vars_files:
- ../vars/vault.yml
roles:
- role: ../roles/opensearch
vars:
state: present
vars_prompt:
- name: "opensearch_admin_password"
prompt: "Enter OpenSearch initial admin password"
private: yes
- name: Install OpenSearch Dashboards
hosts: dashboards
become: yes
vars_files:
- ../vars/vault.yml
roles:
- role: ../roles/opensearch-dashboards
vars:
state: present

View File

@@ -0,0 +1,2 @@
---
# defaults file for opensearch-dashboards

View File

@@ -0,0 +1,11 @@
---
# handlers file for opensearch-dashboards
- name: Reload firewalld
ansible.builtin.systemd:
name: firewalld
state: reloaded
- name: Restart OpenSearch Dashboards
ansible.builtin.systemd:
name: opensearch-dashboards
state: restarted

View File

@@ -0,0 +1,25 @@
---
- name: Download OpenSearch Dashboards repo file
ansible.builtin.get_url:
url: "{{ os_dashboards_url }}"
dest: /etc/yum.repos.d/opensearch-dashboards-3.x.repo
mode: '0644'
- name: Install OpenSearch Dashboards
ansible.builtin.dnf:
name: opensearch-dashboards
state: present
- name: Configure OpenSearch
template:
src: "opensearch-dashboards.yml.j2"
dest: /etc/opensearch-dashboards/opensearch_dashboards.yml
owner: opensearch-dashboards
group: opensearch-dashboards
- name: Enable and start OpenSearch Dashboards service
ansible.builtin.systemd:
name: opensearch-dashboards
enabled: true
state: started

View File

@@ -0,0 +1,17 @@
# tasks file for opensearch-dashboards
---
- name: Tune the system settings
include_tasks: preconfig.yml
when: state == "present"
- name: OpenSearch Dashboards installation and configuration
ansible.builtin.import_tasks: install.yml
when: state == "present"
- name: Configure TLS certificates
include_tasks: tls.yml
when: state == "present"
- name: OpenSearch Dashboards removal
include_tasks: remove.yml
when: state == "absent"

View File

@@ -0,0 +1,24 @@
---
- name: Ensure curl is installed
ansible.builtin.dnf:
name: curl
state: present
- name: Add NodeSource Node.js 18 repo
ansible.builtin.shell: "curl -fsSL {{ node_url }} | bash -"
register: nodesource_repo
changed_when: "'Complete!' in nodesource_repo.stdout"
- name: Install Node.js 18
ansible.builtin.dnf:
name: nodejs
state: present
- name: Verify Node.js version
ansible.builtin.command: node -v
register: node_version
changed_when: false
- name: Show installed Node.js version
ansible.builtin.debug:
msg: "Installed Node.js version: {{ node_version.stdout }}"

View File

@@ -0,0 +1,64 @@
---
- name: Stop and disable Opensearch-Dashboards
ansible.builtin.systemd:
name: opensearch-dashboards
state: stopped
enabled: no
ignore_errors: yes
- name: Remove Opensearch-Dashboards package
ansible.builtin.dnf:
name: opensearch-dashboards
state: absent
autoremove: yes
ignore_errors: yes
- name: Delete Opensearch-Dashboards shared directory
ansible.builtin.file:
path: /usr/share/opensearch-dashboards
state: absent
ignore_errors: yes
- name: Delete Opensearch-Dashboards configuration directory
ansible.builtin.file:
path: /etc/opensearch-dashboards
state: absent
- name: Delete Opensearch-Dashboards data directory
ansible.builtin.file:
path: /var/lib/opensearch-dashboards
state: absent
ignore_errors: yes
- name: Delete Opensearch-Dashboards log directory
ansible.builtin.file:
path: /var/log/opensearch-dashboards
state: absent
- name: Delete Opensearch-Dashboards repository file
ansible.builtin.file:
path: /etc/yum.repos.d/opensearch-dashboards-3.x.repo
state: absent
- name: Clean up DNF cache for Opensearch-Dashboards
ansible.builtin.command: dnf clean all
changed_when: true
- name: Remove Opensearch-Dashboards system user and group
ansible.builtin.user:
name: opensearch-dashboards
state: absent
remove: yes
ignore_errors: yes
- name: Close Firewall port for Opensearch-Dashboards
ansible.posix.firewalld:
port: "{{ firewall_os_dashboards_port }}/tcp"
permanent: yes
state: disabled
zone: public
notify:
- Reload firewalld
ignore_errors: yes

View File

@@ -0,0 +1,123 @@
---
#Check directory, create one if it doesn't exist
- name: Ensure certificate directory exists
file:
path: "{{ cert_dir }}"
owner: opensearch-dashboards
group: opensearch-dashboards
state: directory
mode: '0700'
#Copy root-ca.pem and root-ca-key.pem to /etc/opensearch-dashboards/certs
- name: Copy root CA cert and key to dashboards cert directory
copy:
src: "{{ root_ca_dir }}/{{ item }}"
dest: "{{ cert_dir }}/{{ item }}"
owner: root
group: root
mode: '0644'
remote_src: yes
loop:
- root-ca.pem
- root-ca-key.pem
#Generate Intermediate CA files
- name: Generate intermediate CA private key
community.crypto.openssl_privatekey:
path: "{{ cert_dir }}/intermediate-ca-key.pem"
format: pkcs8
run_once: true
become: yes
- name: Generate intermediate CA CSR
community.crypto.openssl_csr:
path: "{{ cert_dir }}/intermediate-ca.csr"
privatekey_path: "{{ cert_dir }}/intermediate-ca-key.pem"
common_name: "{{ intermediate_ca_cn }}"
organization_name: "MyOrg"
organizational_unit_name: "Intermediate"
basic_constraints:
- 'CA:TRUE'
basic_constraints_critical: true
key_usage:
- keyCertSign
- cRLSign
key_usage_critical: true
run_once: true
become: yes
- name: Sign intermediate CA with root CA
community.crypto.x509_certificate:
path: "{{ cert_dir }}/intermediate-ca.pem"
csr_path: "{{ cert_dir }}/intermediate-ca.csr"
provider: ownca
ownca_path: "{{ root_ca_dir }}/root-ca.pem"
ownca_privatekey_path: "{{ root_ca_dir }}/root-ca-key.pem"
ownca_not_after: "+730d"
ownca_not_before: "-1d"
ownca_digest: sha256
run_once: true
become: yes
#Generate client key and certificate
- name: Generate client private key
openssl_privatekey:
path: "{{ cert_dir }}/client-cert-key.pem"
run_once: true
become: yes
- name: Generate client CSR
community.crypto.openssl_csr:
path: "{{ cert_dir }}/client-cert.csr"
privatekey_path: "{{ cert_dir }}/client-cert-key.pem"
common_name: "{{ dashboards_cn }}"
organization_name: "MyOrg"
organizational_unit_name: "Dashboards"
run_once: true
become: yes
- name: Sign client certificate with intermediate CA
community.crypto.x509_certificate:
path: "{{ cert_dir }}/client-cert.pem"
csr_path: "{{ cert_dir }}/client-cert.csr"
privatekey_path: "{{ cert_dir }}/client-cert-key.pem"
ownca_path: "{{ cert_dir }}/intermediate-ca.pem"
ownca_privatekey_path: "{{ cert_dir }}/intermediate-ca-key.pem"
provider: ownca
ownca_not_after: +730d
ownca_not_before: "-1d"
ownca_digest: sha256
run_once: true
become: yes
- name: Secure private keys
ansible.builtin.shell: chmod 600 {{ cert_dir }}/*-key.pem
become: yes
ignore_errors: yes
- name: Set permissions for CSRs
ansible.builtin.shell: chmod 644 {{ cert_dir }}/*.csr
become: yes
ignore_errors: yes
- name: Set permissions for certificates
ansible.builtin.shell: chmod 644 {{ cert_dir }}/*.pem
become: yes
ignore_errors: yes
#Remove temporary files
# - name: Remove temporary files if they exist
# file:
# path: "{{ item }}"
# state: absent
# loop:
# - "{{ cert_dir }}/intermediate-ca-key.pem"
# - "{{ cert_dir }}/intermediate-ca.csr"
# - "{{ cert_dir }}/client-cert.csr"
# ignore_errors: yes
- name: Certificate generation complete
debug:
msg: "Certificates are located at {{ cert_dir }}"
notify: Restart OpenSearch Dashboards

View File

@@ -0,0 +1,234 @@
---
# ======================== OpenSearch Dashboards Configuration =========================
#
# .dP"Y8 Yb dP 88 .dP"Y8 .dP"Y8 8b d8 db 88 dP 888888 88""Yb .dP"Y8 .dP"Y8 88 888888 8b d8
# `Ybo." Yb db dP 88 `Ybo." `Ybo." 88b d88 dPYb 88odP 88__ 88__dP `Ybo." `Ybo." 88 88__ 88b d88
# o.`Y8b YbdPYbdP 88 o.`Y8b o.`Y8b 88YbdP88 dP__Yb 88"Yb 88"" 88"Yb o.`Y8b o.`Y8b 88 88"" 88YbdP88
# 8bodP' YP YP 88 8bodP' 8bodP' 88 YY 88 dP""""Yb 88 Yb 888888 88 Yb 8bodP' 8bodP' 88 888888 88 YY 88
#
# Copyright OpenSearch Contributors
# SPDX-License-Identifier: Apache-2.0
# Description:
# Configuration for OpenSearch Dashboards
# OpenSearch Dashboards is served by a back end server. This setting specifies the port to use.
# server.port: 5601
# Specifies the address to which the OpenSearch Dashboards server will bind. IP addresses and host names are both valid values.
# The default is 'localhost', which usually means remote machines will not be able to connect.
# To allow connections from remote users, set this parameter to a non-loopback address.
server.host: 0.0.0.0
# Enables you to specify a path to mount OpenSearch Dashboards at if you are running behind a proxy.
# Use the `server.rewriteBasePath` setting to tell OpenSearch Dashboards if it should remove the basePath
# from requests it receives, and to prevent a deprecation warning at startup.
# This setting cannot end in a slash.
# server.basePath: ""
# Specifies whether OpenSearch Dashboards should rewrite requests that are prefixed with
# `server.basePath` or require that they are rewritten by your reverse proxy.
# server.rewriteBasePath: false
# The maximum payload size in bytes for incoming server requests.
# server.maxPayloadBytes: 1048576
# The OpenSearch Dashboards server's name. This is used for display purposes.
# server.name: "your-hostname"
# The URLs of the OpenSearch instances to use for all your queries.
opensearch.hosts: ["https://node1.opensearch.local:9200"]
# OpenSearch Dashboards uses an index in OpenSearch to store saved searches, visualizations and
# dashboards. OpenSearch Dashboards creates a new index if the index doesn't already exist.
# opensearchDashboards.index: ".opensearch_dashboards"
# The default application to load.
# opensearchDashboards.defaultAppId: "home"
# Setting for an optimized healthcheck that only uses the local OpenSearch node to do Dashboards healthcheck.
# This settings should be used for large clusters or for clusters with ingest heavy nodes.
# It allows Dashboards to only healthcheck using the local OpenSearch node rather than fan out requests across all nodes.
#
# It requires the user to create an OpenSearch node attribute with the same name as the value used in the setting
# This node attribute should assign all nodes of the same cluster an integer value that increments with each new cluster that is spun up
# e.g. in opensearch.yml file you would set the value to a setting using node.attr.cluster_id:
# Should only be enabled if there is a corresponding node attribute created in your OpenSearch config that matches the value here
# opensearch.optimizedHealthcheckId: "cluster_id"
# If your OpenSearch is protected with basic authentication, these settings provide
# the username and password that the OpenSearch Dashboards server uses to perform maintenance on the OpenSearch Dashboards
# index at startup. Your OpenSearch Dashboards users still need to authenticate with OpenSearch, which
# is proxied through the OpenSearch Dashboards server.
opensearch.username: "kibanaserver"
opensearch.password: "{{ vault_kibana_pass }}"
# Enables SSL and paths to the PEM-format SSL certificate and SSL key files, respectively.
# These settings enable SSL for outgoing requests from the OpenSearch Dashboards server to the browser.
server.ssl.enabled: true
server.ssl.certificate: /etc/opensearch-dashboards/certs/client-cert.pem
server.ssl.key: /etc/opensearch-dashboards/certs/client-cert-key.pem
# Optional settings that provide the paths to the PEM-format SSL certificate and key files.
# These files are used to verify the identity of OpenSearch Dashboards to OpenSearch and are required when
# xpack.security.http.ssl.client_authentication in OpenSearch is set to required.
# opensearch.ssl.certificate: /path/to/your/client.crt
# opensearch.ssl.key: /path/to/your/client.key
# Optional setting that enables you to specify a path to the PEM file for the certificate
# authority for your OpenSearch instance.
opensearch.ssl.certificateAuthorities: [ "/etc/opensearch-dashboards/certs/root-ca.pem", "/etc/opensearch-dashboards/certs/intermediate-ca.pem" ]
# To disregard the validity of SSL certificates, change this setting's value to 'none'.
opensearch.ssl.verificationMode: full
# Time in milliseconds to wait for OpenSearch to respond to pings. Defaults to the value of
# the opensearch.requestTimeout setting.
# opensearch.pingTimeout: 1500
# Time in milliseconds to wait for responses from the back end or OpenSearch. This value
# must be a positive integer.
# opensearch.requestTimeout: 30000
# List of OpenSearch Dashboards client-side headers to send to OpenSearch. To send *no* client-side
# headers, set this value to [] (an empty list).
# opensearch.requestHeadersWhitelist: [ authorization ]
# Header names and values that are sent to OpenSearch. Any custom headers cannot be overwritten
# by client-side headers, regardless of the opensearch.requestHeadersWhitelist configuration.
# opensearch.customHeaders: {}
# Time in milliseconds for OpenSearch to wait for responses from shards. Set to 0 to disable.
# opensearch.shardTimeout: 30000
# Logs queries sent to OpenSearch. Requires logging.verbose set to true.
# opensearch.logQueries: false
# Specifies the path where OpenSearch Dashboards creates the process ID file.
# pid.file: /var/run/opensearchDashboards.pid
# Enables you to specify a file where OpenSearch Dashboards stores log output.
# logging.dest: stdout
# 2.15 Ignore 'ENOSPC' error for logging stream.
# When set to true, the 'ENOSPC' error message will not cause the OpenSearch Dashboards process to crash. Otherwise,
# the original behavior will be maintained. It is disabled by default.
# logging.ignoreEnospcError: false
# Set the value of this setting to true to suppress all logging output.
# logging.silent: false
# Set the value of this setting to true to suppress all logging output other than error messages.
# logging.quiet: false
# Set the value of this setting to true to log all events, including system usage information
# and all requests.
# logging.verbose: false
# Set the interval in milliseconds to sample system and process performance
# metrics. Minimum is 100ms. Defaults to 5000.
# ops.interval: 5000
# Specifies locale to be used for all localizable strings, dates and number formats.
# Supported languages are the following: English - en , by default , Chinese - zh-CN .
# i18n.locale: "en"
# Set the allowlist to check input graphite Url. Allowlist is the default check list.
# vis_type_timeline.graphiteAllowedUrls: ['https://www.hostedgraphite.com/UID/ACCESS_KEY/graphite']
# Set the blocklist to check input graphite Url. Blocklist is an IP list.
# Below is an example for reference
# vis_type_timeline.graphiteBlockedIPs: [
# //Loopback
# '127.0.0.0/8',
# '::1/128',
# //Link-local Address for IPv6
# 'fe80::/10',
# //Private IP address for IPv4
# '10.0.0.0/8',
# '172.16.0.0/12',
# '192.168.0.0/16',
# //Unique local address (ULA)
# 'fc00::/7',
# //Reserved IP address
# '0.0.0.0/8',
# '100.64.0.0/10',
# '192.0.0.0/24',
# '192.0.2.0/24',
# '198.18.0.0/15',
# '192.88.99.0/24',
# '198.51.100.0/24',
# '203.0.113.0/24',
# '224.0.0.0/4',
# '240.0.0.0/4',
# '255.255.255.255/32',
# '::/128',
# '2001:db8::/32',
# 'ff00::/8',
# ]
# vis_type_timeline.graphiteBlockedIPs: []
# opensearchDashboards.branding:
# logo:
# defaultUrl: ""
# darkModeUrl: ""
# mark:
# defaultUrl: ""
# darkModeUrl: ""
# loadingLogo:
# defaultUrl: ""
# darkModeUrl: ""
# faviconUrl: ""
# applicationTitle: ""
# Set the value of this setting to true to capture region blocked warnings and errors
# for your map rendering services.
# map.showRegionBlockedWarning: false%
# Set the value of this setting to false to suppress search usage telemetry
# for reducing the load of OpenSearch cluster.
# data.search.usageTelemetry.enabled: false
# 2.4 renames 'wizard.enabled: false' to 'vis_builder.enabled: false'
# Set the value of this setting to false to disable VisBuilder
# functionality in Visualization.
# vis_builder.enabled: false
# 2.4 New Experimental Feature
# Set the value of this setting to true to enable the experimental multiple data source
# support feature. Use with caution.
# data_source.enabled: false
# Set the value of these settings to customize crypto materials to encryption saved credentials
# in data sources.
# data_source.encryption.wrappingKeyName: 'changeme'
# data_source.encryption.wrappingKeyNamespace: 'changeme'
# data_source.encryption.wrappingKey: [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
# 2.6 New ML Commons Dashboards Feature
# Set the value of this setting to true to enable the ml commons dashboards
# ml_commons_dashboards.enabled: false
# 2.12 New Experimental Assistant Dashboards Feature
# Set the value of this setting to true to enable the assistant dashboards
# assistant.chat.enabled: false
# 2.13 New Query Assistant Feature
# Set the value of this setting to false to disable the query assistant
# observability.query_assist.enabled: false
# 2.14 Enable Ui Metric Collectors in Usage Collector
# Set the value of this setting to true to enable UI Metric collections
# usageCollection.uiMetric.enabled: false
# 2.18 New Experimental Settings
# Set the value to true to enable
# assistant.alertInsight.enabled: false
# assistant.smartAnomalyDetector.enabled: false
# assistant.text2viz.enabled: false
# queryEnhancements.queryAssist.summary.enabled: false
opensearch.requestHeadersAllowlist: [ authorization,securitytenant ]
opensearch_security.multitenancy.enabled: true
opensearch_security.multitenancy.tenants.preferred: ["Private", "Global"]
opensearch_security.readonly_mode.roles: ["kibana_read_only"]
opensearch_security.cookie.secure: true

View File

@@ -0,0 +1,11 @@
# vars file for OpenSearch-Dashboards
---
key_size: 4096
intermediate_ca_cn: "OpenSearch Intermediate CA"
dashboards_cn: node1.opensearch.local
cert_dir: "/etc/opensearch-dashboards/certs"
root_ca_dir: "/etc/opensearch/certs"
firewall_os_dashboards_port: 5601
os_dashboards_url: https://artifacts.opensearch.org/releases/bundle/opensearch-dashboards/3.x/opensearch-dashboards-3.x.repo
node_url: https://rpm.nodesource.com/setup_18.x

View File

@@ -0,0 +1 @@
cluster_type: multi-node

View File

@@ -0,0 +1,17 @@
# handlers file for opensearch role
---
- name: Reload firewalld
ansible.builtin.command: firewall-cmd --reload
become: true
- name: Restart Opensearch
ansible.builtin.systemd:
name: opensearch
state: restarted
enabled: yes
- name: Restart chrony
become: true
ansible.builtin.service:
name: chronyd
state: restarted

View File

@@ -0,0 +1,50 @@
---
- name: Download OpenSearch repo file using curl
ansible.builtin.command:
cmd: curl -fsSL -o /etc/yum.repos.d/opensearch-3.x.repo "{{ os_url }}"
args:
creates: /etc/yum.repos.d/opensearch-3.x.repo
- name: Clean yum cache
ansible.builtin.yum:
name: '*'
state: latest
update_cache: yes
become: yes
- name: Set crypto policy to DEFAULT:SHA1 for Rocky 9 compatibility
ansible.builtin.command:
cmd: update-crypto-policies --set DEFAULT:SHA1
become: yes
ignore_errors: yes
- name: Install OpenSearch with initial admin password set in environment
ansible.builtin.yum:
name: opensearch
state: present
environment:
OPENSEARCH_INITIAL_ADMIN_PASSWORD: "{{ opensearch_admin_password }}"
- name: Reset crypto policy back to DEFAULT
ansible.builtin.command:
cmd: update-crypto-policies --set DEFAULT
become: yes
ignore_errors: yes
- name: Configure JVM options - set Xms and Xmx values
template:
src: jvm.options.j2
dest: /etc/opensearch/jvm.options
- name: Configure OpenSearch LDAP
template:
src: config.yml.j2
dest: /etc/opensearch/opensearch-security/config.yml
owner: opensearch
group: opensearch
mode: '0640'
- name: Configure OpenSearch
template:
src: "opensearch-{{ cluster_type }}.yml.j2"
dest: /etc/opensearch/opensearch.yml

View File

@@ -0,0 +1,17 @@
# Tasks sequence for opensearch role
---
- name: Tune the system settings
include_tasks: preconfig.yml
when: state == "present"
- name: OpenSearch installation and configuration
ansible.builtin.import_tasks: install.yml
when: state == "present"
- name: Configure TLS certificates
include_tasks: tls.yml
when: state == "present"
- name: OpenSearch remove
include_tasks: remove.yml
when: state == "absent"

View File

@@ -0,0 +1,114 @@
# Pre-configuration required for OpenSearch
---
- name: Update all packages
dnf:
name: "*"
state: latest
update_cache: yes
- name: Set vm.max_map_count in sysctl.conf
ansible.posix.sysctl:
name: vm.max_map_count
value: 262144
state: present
- name: Set open files limit in sysctl.conf
ansible.posix.sysctl:
name: fs.file-max
value: 65536
state: present
- name: Install OpenJDK 17 JDK
dnf:
name: java-17-openjdk
state: present
ignore_errors: yes
- name: Install required dependencies
ansible.builtin.dnf:
name: "{{ item }}"
state: present
loop:
- vim
- rsync
- tar
- unzip
- bzip2
- yum-utils
- curl
- wget
- bash-completion
- policycoreutils-python-utils
- mlocate
- bind-utils
- chrony
ignore_errors: yes
- name: Set FQDN as hostname
ansible.builtin.hostname:
name: "{{ inventory_hostname }}"
- name: Ensure FQDN is in /etc/hosts
ansible.builtin.lineinfile:
path: /etc/hosts
regexp: "^{{ ansible_host }}\\s+"
line: "{{ ansible_host }} {{ inventory_hostname }} {{ inventory_hostname.split('.')[0] }}"
state: present
- name: Set timezone to Europe/Zurich
become: true
community.general.timezone:
name: Europe/Zurich
- name: Enable system NTP with timedatectl
become: true
ansible.builtin.command: timedatectl set-ntp true
- name: Sync system clock immediately with NTP servers
become: true
ansible.builtin.command: chronyc -a 'makestep'
- name: Open Firewall port 9200/tcp for OpenSearch REST API
ansible.posix.firewalld:
port: "{{ firewall_os_port }}/tcp"
permanent: yes
state: enabled
zone: public
notify:
- Reload firewalld
- name: Open Firewall port 9300/tcp for Node communication and transport, cross cluster search
ansible.posix.firewalld:
port: "{{ firewall_os_internal_port }}/tcp"
permanent: yes
state: enabled
zone: public
notify:
- Reload firewalld
- name: Open Firewall port 9600/tcp for OpenSearch Performance Analyzer
ansible.posix.firewalld:
port: "{{ firewall_os_pa_port }}/tcp"
permanent: yes
state: enabled
zone: public
notify:
- Reload firewalld
- name: Open Firewall port 5601/tcp for OpenSearch Dashboards
ansible.posix.firewalld:
port: "{{ firewall_os_dashboards_port }}/tcp"
permanent: yes
state: enabled
zone: public
notify:
- Reload firewalld
- name: Reload firewall-cmd
ansible.builtin.command: firewall-cmd --reload
become: true
- name: Disable swap with sed
ansible.builtin.shell: |
sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
swapoff -a

View File

@@ -0,0 +1,81 @@
---
- name: Stop and disable OpenSearch service
ansible.builtin.systemd:
name: opensearch
state: stopped
enabled: no
ignore_errors: yes
- name: Remove OpenSearch package
ansible.builtin.dnf:
name: opensearch
state: absent
autoremove: yes
ignore_errors: yes
- name: Delete OpenSearch shared directory
ansible.builtin.file:
path: /usr/share/opensearch
state: absent
ignore_errors: yes
- name: Delete OpenSearch configuration directory
ansible.builtin.file:
path: /etc/opensearch
state: absent
- name: Delete OpenSearch data directory
ansible.builtin.file:
path: /var/lib/opensearch
state: absent
- name: Delete OpenSearch log directory
ansible.builtin.file:
path: /var/log/opensearch
state: absent
- name: Delete OpenSearch repository file
ansible.builtin.file:
path: /etc/yum.repos.d/opensearch.repo
state: absent
- name: Remove opensearch.xml firewalld service definition
ansible.builtin.file:
path: /usr/lib/firewalld/services/opensearch.xml
state: absent
ignore_errors: yes
- name: Clean up DNF cache for OpenSearch
ansible.builtin.command: dnf clean all
changed_when: true
- name: Remove OpenSearch system user and group
ansible.builtin.user:
name: opensearch
state: absent
remove: yes
ignore_errors: yes
- name: Close Firewall port for OpenSearch
ansible.posix.firewalld:
port: "{{ firewall_os_port }}/tcp"
permanent: yes
state: disabled
zone: public
- name: Close Firewall port 9300/tcp for Node communication and transport, cross cluster search
ansible.posix.firewalld:
port: "{{ firewall_os_internal_port }}/tcp"
permanent: yes
state: disabled
zone: public
- name: Close Firewall port 9600/tcp for OpenSearch Performance Analyzer
ansible.posix.firewalld:
port: "{{ firewall_os_pa_port }}/tcp"
permanent: yes
state: disabled
zone: public
notify:
- Reload firewalld

View File

@@ -0,0 +1,259 @@
# Certificates generation for OpenSearch
---
- name: Create a temporary directory for certificate generation
ansible.builtin.file:
path: "{{ opensearch_certs_temp_path }}"
state: directory
mode: '0755'
delegate_to: localhost
run_once: true
become: no
- name: Create certificates directory
ansible.builtin.file:
path: "{{ opensearch_certs_remote_path }}"
state: directory
mode: '0700'
owner: opensearch
group: opensearch
become: true
- name: Find all .pem files
find:
paths: /etc/opensearch
patterns: "*.pem"
register: pem_files
- name: Remove all .pem files
file:
path: "{{ item.path }}"
state: absent
loop: "{{ pem_files.files }}"
# Root CA Generation
- name: Create Root CA private key
community.crypto.openssl_privatekey:
path: "{{ opensearch_certs_temp_path }}/root-ca-key.pem"
delegate_to: localhost
run_once: true
become: no
- name: Generate an in-memory CSR for the Root CA
community.crypto.openssl_csr_pipe:
privatekey_path: "{{ opensearch_certs_temp_path }}/root-ca-key.pem"
subject: "{{ ca_subject }}"
basic_constraints:
- 'CA:TRUE'
basic_constraints_critical: true
key_usage:
- keyCertSign
- cRLSign
key_usage_critical: true
register: ca_csr
delegate_to: localhost
run_once: true
become: no
- name: Create a self-signed Root CA certificate from the CSR
community.crypto.x509_certificate:
path: "{{ opensearch_certs_temp_path }}/root-ca.pem"
csr_content: "{{ ca_csr.csr }}"
privatekey_path: "{{ opensearch_certs_temp_path }}/root-ca-key.pem"
provider: selfsigned
selfsigned_digest: sha256
selfsigned_not_after: "+730d"
delegate_to: localhost
run_once: true
become: no
# Admin Certificate Generation
- name: Generate admin private key
community.crypto.openssl_privatekey:
path: "{{ opensearch_certs_temp_path }}/admin-key.pem"
size: "{{ opensearch_key_size }}"
format: pkcs8
delegate_to: localhost
run_once: true
become: no
- name: Generate admin CSR
community.crypto.openssl_csr:
path: "{{ opensearch_certs_temp_path }}/admin.csr"
privatekey_path: "{{ opensearch_certs_temp_path }}/admin-key.pem"
common_name: "{{ opensearch_admin_common_name }}"
organization_name: "MyOrg"
organizational_unit_name: "Admins"
delegate_to: localhost
run_once: true
become: no
- name: Sign admin certificate with Root CA
community.crypto.x509_certificate:
path: "{{ opensearch_certs_temp_path }}/admin.pem"
csr_path: "{{ opensearch_certs_temp_path }}/admin.csr"
ownca_path: "{{ opensearch_certs_temp_path }}/root-ca.pem"
ownca_privatekey_path: "{{ opensearch_certs_temp_path }}/root-ca-key.pem"
provider: ownca
ownca_not_after: +730d
ownca_not_before: "-1d"
ownca_digest: sha256
delegate_to: localhost
run_once: true
become: no
# Nodes Certificates
# Build nodes info dynamically from inventory group "opensearch"
- name: Build nodes info from inventory
set_fact:
opensearch_nodes_info: >-
{{
opensearch_nodes_info | default([]) +
[
{
"name": item.split('.')[0],
"common_name": item,
"san": ["DNS:" ~ item]
}
]
}}
loop: "{{ groups['opensearch'] }}"
run_once: true
delegate_to: localhost
- name: Generate keys and certificates for each node
block:
- name: "Generate private key for {{ item.name }}"
community.crypto.openssl_privatekey:
path: "{{ opensearch_certs_temp_path }}/{{ item.name }}-key.pem"
size: "{{ opensearch_key_size }}"
format: pkcs8
delegate_to: localhost
loop: "{{ opensearch_nodes_info }}"
loop_control:
loop_var: item
become: no
- name: Generate CSR for {{ item.name }}
community.crypto.openssl_csr:
path: "{{ opensearch_certs_temp_path }}/{{ item.name }}.csr"
privatekey_path: "{{ opensearch_certs_temp_path }}/{{ item.name }}-key.pem"
common_name: "{{ item.common_name }}"
subject_alt_name: "{{ item.san }}"
organization_name: "MyOrg"
organizational_unit_name: "Nodes"
delegate_to: localhost
loop: "{{ opensearch_nodes_info }}"
loop_control:
loop_var: item
become: no
- name: Sign {{ item.name }} certificate with Root CA
community.crypto.x509_certificate:
path: "{{ opensearch_certs_temp_path }}/{{ item.name }}.pem"
csr_path: "{{ opensearch_certs_temp_path }}/{{ item.name }}.csr"
ownca_path: "{{ opensearch_certs_temp_path }}/root-ca.pem"
ownca_privatekey_path: "{{ opensearch_certs_temp_path }}/root-ca-key.pem"
provider: ownca
ownca_not_after: +730d
ownca_not_before: "-1d"
ownca_digest: sha256
delegate_to: localhost
loop: "{{ opensearch_nodes_info }}"
loop_control:
loop_var: item
become: no
run_once: true
# Client Certificate Generation
- name: Generate client private key
community.crypto.openssl_privatekey:
path: "{{ opensearch_certs_temp_path }}/client-key.pem"
size: "{{ opensearch_key_size }}"
format: pkcs8
delegate_to: localhost
run_once: true
become: no
- name: Generate client CSR
community.crypto.openssl_csr:
path: "{{ opensearch_certs_temp_path }}/client.csr"
privatekey_path: "{{ opensearch_certs_temp_path }}/client-key.pem"
common_name: "{{ opensearch_client_common_name }}"
subject_alt_name: "{{ opensearch_client_san }}"
organization_name: "MyOrg"
organizational_unit_name: "Clients"
delegate_to: localhost
run_once: true
become: no
- name: Sign client certificate with Root CA
community.crypto.x509_certificate:
path: "{{ opensearch_certs_temp_path }}/client.pem"
csr_path: "{{ opensearch_certs_temp_path }}/client.csr"
ownca_path: "{{ opensearch_certs_temp_path }}/root-ca.pem"
ownca_privatekey_path: "{{ opensearch_certs_temp_path }}/root-ca-key.pem"
provider: ownca
ownca_not_after: +730d
ownca_not_before: "-1d"
ownca_digest: sha256
delegate_to: localhost
run_once: true
become: no
# Distribution of certificates
- name: Distribute required certificates to all OpenSearch nodes
ansible.builtin.copy:
src: "{{ opensearch_certs_temp_path }}/{{ item.src }}"
dest: "{{ opensearch_certs_remote_path }}/{{ item.dest }}"
owner: opensearch
group: opensearch
mode: '0640'
loop:
- { src: "root-ca.pem", dest: "root-ca.pem" }
- { src: "root-ca-key.pem", dest: "root-ca-key.pem" }
- { src: "admin.pem", dest: "admin.pem" }
- { src: "admin-key.pem", dest: "admin-key.pem" }
- { src: "client.pem", dest: "client.pem" }
- { src: "client-key.pem", dest: "client-key.pem" }
become: yes
- name: Distribute node-specific private key
ansible.builtin.copy:
src: "{{ opensearch_certs_temp_path }}/{{ ansible_hostname }}-key.pem"
dest: "{{ opensearch_certs_remote_path }}/{{ ansible_hostname }}-key.pem"
owner: opensearch
group: opensearch
mode: '0640'
become: yes
- name: Distribute node-specific certificate
ansible.builtin.copy:
src: "{{ opensearch_certs_temp_path }}/{{ ansible_hostname }}.pem"
dest: "{{ opensearch_certs_remote_path }}/{{ ansible_hostname }}.pem"
owner: opensearch
group: opensearch
mode: '0640'
become: yes
- name: Enable and start opensearch service
ansible.builtin.systemd:
name: opensearch
enabled: yes
state: started
become: yes
- name: Check status of opensearch service
ansible.builtin.systemd:
name: opensearch
state: started
become: yes
# #Cleanup
# - name: "Clean up temporary files"
# ansible.builtin.file:
# path: "{{ opensearch_certs_temp_path }}"
# state: absent
# delegate_to: localhost
# run_once: true
# become: no

View File

@@ -0,0 +1,65 @@
_meta:
type: "config"
config_version: 2
config:
dynamic:
http:
anonymous_auth_enabled: false
authc:
internal_auth:
order: 0
description: "HTTP basic authentication using the internal user database"
http_enabled: true
transport_enabled: true
http_authenticator:
type: basic
challenge: false
authentication_backend:
type: internal
ldap_auth:
order: 1
description: "Authenticate and Authorize using LDAP"
http_enabled: true
transport_enabled: true
http_authenticator:
type: basic
challenge: false
authentication_backend:
type: ldap
config:
enable_ssl: false
enable_start_tls: false
enable_ssl_client_auth: false
verify_hostnames: true
hosts:
- "{{ ldap_host }}:{{ ldap_port }}"
bind_dn: "cn=admin,dc=ldap,dc=local"
password: "{{ vault_openldap_pass }}"
userbase: "ou=users,dc=ldap,dc=local"
usersearch: '(uid={0})'
username_attribute: "uid"
authz:
ldap_roles:
description: "Authorize using LDAP roles"
http_enabled: true
transport_enabled: true
authorization_backend:
type: ldap
config:
enable_ssl: false
enable_start_tls: false
enable_ssl_client_auth: false
verify_hostnames: true
hosts:
- "{{ ldap_host }}:{{ ldap_port }}"
bind_dn: "cn=admin,dc=ldap,dc=local"
password: "{{ vault_openldap_pass }}"
rolebase: "ou=groups,dc=ldap,dc=local"
rolesearch: '(uniqueMember={0})'
rolename: cn
resolve_nested_roles: false
skip_users:
- admin
- kibanaserver

View File

@@ -0,0 +1,94 @@
## JVM configuration
################################################################
## IMPORTANT: JVM heap size
################################################################
##
## You should always set the min and max JVM heap
## size to the same value. For example, to set
## the heap to 4 GB, set:
##
## -Xms4g
## -Xmx4g
##
## See https://opensearch.org/docs/opensearch/install/important-settings/
## for more information
##
################################################################
# Xms represents the initial size of total heap space
# Xmx represents the maximum size of total heap space
-Xms{{ xms_value }}g
-Xmx{{ xmx_value }}g
################################################################
## Expert settings
################################################################
##
## All settings below this section are considered
## expert settings. Don't tamper with them unless
## you understand what you are doing
##
################################################################
## GC configuration
8-10:-XX:+UseConcMarkSweepGC
8-10:-XX:CMSInitiatingOccupancyFraction=75
8-10:-XX:+UseCMSInitiatingOccupancyOnly
## G1GC Configuration
# NOTE: G1GC is the default GC for all JDKs 11 and newer
11-:-XX:+UseG1GC
# See https://github.com/elastic/elasticsearch/pull/46169 for the history
# behind these settings, but the tl;dr is that default values can lead
# to situations where heap usage grows enough to trigger a circuit breaker
# before GC kicks in.
11-:-XX:G1ReservePercent=25
11-:-XX:InitiatingHeapOccupancyPercent=30
## JVM temporary directory
-Djava.io.tmpdir=${OPENSEARCH_TMPDIR}
## heap dumps
# generate a heap dump when an allocation from the Java heap fails
# heap dumps are created in the working directory of the JVM
-XX:+HeapDumpOnOutOfMemoryError
# specify an alternative path for heap dumps; ensure the directory exists and
# has sufficient space
-XX:HeapDumpPath=/var/lib/opensearch
# specify an alternative path for JVM fatal error logs
-XX:ErrorFile=/var/log/opensearch/hs_err_pid%p.log
## JDK 8 GC logging
8:-XX:+PrintGCDetails
8:-XX:+PrintGCDateStamps
8:-XX:+PrintTenuringDistribution
8:-XX:+PrintGCApplicationStoppedTime
8:-Xloggc:/var/log/opensearch/gc.log
8:-XX:+UseGCLogFileRotation
8:-XX:NumberOfGCLogFiles=32
8:-XX:GCLogFileSize=64m
# JDK 9+ GC logging
9-:-Xlog:gc*,gc+age=trace,safepoint:file=/var/log/opensearch/gc.log:utctime,pid,tags:filecount=32,filesize=64m
# JDK 20+ Incubating Vector Module for SIMD optimizations;
# disabling may reduce performance on vector optimized lucene
20-:--add-modules=jdk.incubator.vector
# See please https://bugs.openjdk.org/browse/JDK-8341127 (openjdk/jdk#21283)
23:-XX:CompileCommand=dontinline,java/lang/invoke/MethodHandle.setAsTypeCache
23:-XX:CompileCommand=dontinline,java/lang/invoke/MethodHandle.asTypeUncached
21-:-javaagent:agent/opensearch-agent.jar
21-:--add-opens=java.base/java.nio=org.apache.arrow.memory.core,ALL-UNNAMED
## OpenSearch Performance Analyzer
-Dclk.tck=100
-Djdk.attach.allowAttachSelf=true
-Djava.security.policy=file:///etc/opensearch/opensearch-performance-analyzer/opensearch_security.policy
--add-opens=jdk.attach/sun.tools.attach=ALL-UNNAMED

View File

@@ -0,0 +1,155 @@
# ======================== OpenSearch Configuration =========================
#
# .dP"Y8 Yb dP 88 .dP"Y8 .dP"Y8 8b d8 db 88 dP 888888 88""Yb .dP"Y8 .dP"Y8 88 888888 8b d8
# `Ybo." Yb db dP 88 `Ybo." `Ybo." 88b d88 dPYb 88odP 88__ 88__dP `Ybo." `Ybo." 88 88__ 88b d88
# o.`Y8b YbdPYbdP 88 o.`Y8b o.`Y8b 88YbdP88 dP__Yb 88"Yb 88"" 88"Yb o.`Y8b o.`Y8b 88 88"" 88YbdP88
# 8bodP' YP YP 88 8bodP' 8bodP' 88 YY 88 dP""""Yb 88 Yb 888888 88 Yb 8bodP' 8bodP' 88 888888 88 YY 88
#
#
# ---------------------------------- Cluster -----------------------------------
#
# Use a descriptive name for your cluster:
cluster.name: {{ cluster_name }}
#
# ------------------------------------ Node ------------------------------------
#
# Use a descriptive name for the node:
node.name: {{ ansible_fqdn }}
#
# Add custom attributes to the node:
#
#node.attr.rack: r1
#Node roles
node.roles: [ {{ hostvars[inventory_hostname].roles | replace(',', ', ') }} ]
#
# ----------------------------------- Paths ------------------------------------
#
# Path to directory where to store the data (separate multiple locations by comma):
#
path.data: /var/lib/opensearch
# Path to log files:
path.logs: /var/log/opensearch
#
# ----------------------------------- Memory -----------------------------------
#
# Lock the memory on startup:
bootstrap.memory_lock: false
#
# Make sure that the heap size is set to about half the memory available
# on the system and that the owner of the process is allowed to use this
# limit.
#
# OpenSearch performs poorly when the system is swapping the memory.
#
# ---------------------------------- Network -----------------------------------
#
# Set the bind address to a specific IP (IPv4 or IPv6):
network.host: 0.0.0.0
#
# Set a custom port for HTTP:
http.port: 9200
#
# For more information, consult the network module documentation.
#
# --------------------------------- Discovery ----------------------------------
#
# Pass an initial list of hosts to perform discovery when this node is started:
# The default list of hosts is ["127.0.0.1", "[::1]"]
#
discovery.seed_hosts:
{% for host in groups['opensearch'] %}
- {{ hostvars[host].ansible_host }}
{% endfor %}
#
# Bootstrap the cluster using an initial set of cluster-manager-eligible nodes:
#
#cluster.initial_cluster_manager_nodes:
{% if 'cluster_manager' in hostvars[inventory_hostname].roles.split(',') %}
cluster.initial_master_nodes:
{% for host in groups['opensearch'] if 'cluster_manager' in hostvars[host].roles.split(',') %}
- {{ host }}
{% endfor %}
{% endif %}
#
# For more information, consult the discovery and cluster formation module documentation.
#
# ---------------------------------- Gateway -----------------------------------
#
# Block initial recovery after a full cluster restart until N nodes are started:
#
#gateway.recover_after_data_nodes: 3
#
# For more information, consult the gateway module documentation.
#
# ---------------------------------- Various -----------------------------------
#
# Require explicit names when deleting indices:
#
#action.destructive_requires_name: true
#
# ---------------------------------- Remote Store -----------------------------------
# Controls whether cluster imposes index creation only with remote store enabled
# cluster.remote_store.enabled: true
#
# Repository to use for segment upload while enforcing remote store for an index
# node.attr.remote_store.segment.repository: my-repo-1
#
# Repository to use for translog upload while enforcing remote store for an index
# node.attr.remote_store.translog.repository: my-repo-1
#
# ---------------------------------- Experimental Features -----------------------------------
# Gates the visibility of the experimental segment replication features until they are production ready.
#
#opensearch.experimental.feature.segment_replication_experimental.enabled: false
#
# Gates the functionality of a new parameter to the snapshot restore API
# that allows for creation of a new index type that searches a snapshot
# directly in a remote repository without restoring all index data to disk
# ahead of time.
#
#opensearch.experimental.feature.searchable_snapshot.enabled: false
#
#
# Gates the functionality of enabling extensions to work with OpenSearch.
# This feature enables applications to extend features of OpenSearch outside of
# the core.
#
#opensearch.experimental.feature.extensions.enabled: false
#
#
# Gates the optimization of datetime formatters caching along with change in default datetime formatter
# Once there is no observed impact on performance, this feature flag can be removed.
#
#opensearch.experimental.optimization.datetime_formatter_caching.enabled: false
# ---------------------------------- Security -----------------------------------
# Extract node name from FQDN
{% set node_name = inventory_hostname.split('.')[0] %}
# TLS/SSL for transport layer
plugins.security.ssl.transport.pemcert_filepath: /etc/opensearch/certs/{{ node_name }}.pem
plugins.security.ssl.transport.pemkey_filepath: /etc/opensearch/certs/{{ node_name }}-key.pem
plugins.security.ssl.transport.pemtrustedcas_filepath: /etc/opensearch/certs/root-ca.pem
# TLS/SSL for HTTP layer
plugins.security.ssl.http.enabled: true
plugins.security.ssl.http.pemcert_filepath: /etc/opensearch/certs/{{ node_name }}.pem
plugins.security.ssl.http.pemkey_filepath: /etc/opensearch/certs/{{ node_name }}-key.pem
plugins.security.ssl.http.pemtrustedcas_filepath: /etc/opensearch/certs/root-ca.pem
# Security plugin settings
plugins.security.allow_default_init_securityindex: true
plugins.security.authcz.admin_dn:
- 'CN=admin.opensearch.local,OU=Admins,O=MyOrg'
plugins.security.nodes_dn:
{% for host in groups['opensearch'] %}
- 'CN={{ host }},OU=Nodes,O=MyOrg'
{% endfor %}
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"]

View File

@@ -0,0 +1,153 @@
# ======================== OpenSearch Configuration =========================
#
# .dP"Y8 Yb dP 88 .dP"Y8 .dP"Y8 8b d8 db 88 dP 888888 88""Yb .dP"Y8 .dP"Y8 88 888888 8b d8
# `Ybo." Yb db dP 88 `Ybo." `Ybo." 88b d88 dPYb 88odP 88__ 88__dP `Ybo." `Ybo." 88 88__ 88b d88
# o.`Y8b YbdPYbdP 88 o.`Y8b o.`Y8b 88YbdP88 dP__Yb 88"Yb 88"" 88"Yb o.`Y8b o.`Y8b 88 88"" 88YbdP88
# 8bodP' YP YP 88 8bodP' 8bodP' 88 YY 88 dP""""Yb 88 Yb 888888 88 Yb 8bodP' 8bodP' 88 888888 88 YY 88
#
#
# ---------------------------------- Cluster -----------------------------------
#
# Use a descriptive name for your cluster:
cluster.name: {{ cluster_name }}
#
# ------------------------------------ Node ------------------------------------
#
# Use a descriptive name for the node:
node.name: {{ ansible_fqdn }}
#
# Add custom attributes to the node:
#
#node.attr.rack: r1
#Node roles
#node.roles: [ {{ hostvars[inventory_hostname].roles | replace(',', ', ') }} ]
#
# ----------------------------------- Paths ------------------------------------
#
# Path to directory where to store the data (separate multiple locations by comma):
#
path.data: /var/lib/opensearch
# Path to log files:
path.logs: /var/log/opensearch
#
# ----------------------------------- Memory -----------------------------------
#
# Lock the memory on startup:
bootstrap.memory_lock: true
#
# Make sure that the heap size is set to about half the memory available
# on the system and that the owner of the process is allowed to use this
# limit.
#
# OpenSearch performs poorly when the system is swapping the memory.
#
# ---------------------------------- Network -----------------------------------
#
# Set the bind address to a specific IP (IPv4 or IPv6):
network.host: 0.0.0.0
#
# Set a custom port for HTTP:
http.port: {{ firewall_os_port }}
#
# For more information, consult the network module documentation.
#
# --------------------------------- Discovery ----------------------------------
#
# Pass an initial list of hosts to perform discovery when this node is started:
# The default list of hosts is ["127.0.0.1", "[::1]"]
#
#discovery.seed_hosts:
# {% for host in groups['opensearch'] %}
# - {{ hostvars[host].ansible_host }}
# {% endfor %}
discovery.type: single-node
#
# Bootstrap the cluster using an initial set of cluster-manager-eligible nodes:
#
#cluster.initial_cluster_manager_nodes:
#
#cluster.initial_master_nodes:
#
# For more information, consult the discovery and cluster formation module documentation.
#
# ---------------------------------- Gateway -----------------------------------
#
# Block initial recovery after a full cluster restart until N nodes are started:
#
#gateway.recover_after_data_nodes: 3
#
# For more information, consult the gateway module documentation.
#
# ---------------------------------- Various -----------------------------------
#
# Require explicit names when deleting indices:
#
#action.destructive_requires_name: true
#
# ---------------------------------- Remote Store -----------------------------------
# Controls whether cluster imposes index creation only with remote store enabled
# cluster.remote_store.enabled: true
#
# Repository to use for segment upload while enforcing remote store for an index
# node.attr.remote_store.segment.repository: my-repo-1
#
# Repository to use for translog upload while enforcing remote store for an index
# node.attr.remote_store.translog.repository: my-repo-1
#
# ---------------------------------- Experimental Features -----------------------------------
# Gates the visibility of the experimental segment replication features until they are production ready.
#
#opensearch.experimental.feature.segment_replication_experimental.enabled: false
#
# Gates the functionality of a new parameter to the snapshot restore API
# that allows for creation of a new index type that searches a snapshot
# directly in a remote repository without restoring all index data to disk
# ahead of time.
#
#opensearch.experimental.feature.searchable_snapshot.enabled: false
#
#
# Gates the functionality of enabling extensions to work with OpenSearch.
# This feature enables applications to extend features of OpenSearch outside of
# the core.
#
#opensearch.experimental.feature.extensions.enabled: false
#
#
# Gates the optimization of datetime formatters caching along with change in default datetime formatter
# Once there is no observed impact on performance, this feature flag can be removed.
#
#opensearch.experimental.optimization.datetime_formatter_caching.enabled: false
# ---------------------------------- Security -----------------------------------
# Extract node name from FQDN
{% set node_name = inventory_hostname.split('.')[0] %}
# TLS/SSL for transport layer
plugins.security.ssl.transport.pemcert_filepath: /etc/opensearch/certs/{{ node_name }}.pem
plugins.security.ssl.transport.pemkey_filepath: /etc/opensearch/certs/{{ node_name }}-key.pem
plugins.security.ssl.transport.pemtrustedcas_filepath: /etc/opensearch/certs/root-ca.pem
# TLS/SSL for HTTP layer
plugins.security.ssl.http.enabled: true
plugins.security.ssl.http.pemcert_filepath: /etc/opensearch/certs/{{ node_name }}.pem
plugins.security.ssl.http.pemkey_filepath: /etc/opensearch/certs/{{ node_name }}-key.pem
plugins.security.ssl.http.pemtrustedcas_filepath: /etc/opensearch/certs/root-ca.pem
# Security plugin settings
plugins.security.allow_default_init_securityindex: true
plugins.security.authcz.admin_dn:
- 'CN=admin.opensearch.local,OU=Admins,O=MyOrg'
plugins.security.nodes_dn:
{% for host in groups['opensearch'] %}
- 'CN={{ host }}'
{% endfor %}
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"]

View File

@@ -0,0 +1,47 @@
# Vars file for OpenSearch
---
cluster_name: siem-swissmakers-opensearch
# Firewall ports
firewall_os_port: 9200
firewall_os_internal_port: 9300
firewall_os_pa_port: 9600
firewall_os_dashboards_port: 5601
# Java memory heap values (in GB) for OpenSearch
xms_value: 2
xmx_value: 2
#OpenSearch URL
os_url: https://artifacts.opensearch.org/releases/bundle/opensearch/3.x/opensearch-3.x.repo
# Certificate validity in days
opensearch_cert_validity: 730
opensearch_key_size: 4096
# Root CA details
opensearch_ca_common_name: "root.opensearch.local"
# Admin cert details
opensearch_admin_common_name: "admin.opensearch.local"
# Client cert details
opensearch_client_common_name: "client.opensearch.local"
opensearch_client_san:
- "DNS:client.opensearch.local"
# Destination path on the control node for generated files
opensearch_certs_temp_path: "~/opensearch_certs_temp"
# Destination path on the remote OpenSearch nodes
opensearch_certs_remote_path: "/etc/opensearch/certs"
ca_subject:
CN: "root.opensearch.local"
O: "MyCompany"
OU: "DevOps"
C: "CH"
#LDAP
ldap_host: OPENLDAP_IP
ldap_port: 389

2
vars/general-vars.yml Normal file
View File

@@ -0,0 +1,2 @@
# Cluster type whether its single-node or multi-node
cluster_type: multi-node

8
vars/vault.yml Normal file
View File

@@ -0,0 +1,8 @@
$ANSIBLE_VAULT;1.1;AES256
34303731386632383737663266643333303066616136303464396539333063343231316139353834
3061333435303261653134663430653837613934633631360a363131323238613131303566376562
33323034343261323165393634306531366366303635333833386234343831393631333863306634
6135353964336565660a323364373133306665663735353830373633356564656262323664326530
31316538316638373230313963663762306163313432373531316365613666346636646635363530
36663538363363623637626161386261323334353363336238353930623534643164343966643930
663030356331336435363832393938356135