Skip to content

Commit

Permalink
Merge branch 'drybjed-elasticsearch-per-cluster-passwords'
Browse files Browse the repository at this point in the history
  • Loading branch information
drybjed committed Jan 12, 2024
2 parents 6b9e156 + 4e4a48b commit 1ca551f
Show file tree
Hide file tree
Showing 7 changed files with 75 additions and 15 deletions.
20 changes: 20 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,26 @@ Changed

- The role now supports new Elasticsearch v8.x password management mechanism.

- The role can now manage passwords in separate Elasticsearch clusters defined
in one Ansible inventory.

.. warning:: Due to this change, Elasticsearch passwords stored in the
:file:`ansible/secret/` subdirectory will be read from a different
location. If passwords are not moved to the new location, role
will reset the Elasticsearch built-in users passwords
automatically. This might result in data loss.

:ref:`debops.kibana` role
'''''''''''''''''''''''''

- The path to the password file stored in :file:`ansible/secret/` subdirectory
is now configurable using a variable.

- The role uses new per-cluster Elasticsearch passwords by default. This is
done using a separate :envvar:`kibana__elasticsearch_cluster_name` variable,
which needs to be synchronized with the Elasticsearch configuration via
Ansible inventory (Kibana can be installed separately from Elasticsearch).


`debops v3.1.0`_ - 2023-11-29
-----------------------------
Expand Down
13 changes: 11 additions & 2 deletions ansible/roles/elasticsearch/defaults/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -251,13 +251,22 @@ elasticsearch__api_base_url: '{{ "https://" + ansible_fqdn + ":9200" }}'
# ``elastic`` user account has superuser privileges.
elasticsearch__api_username: 'elastic'

# ]]]
# .. envvar:: elasticsearch__secret_path [[[
#
# Path to the directory in the :ref:`debops.secret` storage where passwords of
# Elastcisearch built-in users will be stored.
elasticsearch__secret_path: '{{ "elasticsearch/credentials/"
+ elasticsearch__cluster_name + "/built-in" }}'

# ]]]
# .. envvar:: elasticsearch__api_password [[[
#
# The password used to access the Elasticsearch API, stored in the
# :file:`secret/` directory, managed by the :ref:`debops.secret` Ansible role.
elasticsearch__api_password: '{{ lookup("password", secret + "/elasticsearch/credentials/"
+ "built-in/" + elasticsearch__api_username + "/password") }}'
elasticsearch__api_password: '{{ lookup("password", secret + "/"
+ elasticsearch__secret_path + "/"
+ elasticsearch__api_username + "/password") }}'

# ]]]
# .. envvar:: elasticsearch__native_roles [[[
Expand Down
4 changes: 2 additions & 2 deletions ansible/roles/elasticsearch/tasks/authentication.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@

- name: Create required directories on Ansible Controller
ansible.builtin.file:
path: '{{ secret + "/elasticsearch/credentials/built-in/" + item.split()[0] }}'
path: '{{ secret + "/" + elasticsearch__secret_path + "/" + item.split()[0] }}'
state: 'directory'
mode: '0755'
loop: '{{ elasticsearch__register_builtin_users.stdout_lines }}'
Expand All @@ -43,7 +43,7 @@
- name: Save generated user passwords on Ansible Controller
ansible.builtin.copy:
content: '{{ item.split()[1] }}'
dest: '{{ secret + "/elasticsearch/credentials/built-in/" + item.split()[0] + "/password" }}'
dest: '{{ secret + "/" + elasticsearch__secret_path + "/" + item.split()[0] + "/password" }}'
mode: '0644'
loop: '{{ elasticsearch__register_builtin_users.stdout_lines }}'
become: False
Expand Down
4 changes: 2 additions & 2 deletions ansible/roles/elasticsearch/tasks/reset_password.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

- name: Create required directories on Ansible Controller
ansible.builtin.file:
path: '{{ secret + "/elasticsearch/credentials/built-in/" + item }}'
path: '{{ secret + "/" + elasticsearch__secret_path + "/" + item }}'
state: 'directory'
mode: '0755'
become: False
Expand All @@ -27,7 +27,7 @@
- name: Save generated password of account '{{ item }}'
ansible.builtin.copy:
content: '{{ elasticsearch__register_builtin_password.stdout }}'
dest: '{{ secret + "/elasticsearch/credentials/built-in/" + item + "/password" }}'
dest: '{{ secret + "/" + elasticsearch__secret_path + "/" + item + "/password" }}'
mode: '0644'
become: False
delegate_to: 'localhost'
Expand Down
23 changes: 21 additions & 2 deletions ansible/roles/kibana/defaults/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,14 @@ kibana__elasticsearch_url: 'http://localhost:9200'
# This variable is used on Kibana >= 7.0.0.
kibana__elasticsearch_hosts: [ 'http://localhost:9200' ]

