diff --git a/docs/role-elasticsearch.md b/docs/role-elasticsearch.md index 693dac09..bffc2b63 100644 --- a/docs/role-elasticsearch.md +++ b/docs/role-elasticsearch.md @@ -45,6 +45,16 @@ elasticsearch_extra_config: order: 0 enabled: true ``` +* *elasticsearch_keystore_extra*: You can set additional items for the elasticsearch keystore. Example: +```YAML +... +elasticsearch_keystore_extra: + the.setting.name.to.set: "some value", + the.other.setting.name.to.set: "some other value" + +``` + +* *elasticsearch_keystore_purge*: Purge items from keystore not set by this role. (Default: false) This variable activates a workaround to start on systems that have certain hardening measures active. See [Stackoverflow](https://stackoverflow.com/questions/47824643/unable-to-load-jna-native-support-library-elasticsearch-6-x/50371992#50371992) for details and logmessages to look for. **WARNING**: This will change your `/etc/sysconfig/elasticseach`or `/etc/default/elasticsearch` file and overwrite `ES_JAVA_OPTS`. See this [issue](https://github.com/netways/ansible-role-elasticsearch/issues/79) for details. diff --git a/roles/elasticsearch/defaults/main.yml b/roles/elasticsearch/defaults/main.yml index 29aaa0c6..e9d99ab8 100644 --- a/roles/elasticsearch/defaults/main.yml +++ b/roles/elasticsearch/defaults/main.yml @@ -22,6 +22,8 @@ elasticsearch_conf_dir: "/etc/elasticsearch/" elasticsearch_user: elasticsearch elasticsearch_group: elasticsearch elasticsearch_api_host: localhost +elasticsearch_keystore_extra: {} +elasticsearch_keystore_purge: false # JVM custom parameters elasticsearch_java_home: '' diff --git a/roles/elasticsearch/tasks/elasticsearch-keystore-addupdate.yml b/roles/elasticsearch/tasks/elasticsearch-keystore-addupdate.yml new file mode 100644 index 00000000..138e1ee5 --- /dev/null +++ b/roles/elasticsearch/tasks/elasticsearch-keystore-addupdate.yml @@ -0,0 +1,39 @@ +--- + +# Unless we clear the variable there is an edgecase +# where we skip the Get task, and procced to the +# set task with results from the previous run. +# If the previous variable matches the new one, +# we end up never setting the var. +- name: Clear temporary variable + ansible.builtin.set_fact: + elasticsearch_keystore_current_value: null + +- name: Get keystore value for {{ item.key }} + ansible.builtin.command: + argv: + - /usr/share/elasticsearch/bin/elasticsearch-keystore + - show + - "{{ item.key | quote }}" + changed_when: false + register: elasticsearch_keystore_current_value + failed_when: elasticsearch_keystore_current_value.rc != 0 + when: + - "item.key in elasticsearch_keystore_current_items.stdout_lines" + +- name: Set keystore value for {{ item.key }} + ansible.builtin.command: + argv: + - /usr/share/elasticsearch/bin/elasticsearch-keystore + - add + - -f + - -x + - "{{ item.key | quote }}" + stdin: "{{ item.value }}" + changed_when: true + register: result + failed_when: result.rc != 0 + when: + - elasticsearch_keystore_current_value.stdout is undefined or item.value != elasticsearch_keystore_current_value.stdout + notify: + - Restart Elasticsearch diff --git a/roles/elasticsearch/tasks/elasticsearch-keystore.yml b/roles/elasticsearch/tasks/elasticsearch-keystore.yml index 31481fc8..7e501ac5 100644 --- a/roles/elasticsearch/tasks/elasticsearch-keystore.yml +++ b/roles/elasticsearch/tasks/elasticsearch-keystore.yml @@ -1,184 +1,45 @@ --- -- name: Create keystore +- name: "Elasticsearch keystore: Create keystore" ansible.builtin.command: /usr/share/elasticsearch/bin/elasticsearch-keystore create args: creates: /etc/elasticsearch/elasticsearch.keystore -- name: Check for bootstrap password +- name: "Elasticsearch keystore: Get current variables" ansible.builtin.command: /usr/share/elasticsearch/bin/elasticsearch-keystore list changed_when: false - register: elasticsearch_keystore - -- name: Set bootstrap password # noqa: risky-shell-pipe - ansible.builtin.shell: > - if test -n "$(ps -p $$ | grep bash)"; then set -o pipefail; fi; - echo "{{ elasticsearch_bootstrap_pw }}" | - /usr/share/elasticsearch/bin/elasticsearch-keystore - add -x 'bootstrap.password' - when: "'bootstrap.password' not in elasticsearch_keystore.stdout_lines" - changed_when: false - no_log: true - notify: - - Restart Elasticsearch - ignore_errors: "{{ ansible_check_mode }}" - -- name: Get xpack.security.http.ssl.keystore.secure_password # noqa: risky-shell-pipe - ansible.builtin.shell: > - if test -n "$(ps -p $$ | grep bash)"; then set -o pipefail; fi; - /usr/share/elasticsearch/bin/elasticsearch-keystore - show 'xpack.security.http.ssl.keystore.secure_password' - when: - - "'xpack.security.http.ssl.keystore.secure_password' in elasticsearch_keystore.stdout_lines" - - elasticsearch_http_security - register: elasticsearch_http_ssl_keystore_secure_password - ignore_errors: "{{ ansible_check_mode }}" - no_log: true - changed_when: false - -- name: Set xpack.security.http.ssl.keystore.secure_password # noqa: risky-shell-pipe - ansible.builtin.shell: > - if test -n "$(ps -p $$ | grep bash)"; then set -o pipefail; fi; - echo "{{ elasticsearch_tls_key_passphrase }}" | - /usr/share/elasticsearch/bin/elasticsearch-keystore - add -f -x 'xpack.security.http.ssl.keystore.secure_password' - changed_when: false - no_log: true - when: - - elasticsearch_http_ssl_keystore_secure_password.stdout is undefined or elasticsearch_tls_key_passphrase != elasticsearch_http_ssl_keystore_secure_password.stdout - - elasticsearch_http_security - notify: - - Restart Elasticsearch - -- name: Remove xpack.security.http.ssl.keystore.secure_password # noqa: risky-shell-pipe - ansible.builtin.shell: > - if test -n "$(ps -p $$ | grep bash)"; then set -o pipefail; fi; - /usr/share/elasticsearch/bin/elasticsearch-keystore - remove 'xpack.security.http.ssl.keystore.secure_password' - changed_when: false - no_log: true - when: - - "'xpack.security.http.ssl.keystore.secure_password' in elasticsearch_keystore.stdout_lines" - - not elasticsearch_http_security - notify: - - Restart Elasticsearch - -- name: Get xpack.security.http.ssl.truststore.secure_password # noqa: risky-shell-pipe - ansible.builtin.shell: > - if test -n "$(ps -p $$ | grep bash)"; then set -o pipefail; fi; - /usr/share/elasticsearch/bin/elasticsearch-keystore - show 'xpack.security.http.ssl.truststore.secure_password' - when: - - "'xpack.security.http.ssl.truststore.secure_password' in elasticsearch_keystore.stdout_lines" - - elasticsearch_http_security - register: elasticsearch_http_ssl_truststore_secure_password - ignore_errors: "{{ ansible_check_mode }}" - no_log: true - changed_when: false - -- name: Set xpack.security.http.ssl.truststore.secure_password # noqa: risky-shell-pipe - ansible.builtin.shell: > - if test -n "$(ps -p $$ | grep bash)"; then set -o pipefail; fi; - echo "{{ elasticsearch_tls_key_passphrase }}" | - /usr/share/elasticsearch/bin/elasticsearch-keystore - add -f -x 'xpack.security.http.ssl.truststore.secure_password' - changed_when: false - no_log: true - when: - - elasticsearch_http_ssl_truststore_secure_password.stdout is undefined or elasticsearch_tls_key_passphrase != elasticsearch_http_ssl_truststore_secure_password.stdout - - elasticsearch_http_security - notify: - - Restart Elasticsearch - -- name: Remove xpack.security.http.ssl.truststore.secure_password # noqa: risky-shell-pipe - ansible.builtin.shell: > - if test -n "$(ps -p $$ | grep bash)"; then set -o pipefail; fi; - /usr/share/elasticsearch/bin/elasticsearch-keystore - remove 'xpack.security.http.ssl.truststore.secure_password' - changed_when: false - no_log: true - when: - - "'xpack.security.http.ssl.truststore.secure_password' in elasticsearch_keystore.stdout_lines" - - not elasticsearch_http_security - notify: - - Restart Elasticsearch - -- name: Get xpack.security.transport.ssl.keystore.secure_password # noqa: risky-shell-pipe - ansible.builtin.shell: > - if test -n "$(ps -p $$ | grep bash)"; then set -o pipefail; fi; - /usr/share/elasticsearch/bin/elasticsearch-keystore - show 'xpack.security.transport.ssl.keystore.secure_password' - when: - - "'xpack.security.transport.ssl.keystore.secure_password' in elasticsearch_keystore.stdout_lines" - - elasticsearch_security - register: elasticsearch_transport_ssl_keystore_secure_password - ignore_errors: "{{ ansible_check_mode }}" - no_log: true - changed_when: false - -- name: Set xpack.security.transport.ssl.keystore.secure_password # noqa: risky-shell-pipe - ansible.builtin.shell: > - if test -n "$(ps -p $$ | grep bash)"; then set -o pipefail; fi; - echo "{{ elasticsearch_tls_key_passphrase }}" | - /usr/share/elasticsearch/bin/elasticsearch-keystore - add -f -x 'xpack.security.transport.ssl.keystore.secure_password' - changed_when: false - no_log: true - when: - - elasticsearch_transport_ssl_keystore_secure_password.stdout is undefined or elasticsearch_tls_key_passphrase != elasticsearch_transport_ssl_keystore_secure_password.stdout - - elasticsearch_security - notify: - - Restart Elasticsearch - -- name: Remove xpack.security.transport.ssl.keystore.secure_password # noqa: risky-shell-pipe - ansible.builtin.shell: > - if test -n "$(ps -p $$ | grep bash)"; then set -o pipefail; fi; - /usr/share/elasticsearch/bin/elasticsearch-keystore - remove 'xpack.security.transport.ssl.keystore.secure_password' - changed_when: false - no_log: true - when: - - "'xpack.security.transport.ssl.keystore.secure_password' in elasticsearch_keystore.stdout_lines" - - not elasticsearch_security - notify: - - Restart Elasticsearch - -- name: Get xpack.security.transport.ssl.truststore.secure_password # noqa: risky-shell-pipe - ansible.builtin.shell: > - if test -n "$(ps -p $$ | grep bash)"; then set -o pipefail; fi; - /usr/share/elasticsearch/bin/elasticsearch-keystore - show 'xpack.security.transport.ssl.truststore.secure_password' - when: - - "'xpack.security.transport.ssl.truststore.secure_password' in elasticsearch_keystore.stdout_lines" - - elasticsearch_security - register: elasticsearch_transport_ssl_truststore_secure_password - ignore_errors: "{{ ansible_check_mode }}" - no_log: true - changed_when: false - -- name: Set xpack.security.transport.ssl.truststore.secure_password # noqa: risky-shell-pipe - ansible.builtin.shell: > - if test -n "$(ps -p $$ | grep bash)"; then set -o pipefail; fi; - echo "{{ elasticsearch_tls_key_passphrase }}" | - /usr/share/elasticsearch/bin/elasticsearch-keystore - add -f -x 'xpack.security.transport.ssl.truststore.secure_password' - changed_when: false - no_log: true - when: - - elasticsearch_transport_ssl_truststore_secure_password.stdout is undefined or elasticsearch_tls_key_passphrase != elasticsearch_transport_ssl_truststore_secure_password.stdout - - elasticsearch_security - notify: - - Restart Elasticsearch - -- name: Remove xpack.security.transport.ssl.truststore.secure_password # noqa: risky-shell-pipe - ansible.builtin.shell: > - if test -n "$(ps -p $$ | grep bash)"; then set -o pipefail; fi; - /usr/share/elasticsearch/bin/elasticsearch-keystore - remove 'xpack.security.transport.ssl.truststore.secure_password' - changed_when: false - no_log: true - when: - - "'xpack.security.transport.ssl.truststore.secure_password' in elasticsearch_keystore.stdout_lines" - - not elasticsearch_security - notify: - - Restart Elasticsearch + register: elasticsearch_keystore_current_items + +- name: "Elasticsearch keystore: Include xpack.security.http.ssl variables" + ansible.builtin.set_fact: + # Combine data into the dictionary + elasticsearch_keystore_vars: "{{ elasticsearch_keystore_vars | combine({'xpack.security.http.ssl.keystore.secure_password': elasticsearch_tls_key_passphrase, 'xpack.security.http.ssl.truststore.secure_password': elasticsearch_tls_key_passphrase}) }}" + no_log: "{{ elasticstack_no_log }}" + when: elasticsearch_http_security | default(false) | bool + +- name: "Elasticsearch keystore: Include xpack.security.transport.ssl variables" + ansible.builtin.set_fact: + # Combine data into the dictionary + elasticsearch_keystore_vars: "{{ elasticsearch_keystore_vars | combine({'xpack.security.transport.ssl.keystore.secure_password': elasticsearch_tls_key_passphrase, 'xpack.security.transport.ssl.truststore.secure_password': elasticsearch_tls_key_passphrase}) }}" + no_log: "{{ elasticstack_no_log }}" + when: elasticsearch_security | default(false) | bool + +- name: Add/update elements to elasticsearch keystore + ansible.builtin.include_tasks: + elasticsearch-keystore-addupdate.yml + no_log: "{{ elasticstack_no_log }}" + loop: "{{ (elasticsearch_keystore_extra | dict2items) + (elasticsearch_keystore_vars | dict2items) }}" + +- name: Purge keys from elasticsearch keystore + ansible.builtin.command: + argv: + - /usr/share/elasticsearch/bin/elasticsearch-keystore + - remove + - "{{ item | quote }}" + changed_when: true + loop: "{{ elasticsearch_keystore_current_items.stdout_lines }}" + when: + - elasticsearch_keystore_purge + - item not in elasticsearch_keystore_vars + - item not in elasticsearch_keystore_extra + - item not in elasticsearch_keystore_builtin diff --git a/roles/elasticsearch/vars/main.yml b/roles/elasticsearch/vars/main.yml index 140916a9..cbc0bb76 100644 --- a/roles/elasticsearch/vars/main.yml +++ b/roles/elasticsearch/vars/main.yml @@ -1,2 +1,15 @@ --- # vars file for elasticsearch + +# List all keystore items added by elastic +# to avoid deleting them if role is set to +# pruge keystore +elasticsearch_keystore_builtin: + - keystore.seed + - autoconfiguration.password_hash + +# We always set bootstrap.password +# Other variables are added to the dict in elasticsearch-keystore.yml +elasticsearch_keystore_vars: { + bootstrap.password: "{{ elasticsearch_bootstrap_pw }}" +} \ No newline at end of file