# ]]]
# .. envvar:: kibana__elasticsearch_cluster_name [[[
#
# Name of the Elasticsearch cluster, used to lookup passwords in the
# :ref:`debops.secret` subdirectory. This variable should be synchronized with
# the :envvar:`elasticsearch__cluster_name` variable using Ansible inventory.
kibana__elasticsearch_cluster_name: '{{ kibana__domain | replace(".", "-") }}'

# ]]]
# .. envvar:: kibana__elasticsearch_username [[[
#
Expand All @@ -167,15 +175,26 @@ kibana__elasticsearch_username: '{{ ""
if (kibana__version is version("7.0.0", "<"))
else "kibana_system") }}'

# ]]]
# .. envvar:: kibana__elasticsearch_secret_path [[[
#
# Path to the Elasticsearch passwords stored in the :ref:`debops.secret`
# directory. It should be synchronized with :envvar:`elasticsearch__secret_path`
# variable for best results.
kibana__elasticsearch_secret_path: '{{ "elasticsearch/credentials/"
+ kibana__elasticsearch_cluster_name
+ "/built-in" }}'

# ]]]
# .. envvar:: kibana__elasticsearch_password [[[
#
# The password used by Kibana for internal maintenance on password-protected
# Elasticsearch clusters.
kibana__elasticsearch_password: '{{ ""
if (kibana__elasticsearch_hosts[0].startswith("http://"))
else (lookup("password", secret + "/elasticsearch/credentials/"
+ "built-in/" + kibana__elasticsearch_username
else (lookup("password", secret + "/"
+ kibana__elasticsearch_secret_path + "/"
+ kibana__elasticsearch_username
+ "/password")) }}'

# ]]]
Expand Down
6 changes: 3 additions & 3 deletions docs/ansible/roles/elasticsearch/getting-started.rst
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,9 @@ With secure cluster communication over TLS, the :ref:`debops.elasticsearch`
role can use the Elasticsearch API to manage user accounts and role definitions
in the cluster. A default set of `built-in users`__ will be created
automatically; passwords of these users will be stored in the
:file:`secret/elasticsearch/credentials/built-in/` directory on the Ansible
Controller (managed by the :ref:`debops.secret` role). After that, with the
base URL of the Elasticsearch API set in the
:file:`secret/elasticsearch/credentials/<cluster_name>/built-in/` directory on
the Ansible Controller (managed by the :ref:`debops.secret` role). After that,
with the base URL of the Elasticsearch API set in the
:envvar:`elasticsearch__api_base_url` variable, the role can manage
Elasticsearch roles and user accounts using the ``elastic`` superuser account.

Expand Down
20 changes: 16 additions & 4 deletions docs/ansible/roles/kibana/getting-started.rst
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,22 @@ the Elasticsearch cluster.
If the first host used for connections to the Elasticsearch cluster uses
a ``https://`` connection, Kibana will try to use the ``kibana_system``
Elasticsearch user account and password stored in the
:file:`secret/elasticsearch/credentials/` directory (managed by the
:ref:`debops.secret` role) to authorize itself with the cluster and set up its
own configuration. After that, you can use other users (notably ``elastic``
superuser account) to access the web interface.
:file:`secret/elasticsearch/credentials/<cluster_name>/built-in/kibana_system/password`
file (managed by the :ref:`debops.secret` role) to authorize itself with the
cluster and set up its own configuration. After that, you can use other users
(notably ``elastic`` superuser account) to access the web interface.

.. note:: Make sure that the Elasticsearch cluster name specified via the
:envvar:`elasticsearch__cluster_name` variable is synchronized with
the :envvar:`kibana__elasticsearch_cluster_name` variable in the
inventory. Otherwise, the :ref:`debops.kibana` role might not find
the correct password file and will not connect with the Elasticsearch
cluster.

The reason for doing it this way is that Kibana can be installed
separately from Elasticsearch (on separate hosts), and there's no way
for the :ref:`debops.kibana` role to find out the correct cluster
name on its own, if it's not the default.

You can install additional plugins that provide encrypted connections,
authentication, authorization and access control:
Expand Down

0 comments on commit 1ca551f

Please sign in to comment.