Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add code for automatic updates #250

Merged
merged 73 commits into from
Apr 18, 2024
Merged
Changes from 1 commit
Commits
Show all changes
73 commits
Select commit Hold shift + click to select a range
4de663f
Add code for automatic updates
xtruthx Aug 30, 2023
b9e204d
Start changing playbook into taskfile
xtruthx Jan 16, 2024
eefcef9
Add note about modifications by NPS
widhalmt Jan 16, 2024
9570a9f
Move global vars to new role
widhalmt Jan 16, 2024
c79beb4
Merge branch 'main' into feature/update-216
widhalmt Jan 16, 2024
6a11bf5
Fix lint in defaults
widhalmt Jan 16, 2024
df106c5
lint
widhalmt Jan 16, 2024
6f97e74
Clean up lint
xtruthx Jan 16, 2024
1b47673
Move OS specific vars to global role
widhalmt Jan 16, 2024
0ae36bb
Fix lint
widhalmt Jan 16, 2024
839e603
Set default for elasticstack_ca_will_expire_soon
widhalmt Jan 16, 2024
91d588b
Move elasticsearch_ca naming to global role
widhalmt Jan 16, 2024
e7a4f35
Set name of Elasticsearch CA
widhalmt Jan 16, 2024
4f07aeb
Fix defaults for global role
widhalmt Jan 16, 2024
19367c9
Skip global role if it ran already
widhalmt Jan 16, 2024
61ff0a1
Stupid logical mistake
widhalmt Jan 17, 2024
931d6d1
Set version of ES on elasticstack_ca as target for all components
widhalmt Jan 17, 2024
c162010
Rename file for naming scheme
widhalmt Jan 17, 2024
2b365d0
Lint
widhalmt Jan 17, 2024
ec218de
Specify subvariable for checking
widhalmt Jan 17, 2024
7bebba7
Remove reboot part of upgrade playbook
widhalmt Jan 17, 2024
e49d50b
Add note about version detection
widhalmt Jan 17, 2024
ff13c9e
Remove obsolete vars directory from repos
widhalmt Jan 17, 2024
1cdb583
Use module instead of shell
widhalmt Jan 17, 2024
b94c2cc
Remove overly complicated version check
widhalmt Jan 17, 2024
00a4fcf
Call upgrade taskfile when new version > current version
widhalmt Jan 17, 2024
0017987
Remove upgrades for other packages
widhalmt Jan 18, 2024
464b663
Upgrade shutdown nodes right away
widhalmt Jan 18, 2024
242276d
Only start Elasticsearch if it was running before
widhalmt Jan 18, 2024
1f463da
Remove redundant become
widhalmt Jan 18, 2024
b248e08
Restrict execution of upgrade playbook to one at a time
widhalmt Jan 18, 2024
b215d31
Fetch elastic password for upgrades
widhalmt Jan 18, 2024
dad70f6
Merge branch 'main' into feature/update-216
widhalmt Jan 19, 2024
5244078
Replace package installation with more general one
widhalmt Jan 19, 2024
c659dee
Fix some errors in variable names
widhalmt Jan 19, 2024
d1d0e2d
Damn typo
widhalmt Jan 19, 2024
1cb7571
Directly upgrade nodes that are down
widhalmt Jan 19, 2024
2865d5d
Apply workaround for seria in include tasks
widhalmt Feb 12, 2024
7c4b38d
Workaround for "back in cluster" check
widhalmt Feb 12, 2024
49b34d4
Fix typo
widhalmt Feb 13, 2024
55e5de4
Introduce (and set) elasticsearch_nodename variable
widhalmt Feb 13, 2024
5d92f58
Add rolling restart for handler
widhalmt Feb 13, 2024
5eef485
Merge branch 'main' into feature/update-216
widhalmt Feb 13, 2024
07bc9e4
Enable shard allocation before checks
widhalmt Feb 13, 2024
9ae5b16
Re-Add repo key
widhalmt Feb 13, 2024
96eb6fc
Restart all applications after upgrade
widhalmt Feb 13, 2024
a257c56
Build Logstash version different for deb
widhalmt Feb 13, 2024
b7edd49
Typo
widhalmt Feb 13, 2024
0ce2cda
Typo
widhalmt Feb 13, 2024
1d1537d
NGAH
widhalmt Feb 13, 2024
4b08e54
Revert prototype for rolling restart
widhalmt Feb 14, 2024
4f2e7a0
Test old version picking system
widhalmt Feb 14, 2024
d1d5caf
Fix package name creation on .deb
widhalmt Feb 15, 2024
76f271c
Typo
widhalmt Feb 15, 2024
c098870
Remove directive we don't need anymore
widhalmt Feb 15, 2024
506aa6d
Handle single instances of Elasticsearch during update
widhalmt Feb 15, 2024
2a659ff
Lint
widhalmt Feb 15, 2024
ff70c58
Enable repo only with rpm and full_stack
widhalmt Feb 15, 2024
dde6c86
Streamline installation of common packages and dependencies
widhalmt Feb 15, 2024
3f9f6f4
Add a few explanatory comments
widhalmt Feb 15, 2024
35e31c1
Update Readme
widhalmt Feb 15, 2024
e021ccb
Merge branch 'main' into feature/update-216
widhalmt Feb 16, 2024
83243b3
Update sponsoring note
widhalmt Feb 17, 2024
a728f62
Make single update a block
widhalmt Mar 8, 2024
e28c823
Match elasticsearch_api_host with rest of code
widhalmt Mar 8, 2024
3d0787c
Add faster upgrades for non-prod clusters
widhalmt Mar 8, 2024
7bc3a0b
Lint
widhalmt Mar 8, 2024
df5ba99
Merge branch 'feature/update-216' of github.com:NETWAYS/ansible-colle…
widhalmt Mar 22, 2024
31089d9
Make docs about nodename more clear
widhalmt Mar 22, 2024
53a65b3
Be more clear about Installation task
widhalmt Mar 22, 2024
d2b7458
A bit more clarification
widhalmt Mar 22, 2024
b7d7186
Merge branch 'main' into feature/update-216
widhalmt Apr 17, 2024
a3d021e
Fix remaining legacy group names
widhalmt Apr 17, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Merge branch 'main' into feature/update-216
widhalmt committed Feb 13, 2024

Verified

This commit was signed with the committer’s verified signature. The key has expired.
widhalmt Thomas Widhalm
commit 5eef485bc3ae69dc5e9feac998c7a6ec7fbf1ec4
63 changes: 63 additions & 0 deletions .github/workflows/test_elasticsearch_modules.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
---
name: Test Elasticsearch modules
on:
workflow_dispatch:
inputs:
logLevel:
description: 'Log level'
required: true
default: 'warning'
type: choice
options:
- info
- warning
- debug
pull_request:
paths:
- '.github/workflows/test_elasticsearch_modules.yml'
- 'molecule/elasticsearch_test_modules/*'

jobs:
molecule_elasticsearch_modules:
runs-on: ubuntu-latest

env:
COLLECTION_NAMESPACE: netways
COLLECTION_NAME: elasticstack

strategy:
fail-fast: false
matrix:
distro: [ubuntu2204]
scenario:
- elasticsearch_test_modules
release:
- 8

steps:
- name: Check out code
uses: actions/checkout@v4

- name: Set up Python 3.8
uses: actions/setup-python@v5
with:
python-version: 3.8

- name: Install dependencies
run: |
python3 -m pip install --upgrade pip
python3 -m pip install -r requirements-test.txt
- name: Install collection
run: |
mkdir -p ~/.ansible/collections/ansible_collections/$COLLECTION_NAMESPACE
cp -a ../ansible-collection-$COLLECTION_NAME ~/.ansible/collections/ansible_collections/$COLLECTION_NAMESPACE/$COLLECTION_NAME
- name: Test with molecule
run: |
molecule test -s ${{ matrix.scenario }}
env:
MOLECULE_DISTRO: ${{ matrix.distro }}
PY_COLORS: '1'
ANSIBLE_FORCE_COLOR: '1'
ELASTIC_RELEASE: ${{ matrix.release }}
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
.cache
*.swp
__pycache__*
__pycache__*
.vscode
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -8,14 +8,19 @@ Every role is documented with all variables, please refer to the documentation f

**Please note**: If you are already using this collection before version `1.0.0`, please note that we had to rename a significant amount of variables due to naming schema changes made by Ansible. Please review the variables you have set in your playbooks and variable files.

## Roles Documentation
## Roles documentation

* [Beats](docs/role-beats.md)
* [Elasticsearch](docs/role-elasticsearch.md)
* [Kibana](docs/role-kibana.md)
* [Logstash](docs/role-logstash.md)
* [Repos](docs/role-repos.md)

## Modules documentation

* [elasticsearch_role](docs/module-elasticsearch_role.md)
* [elasticsearch_user](docs/module-elasticsearch_user.md)

## Installation

You can easily install the collection with the `ansible-galaxy` command.
68 changes: 68 additions & 0 deletions docs/module-elasticsearch_role.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
Ansible module: elasticsearch_role
===

This module creates, updates and deletes roles from your Elasticsearch.

Requirements
---

As this module uses the Elasticsearch API you will need to install the `elasticsearch` Python3 library.
```
pip3 install elasticsearch
```

Module arguments
---

* *name*: Name of your role (**Required**)
* *cluster*: List of clusters
* *indicies*: List of indicies
* *names*: List of names (**Required**)
* *privileges*: List of privileges (**Required**)
* *state*: State of the role (Default: `present`)
* *host*: API endpoint (**Required**)
* *auth_user*: User to authenticate on the Elasticsearch API (**Required**)
* *auth_pass*: Password for the given user (**Required**)
* *verify_certs*: Verify certificates (Default: `true`)
* *ca_certs*: Verify HTTPS connection by using ca certificate. Path to ca needs to be given

Example usage
---
```
- name: Create elasticsearch role 'new-role1'
netways.elasticstack.elasticsearch_role:
name: new-role1
cluster:
- manage_own_api_key
- delegate_pki
indicies:
- names:
- default01
privileges:
- read
- write
state: present
host: https://localhost:9200
auth_user: elastic
auth_pass: changeMe123!
verify_certs: true
ca_certs: /etc/elasticsearch/certs/http_ca.crt
- name: Create elasticsearch role 'new-role2'
netways.elasticstack.elasticsearch_role:
name: new-role2
cluster:
- manage_own_api_key
- delegate_pki
indicies:
- names:
- default01
privileges:
- read
- write
state: present
host: https://localhost:9200
auth_user: elastic
auth_pass: changeMe123!
verify_certs: false
```
65 changes: 65 additions & 0 deletions docs/module-elasticsearch_user.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
Ansible module: elasticsearch_user
===

This module creates, updates and deletes users from your Elasticsearch.

Requirements
---

As this module uses the Elasticsearch API you will need to install the `elasticsearch` Python3 library.
```
pip3 install elasticsearch
```

Module arguments
---

* *name*: Name of your user (**Required**)
* *fullname*: Fullname of your user
* *password*: Password for your user (**Required**)
* *email*: Email for your user
* *roles*: List of roles (**Required**)
* *enabled*: Define wheter this user should be enabled (Default: `true`)
* *state*: State of the role. `absent` to delete the user (Default: `present`)
* *host*: API endpoint (**Required**)
* *auth_user*: User to authenticate on the Elasticsearch API (**Required**)
* *auth_pass*: Password for the given user (**Required**)
* *verify_certs*: Verify certificates (Default: `true`)
* *ca_certs*: Verify HTTPS connection by using ca certificate. Path to ca needs to be given

Example usage
---
```
- name: Create elasticsearch user 'new-user1'
netways.elasticstack.elasticsearch_user:
name: new-user1
fullname: New User 1
password: changeMe321!
email: [email protected]
roles:
- new-role
- logstash-writer
enabled: true
state: present
host: https://localhost:9200
auth_user: elastic
auth_pass: changeMe123!
verify_certs: true
ca_certs: /etc/elasticsearch/certs/http_ca.crt
- name: Create elasticsearch user 'new-user2'
netways.elasticstack.elasticsearch_user:
name: new-user2
fullname: New User 2
password: changeMe321!
email: [email protected]
roles:
- new-role
- logstash-writer
enabled: true
state: present
host: https://localhost:9200
auth_user: elastic
auth_pass: changeMe123!
verify_certs: false
```
6 changes: 5 additions & 1 deletion docs/role-elasticsearch.md
Original file line number Diff line number Diff line change
@@ -32,7 +32,7 @@ Role Variables
* *elasticsearch_pamlimits*: Set pam_limits neccessary for Elasticsearch. (Default: `true`)
* *elasticsearch_check_calculation*: End play in checks (Default: `false`)
* *elasticsearch_network_host*: You can configure multipe network addresses where the networking is bind to. You can assign IP addresses or interfaces by their names. You can also use elasticsearch internal variabels as it set as default. Example: `"_ens190_,_local_"` (Default: `"_local_,"_site_"`) (Optional; if not defined `default` is used)

* *elasticsearch_api_host*: Hostname or IP elasticsearch is listening on. Only used for connection checks by ansible role. (Default: `localhost`)
* *elasticsearch_extra_config*: You can set additional configuration in YAML-notation as you would write in the `elasaticsearch.yml`. Example:

```YAML
@@ -49,6 +49,10 @@ elasticsearch_extra_config:
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.

* *elasticsearch_jna_workaround*: Activate JNA workaround. (default: `false`)
* *elasticsearch_ssl_verification_mode*: Defines how to verify the certificates presented by another party in the TLS connection
* *elasticsearch_transport_port*: The port to bind for communication between nodes
* *elasticsearch_seed_hosts*: Set elasticsearch seed hosts
* *elasticsearch_security_enrollment*: Controls enrollment (of nodes and Kibana) to a local node that’s been autoconfigured for security.

These variables are identical over all our elastic related roles, hence the different naming schemes.

65 changes: 65 additions & 0 deletions molecule/elasticsearch_test_modules/converge.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
---
# The workaround for arbitrarily named role directory is important because the git repo has one name and the role within it another
# Found at: https://github.com/ansible-community/molecule/issues/1567#issuecomment-436876722
- name: Converge
collections:
- netways.elasticstack
hosts: all
vars:
elasticstack_full_stack: false
elasticsearch_jna_workaround: true
elasticsearch_disable_systemcallfilterchecks: true
#elasticstack_release: "{{ lookup('env', 'ELASTIC_RELEASE') | int}}"
elasticstack_release: 8
elasticsearch_heap: "1"
elasticstack_no_log: false
tasks:
- name: Include Elastics repos role
ansible.builtin.include_role:
name: repos
- name: Include Elasticsearch
ansible.builtin.include_role:
name: elasticsearch

- name: Fetch Elastic password # noqa: risky-shell-pipe
ansible.builtin.shell: >
if test -n "$(ps -p $$ | grep bash)"; then set -o pipefail; fi;
grep "PASSWORD elastic" /usr/share/elasticsearch/initial_passwords |
awk {' print $4 '}
register: elasticstack_password
changed_when: false

- name: Create elasticsearch role 'new-role'
netways.elasticstack.elasticsearch_role:
name: new-role1
cluster:
- manage_own_api_key
- delegate_pki
indicies:
- names:
- foobar321
privileges:
- read
- write
state: present
host: https://localhost:9200
auth_user: elastic
auth_pass: "{{ elasticstack_password.stdout }}"
verify_certs: false

- name: Create elasticsearch user 'new-user'
netways.elasticstack.elasticsearch_user:
name: new-user1
fullname: New User
password: changeMe123!
email: [email protected]
roles:
- new-role1
- logstash-writer
enabled: true
state: present
host: https://localhost:9200
auth_user: elastic
auth_pass: "{{ elasticstack_password.stdout }}"
verify_certs: false
ca_certs: /etc/elasticsearch/certs/http_ca.crt
24 changes: 24 additions & 0 deletions molecule/elasticsearch_test_modules/molecule.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
dependency:
name: galaxy
options:
requirements-file: requirements.yml
driver:
name: docker
platforms:
- name: elasticsearch_default
groups:
- elasticsearch
image: "geerlingguy/docker-${MOLECULE_DISTRO:-debian11}-ansible:latest"
command: ${MOLECULE_DOCKER_COMMAND:-""}
volumes:
- /sys/fs/cgroup:/sys/fs/cgroup:rw
cgroupns_mode: host
privileged: true
pre_build_image: true
provisioner:
name: ansible
env:
ANSIBLE_VERBOSITY: 3
verifier:
name: ansible
22 changes: 22 additions & 0 deletions molecule/elasticsearch_test_modules/prepare.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
- name: Prepare
hosts: all
tasks:
- name: Install packages for Debian
ansible.builtin.apt:
name:
- gpg
- gpg-agent
- procps
- curl
- iproute2
- git
- openssl
- python3
update_cache: yes

- name: Install python module dependencies
ansible.builtin.pip:
name: "{{ item }}"
loop:
- elasticsearch
3 changes: 3 additions & 0 deletions molecule/elasticsearch_test_modules/requirements.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
---
collections:
- community.general
15 changes: 15 additions & 0 deletions plugins/module_utils/api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# !/usr/bin/python3

# Copyright (c) 2024, Tobias Bauriedel <[email protected]>
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or
# https://www.gnu.org/licenses/gpl-3.0.txt)

from elasticsearch import Elasticsearch
import ssl

class Api():
def new_client_basic_auth(host, auth_user, auth_pass, ca_certs, verify_certs) -> Elasticsearch:
ctx = ssl.create_default_context(cafile=ca_certs)
ctx.check_hostname = False
ctx.verify_mode = False
return Elasticsearch(hosts=[host], basic_auth=(auth_user, auth_pass), ssl_context=ctx, verify_certs=verify_certs)
86 changes: 86 additions & 0 deletions plugins/module_utils/elasticsearch_role.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
#!/usr/bin/python

# Copyright (c) 2024, Tobias Bauriedel <tobias.bauriedel@netways.de>
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or
# https://www.gnu.org/licenses/gpl-3.0.txt)

from ansible_collections.netways.elasticstack.plugins.module_utils.api import (
Api
)

class Role():
def __init__(self, result, role_name, cluster, indicies, state, host, auth_user, auth_pass, verify_certs, ca_certs):
self.role_name = role_name
self.cluster = cluster
self.indicies = indicies
self.state = state
self.result = result

self.client = Api.new_client_basic_auth(host=host, auth_user=auth_user, auth_pass=auth_pass, verify_certs=verify_certs, ca_certs=ca_certs)

self.handle()


def return_result(self) -> dict:
return self.result


def handle(self):

if self.state == 'absent':
self.handle_absent()
elif self.state == 'present':
self.handle_present()

return


def handle_absent(self):
if self.role_name not in self.get_all().raw:
return

res = self.delete()
if res['found'] == True:
self.result['changed'] = True
self.result['msg'] = self.role_name + " has been deleted"

return


def handle_present(self):
if self.role_name in self.get_all().raw:
pre_role = self.get()
else:
pre_role = None

res = self.put()

if res.raw['role']['created'] == True:
self.result['changed'] = True
self.result['msg'] = self.role_name + " has been created"
return

if pre_role == None:
return

if pre_role.raw != self.get().raw:
self.result['changed'] = True
self.result['msg'] = self.role_name + " has been updated"

return


def get_all(self):
return self.client.security.get_role()


def get(self):
return self.client.security.get_role(name=self.role_name)


def put(self):
return self.client.security.put_role(name=self.role_name, cluster=self.cluster, indices=self.indicies)


def delete(self):
return self.client.security.delete_role(name=self.role_name)
88 changes: 88 additions & 0 deletions plugins/module_utils/elasticsearch_user.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
#!/usr/bin/python

# Copyright (c) 2024, Tobias Bauriedel <tobias.bauriedel@netways.de>
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or
# https://www.gnu.org/licenses/gpl-3.0.txt)

from ansible_collections.netways.elasticstack.plugins.module_utils.api import (
Api
)

class User():
def __init__(self, result, user_name, full_name, password, email, roles, enabled, state, host, auth_user, auth_pass, verify_certs, ca_certs):
self.user_name = user_name
self.full_name = full_name
self.password = password
self.email = email
self.roles = roles
self.enabled = enabled
self.state = state
self.result = result

self.client = Api.new_client_basic_auth(host=host, auth_user=auth_user, auth_pass=auth_pass, ca_certs=ca_certs, verify_certs=verify_certs)

self.handle()


def return_result(self) -> dict:
return self.result


def handle(self):
if self.state == 'absent':
self.handle_absent()
elif self.state == 'present':
self.handle_present()

return


def handle_absent(self):
if self.user_name not in self.get_all().raw:
return

res = self.delete()
if res['found'] == True:
self.result['changed'] = True
self.result['msg'] = self.user_name + " has been deleted"

return


def handle_present(self):
if self.user_name in self.get_all().raw:
pre_user = self.get()
else:
pre_user = None

res = self.put()

if res.raw['created'] == True:
self.result['changed'] = True
self.result['msg'] = self.user_name + " has been created"
return

if pre_user == None:
return

if pre_user.raw != self.get().raw:
self.result['changed'] = True
self.result['msg'] = self.user_name + " has beed updated"

return


def get_all(self):
return self.client.security.get_user()


def get(self):
return self.client.security.get_user(username=self.user_name)


def put(self):
return self.client.security.put_user(username=self.user_name, password=self.password, email=self.email, full_name=self.full_name, enabled=self.enabled, roles=self.roles)


def delete(self):
return self.client.security.delete_user(username=self.user_name)
94 changes: 94 additions & 0 deletions plugins/modules/elasticsearch_role.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
#!/usr/bin/python

# Copyright (c) 2024, Tobias Bauriedel <tobias.bauriedel@netways.de>
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or
# https://www.gnu.org/licenses/gpl-3.0.txt)

from __future__ import (absolute_import, division, print_function)
__metaclass__ = type

from ansible.module_utils.basic import AnsibleModule
from ansible_collections.netways.elasticstack.plugins.module_utils.elasticsearch_role import (
Role
)

def run_module():
'''
Elasticsearch user management.
```
netways.elasticstack.elasticsearch_role:
name: new-role
cluster:
- manage_own_api_key
- delegate_pki
indicies:
- names:
- foobar
privileges:
- read
- write
state: present
host: https://localhost:9200
auth_user: elastic
auth_pass: changeMe123!
verify_certs: false
ca_certs: /etc/elasticsearch/certs/http_ca.crt
```
'''

# get role
# https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-get-role.html

# create or update role
# https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-put-role.html

module = AnsibleModule(
argument_spec=dict(
# User args
name=dict(type=str, required=True),
cluster=dict(type=list, required=False),
indicies=dict(type=list, required=False),
state=dict(type=str, required=False, default='present'),

# Auth args
host=dict(type=str, required=True),
auth_user=dict(type=str, required=True),
auth_pass=dict(type=str, required=True, no_log=True),
ca_certs=dict(type=str, required=False),
verify_certs=dict(type=bool, required=False, default=True)
)
)

result = dict(
failed=False,
changed=False
)

if module.params['state'] != 'absent' and module.params['state'] != 'present':
result['stderr'] = "Invalid state given. Please use 'absent' or 'present'"
result['failed'] = True

module.exit_json(**result)


role = Role(
result=result,
role_name=module.params['name'],
cluster=module.params['cluster'],
indicies=module.params['indicies'],
state=module.params['state'],
host=module.params['host'],
auth_user=module.params['auth_user'],
auth_pass=module.params['auth_pass'],
ca_certs=module.params['ca_certs'],
verify_certs=module.params['verify_certs'],
)

result = role.return_result()

module.exit_json(**result)


if __name__ == "__main__":
run_module()
91 changes: 91 additions & 0 deletions plugins/modules/elasticsearch_user.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
#!/usr/bin/python

# Copyright (c) 2024, Tobias Bauriedel <tobias.bauriedel@netways.de>
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or
# https://www.gnu.org/licenses/gpl-3.0.txt)

from __future__ import (absolute_import, division, print_function)
__metaclass__ = type

from ansible.module_utils.basic import AnsibleModule
from ansible_collections.netways.elasticstack.plugins.module_utils.elasticsearch_user import (
User
)


def run_module():
'''
Elasticsearch user management.
```
netways.elasticstack.elasticsearch_user:
name: new-user1
fullname: New User
password: changeMe123!
email: "new@user.de"
roles:
- new-role1
enabled: true
state: absent
host: https://localhost:9200
auth_user: elastic
auth_pass: "{{ elasticstack_password.stdout }}"
verify_certs: false
ca_certs: /etc/elasticsearch/certs/http_ca.crt
```
'''

module = AnsibleModule(
argument_spec=dict(
# User args
name=dict(type=str, required=True),
fullname=dict(type=str, required=False),
password=dict(type=str, required=True, no_log=True),
email=dict(type=str, required=False),
roles=dict(type=list, required=True),
enabled=dict(type=bool, required=False, default=True),
state=dict(type=str, required=False, default="present"),

# Auth args
host=dict(type=str, required=True),
auth_user=dict(type=str, required=True),
auth_pass=dict(type=str, required=True, no_log=True),
ca_certs=dict(type=str, required=False),
verify_certs=dict(type=bool, required=False, default=True)
)
)

result = dict(
failed=False,
changed=False
)

if module.params['state'] != 'absent' and module.params['state'] != 'present':
result['stderr'] = "Invalid state given. Please use 'absent' or 'present'"
result['failed'] = True

module.exit_json(**result)


user = User(
result=result,
user_name=module.params['name'],
full_name=module.params['fullname'],
password=module.params['password'],
email=module.params['email'],
roles=module.params['roles'],
enabled=module.params['enabled'],
state=module.params['state'],
host=module.params['host'],
auth_user=module.params['auth_user'],
auth_pass=module.params['auth_pass'],
ca_certs=module.params['ca_certs'],
verify_certs=module.params['verify_certs'],
)

result = user.return_result()

module.exit_json(**result)

if __name__ == "__main__":
run_module()
1 change: 1 addition & 0 deletions requirements-test.txt
Original file line number Diff line number Diff line change
@@ -4,3 +4,4 @@ molecule
molecule-plugins[docker]
pytest
passlib
elasticsearch
26 changes: 24 additions & 2 deletions roles/beats/tasks/auditbeat.yml
Original file line number Diff line number Diff line change
@@ -10,21 +10,30 @@
string if elasticstack_version is defined else '') |
replace(' ', '')
}}
- name: Install Auditbeat - rpm
- name: Install Auditbeat - rpm - full stack
ansible.builtin.package:
name: "{{ beats_auditbeat_package }}"
enablerepo:
- 'elastic-{{ elasticstack_release }}.x'
when:
- ansible_os_family == "RedHat"
- elasticstack_full_stack | bool

- name: Install Auditbeat - rpm - standalone
ansible.builtin.package:
name: "{{ beats_auditbeat_package }}"
when:
- ansible_os_family == "RedHat"
- not elasticstack_full_stack | bool

- name: Install Auditbeat - deb
ansible.builtin.package:
name: "{{ beats_auditbeat_package }}"
when:
- ansible_os_family == "Debian"

- name: Install Auditbeat latest version - rpm
- name: Install Auditbeat latest version - rpm - full stack
ansible.builtin.package:
name: auditbeat
state: latest
@@ -36,6 +45,19 @@
- elasticstack_version is defined
- elasticstack_version == "latest"
- ansible_os_family == "RedHat"
- elasticstack_full_stack | bool

- name: Install Auditbeat latest version - rpm - standalone
ansible.builtin.package:
name: auditbeat
state: latest
notify:
- Restart Auditbeat
when:
- elasticstack_version is defined
- elasticstack_version == "latest"
- ansible_os_family == "RedHat"
- not elasticstack_full_stack | bool

- name: Install Auditbeat latest version - deb
ansible.builtin.package:
25 changes: 23 additions & 2 deletions roles/beats/tasks/filebeat.yml
Original file line number Diff line number Diff line change
@@ -10,21 +10,29 @@
string if elasticstack_version is defined else '') |
replace(' ', '') }}
- name: Install Filebeat - rpm
- name: Install Filebeat - rpm - full stack
ansible.builtin.package:
name: "{{ beats_filebeat_package }}"
enablerepo:
- 'elastic-{{ elasticstack_release }}.x'
when:
- ansible_os_family == "RedHat"
- elasticstack_full_stack | bool

- name: Install Filebeat - rpm - standalone
ansible.builtin.package:
name: "{{ beats_filebeat_package }}"
when:
- ansible_os_family == "RedHat"
- not elasticstack_full_stack | bool

- name: Install Filebeat - deb
ansible.builtin.package:
name: "{{ beats_filebeat_package }}"
when:
- ansible_os_family == "Debian"

- name: Install Filebeat latest version - rpm
- name: Install Filebeat latest version - rpm - full stack
ansible.builtin.package:
name: filebeat
state: latest
@@ -36,6 +44,19 @@
- elasticstack_version is defined
- elasticstack_version == "latest"
- ansible_os_family == "RedHat"
- elasticstack_full_stack | bool

- name: Install Filebeat latest version - rpm - standalone
ansible.builtin.package:
name: filebeat
state: latest
notify:
- Restart Filebeat
when:
- elasticstack_version is defined
- elasticstack_version == "latest"
- ansible_os_family == "RedHat"
- not elasticstack_full_stack | bool

- name: Install Filebeat latest version - deb
ansible.builtin.package:
26 changes: 24 additions & 2 deletions roles/beats/tasks/metricbeat.yml
Original file line number Diff line number Diff line change
@@ -11,21 +11,29 @@
replace(' ', '')
}}
- name: Install Metricbeat - rpm
- name: Install Metricbeat - rpm - full stack
ansible.builtin.package:
name: "{{ beats_metricbeat_package }}"
enablerepo:
- 'elastic-{{ elasticstack_release }}.x'
when:
- ansible_os_family == "RedHat"
- elasticstack_full_stack | bool

- name: Install Metricbeat - rpm - standalone
ansible.builtin.package:
name: "{{ beats_metricbeat_package }}"
when:
- ansible_os_family == "RedHat"
- not elasticstack_full_stack | bool

- name: Install Metricbeat - deb
ansible.builtin.package:
name: "{{ beats_metricbeat_package }}"
when:
- ansible_os_family == "Debian"

- name: Install Metricbeat latest version - rpm
- name: Install Metricbeat latest version - rpm - full stack
ansible.builtin.package:
name: metricbeat
state: latest
@@ -37,6 +45,20 @@
- elasticstack_version is defined
- elasticstack_version == "latest"
- ansible_os_family == "RedHat"
- elasticstack_full_stack | bool

- name: Install Metricbeat latest version - rpm - standalone
ansible.builtin.package:
name: metricbeat
state: latest
notify:
- Restart Metricbeat
when:
- elasticstack_version is defined
- elasticstack_version == "latest"
- ansible_os_family == "RedHat"
- not elasticstack_full_stack | bool


- name: Install Metricbeat latest version - deb
ansible.builtin.package:
4 changes: 2 additions & 2 deletions roles/beats/templates/filebeat.yml.j2
Original file line number Diff line number Diff line change
@@ -56,7 +56,7 @@ filebeat.inputs:
- type: tcp
enabled: true
max_message_size: 10MiB
host: "0.0.0.0:514"
host: "0.0.0.0:{{ beats_filebeat_syslog_tcp_port }}"
{% if beats_fields is defined %}
fields:
{% for field in beats_fields %}
@@ -69,7 +69,7 @@ filebeat.inputs:
- type: udp
enabled: true
max_message_size: 10MiB
host: "0.0.0.0:514"
host: "0.0.0.0:{{ beats_filebeat_syslog_udp_port }}"
{% if beats_fields is defined %}
fields:
{% for field in beats_fields %}
2 changes: 2 additions & 0 deletions roles/elasticsearch/defaults/main.yml
Original file line number Diff line number Diff line change
@@ -22,6 +22,7 @@ elasticsearch_conf_dir: "/etc/elasticsearch/"
elasticsearch_config_jvm: "jvm.options.j2"
elasticsearch_user: elasticsearch
elasticsearch_group: elasticsearch
elasticsearch_api_host: localhost

# JVM custom parameters
elasticsearch_java_home: ''
@@ -39,6 +40,7 @@ elasticsearch_tls_key_passphrase: PleaseChangeMeIndividually
elasticsearch_cert_validity_period: 1095
elasticsearch_cert_expiration_buffer: 30
elasticsearch_cert_will_expire_soon: false
elasticsearch_ssl_verification_mode: full

# only used internally
elasticsearch_freshstart:
10 changes: 5 additions & 5 deletions roles/elasticsearch/tasks/elasticsearch-security.yml
Original file line number Diff line number Diff line change
@@ -382,7 +382,7 @@

- name: Check for API with bootstrap password
ansible.builtin.uri:
url: "{{ elasticsearch_http_protocol }}://localhost:{{ elasticstack_elasticsearch_http_port }}"
url: "{{ elasticsearch_http_protocol }}://{{ elasticsearch_api_host }}:{{ elasticstack_elasticsearch_http_port }}"
user: elastic
password: "{{ elasticsearch_bootstrap_pw }}"
validate_certs: false
@@ -401,7 +401,7 @@

- name: Check for cluster status with bootstrap password
ansible.builtin.uri:
url: "{{ elasticsearch_http_protocol }}://localhost:{{ elasticstack_elasticsearch_http_port }}/_cluster/health?pretty"
url: "{{ elasticsearch_http_protocol }}://{{ elasticsearch_api_host }}:{{ elasticstack_elasticsearch_http_port }}/_cluster/health?pretty"
user: elastic
password: "{{ elasticsearch_bootstrap_pw }}"
validate_certs: false
@@ -428,7 +428,7 @@

- name: Check for API availability with elastic password
ansible.builtin.uri:
url: "{{ elasticsearch_http_protocol }}://localhost:{{ elasticstack_elasticsearch_http_port }}"
url: "{{ elasticsearch_http_protocol }}://{{ elasticsearch_api_host }}:{{ elasticstack_elasticsearch_http_port }}"
user: elastic
password: "{{ elasticstack_password.stdout }}"
validate_certs: false
@@ -457,7 +457,7 @@
curl
-k
-X PUT
"{{ elasticsearch_http_protocol }}://elastic:{{ elasticstack_password.stdout }}@localhost:9200/_cluster/settings"
"{{ elasticsearch_http_protocol }}://elastic:{{ elasticstack_password.stdout }}@{{ elasticsearch_api_host }}:9200/_cluster/settings"
-H 'Content-Type: application/json' -d
'
{
@@ -479,7 +479,7 @@

- name: Check for cluster status with elastic password
ansible.builtin.uri:
url: "{{ elasticsearch_http_protocol }}://localhost:{{ elasticstack_elasticsearch_http_port }}/_cluster/health?pretty"
url: "{{ elasticsearch_http_protocol }}://{{ elasticsearch_api_host }}:{{ elasticstack_elasticsearch_http_port }}/_cluster/health?pretty"
user: elastic
password: "{{ elasticstack_password.stdout }}"
validate_certs: false
12 changes: 10 additions & 2 deletions roles/elasticsearch/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -141,13 +141,21 @@
- elasticstack_password.stdout is defined
- elasticstack_version is version( ansible_facts.packages['elasticsearch'][0].version, '>')

- name: Install Elasticsearch - rpm
- name: Install Elasticsearch - rpm - full stack
ansible.builtin.package:
name: "{{ elasticsearch_package }}"
enablerepo:
- 'elastic-{% if elasticstack_variant == "oss" %}oss-{% endif %}{{ elasticstack_release }}.x'
when:
- ansible_os_family == "RedHat"
- elasticstack_full_stack | bool

- name: Install Elasticsearch - rpm - standalone
ansible.builtin.package:
name: "{{ elasticsearch_package }}"
when:
- ansible_os_family == "RedHat"
- not elasticstack_full_stack | bool

- name: Install Elasticsearch - deb
ansible.builtin.package:
@@ -234,7 +242,7 @@
block:
- name: Check for cluster status without security
ansible.builtin.uri:
url: "http://localhost:{{ elasticstack_elasticsearch_http_port }}/_cluster/health?pretty"
url: "http://{{ elasticsearch_api_host }}:{{ elasticstack_elasticsearch_http_port }}/_cluster/health?pretty"
register: elasticsearch_cluster_status
ignore_errors: "{{ ansible_check_mode }}"
until: elasticsearch_cluster_status.json.status == "green"
2 changes: 1 addition & 1 deletion roles/elasticsearch/tasks/wait_for_instance.yml
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@

- name: Wait for instance
ansible.builtin.wait_for:
host: "{{ hostvars[item].ansible_default_ipv4.address }}"
host: "{{ elasticsearch_api_host }}"
port: "{{ elasticstack_elasticsearch_http_port }}"
timeout: 600
tags:
25 changes: 21 additions & 4 deletions roles/elasticsearch/templates/elasticsearch.yml.j2
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
{{ ansible_managed | comment }}

node.name: "{{ elasticsearch_nodename }}"
path.data: {{ elasticsearch_datapath }}
path.logs: {{ elasticsearch_logpath }}
@@ -7,6 +9,12 @@ network.host: [ {{ elasticsearch_network_host }} ]
{% else %}
network.host: [ "_local_", "_site_" ]
{% endif %}
{% if elasticstack_elasticsearch_http_port is defined %}
http.port: "{{ elasticstack_elasticsearch_http_port }}"
{% endif %}
{% if elasticsearch_transport_port is defined %}
transport.port: "{{ elasticsearch_transport_port }}"
{% endif %}
{% if elasticsearch_http_publish_host is defined %}
http.publish_host: "{{ elasticsearch_http_publish_host }}"
{% endif %}
@@ -22,11 +30,16 @@ node.roles: [ {% for type in elasticsearch_node_types %}{{ type }}{% if not loop
discovery.type: single-node
{% endif %}

{# Quickfix to override seed_hosts. Otherwise all nodes, not only master nodes are added to seed_hosts #}
{% if elasticsearch_seed_hosts is defined %}
discovery.seed_hosts: {{ elasticsearch_seed_hosts }}
{% else %}
{% if elasticstack_release | int < 8 or groups['elasticsearch'] | length > 1 %}
discovery.seed_hosts: [ {% for host in groups['elasticsearch'] %}
"{{ hostvars[host].ansible_default_ipv4.address | default(hostvars[host].ansible_all_ipv4_addresses[0]) }}"{% if not loop.last %},{% endif %}
{% endfor %} ]
{% endif %}
{% endif %}

{% if not elaticsearch_cluster_set_up | bool and groups['elasticsearch'] | length > 1 %}
{% if elasticsearch_node_types is defined %}
@@ -48,14 +61,18 @@ bootstrap.system_call_filter: false
{% endif %}
{% if elasticstack_variant == "elastic" %}
xpack.ml.enabled: {{ elasticsearch_ml_enabled }}
{% if elasticstack_release == 7 %}
xpack.monitoring.collection.enabled: {{ elasticsearch_monitoring_enabled }}
{% endif %}
{% if elasticsearch_security | bool %}
xpack.security.enabled: true
{% if elasticsearch_security_enrollment is defined %}
xpack.security.enrollment.enabled: {{ elasticsearch_security_enrollment }}
{% endif %}
xpack.security.transport.ssl.enabled: true
#xpack.security.transport.ssl.verification_mode: certificate
xpack.security.transport.ssl.verification_mode: none
xpack.security.transport.ssl.keystore.path: certs/{{ ansible_hostname }}.p12
xpack.security.transport.ssl.truststore.path: certs/{{ ansible_hostname }}.p12
xpack.security.transport.ssl.verification_mode: {{ elasticsearch_ssl_verification_mode }}
xpack.security.transport.ssl.keystore.path: certs/{{ ansible_hostname }}.p12
xpack.security.transport.ssl.truststore.path: certs/{{ ansible_hostname }}.p12
{% if elasticsearch_http_security | bool %}
xpack.security.http.ssl.enabled: true
xpack.security.http.ssl.keystore.path: certs/{{ ansible_hostname }}.p12
10 changes: 9 additions & 1 deletion roles/kibana/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -43,13 +43,21 @@
string if elasticstack_version is defined else '') |
replace(' ', '') }}
- name: Install Kibana - rpm
- name: Install Kibana - rpm - full stack
ansible.builtin.package:
name: "{{ kibana_package }}"
enablerepo:
- 'elastic-{% if elasticstack_variant == "oss" %}oss-{% endif %}{{ elasticstack_release }}.x'
when:
- ansible_os_family == "RedHat"
- elasticstack_full_stack | bool

- name: Install Kibana - rpm - standalone
ansible.builtin.package:
name: "{{ kibana_package }}"
when:
- ansible_os_family == "RedHat"
- not elasticstack_full_stack | bool

- name: Install Kibana - deb
ansible.builtin.package:
10 changes: 9 additions & 1 deletion roles/logstash/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -68,13 +68,21 @@
replace(' ', '')
}}
- name: Install Logstash - rpm
- name: Install Logstash - rpm - full stack
ansible.builtin.package:
name: "{{ logstash_package }}"
enablerepo:
- 'elastic-{% if elasticstack_variant == "oss" %}oss-{% endif %}{{ elasticstack_release }}.x'
when:
- ansible_os_family == "RedHat"
- elasticstack_full_stack | bool

- name: Install Logstash - rpm - standalone
ansible.builtin.package:
name: "{{ logstash_package }}"
when:
- ansible_os_family == "RedHat"
- not elasticstack_full_stack | bool

- name: Install Logstash - deb
ansible.builtin.package:
28 changes: 23 additions & 5 deletions roles/repos/tasks/debian.yml
Original file line number Diff line number Diff line change
@@ -6,19 +6,37 @@
- gpg-agent
state: present

- name: Ensure Elastic Stack key is available (Debian)
- name: Ensure Elastic Stack key is removed (Debian legacy format)
ansible.builtin.apt_key:
url: https://artifacts.elastic.co/GPG-KEY-elasticsearch
state: present
url: "{{ elasticstack_repo_key }}"
state: absent

- name: Ensure Elastic Stack key is available (Debian)
ansible.builtin.get_url:
url: "{{ elasticstack_repo_key }}"
dest: /usr/share/keyrings/elasticsearch.asc
mode: "0644"

- name: Ensure Elastic Stack apt repo is absent (Debian legacy format)
ansible.builtin.file:
path: /etc/apt/sources.list.d/artifacts_elastic_co_packages_{{ item }}_x_apt.list
state: absent
with_items:
- "7"
- "oss-7"
- "8"
- "oss-8"

- name: Ensure Elastic Stack apt repository is configured (Debian)
ansible.builtin.apt_repository:
repo: deb https://artifacts.elastic.co/packages/{{ elasticstack_release }}.x/apt stable main
repo: deb [signed-by=/usr/share/keyrings/elasticsearch.asc] https://artifacts.elastic.co/packages/{{ elasticstack_release }}.x/apt stable main
state: present
filename: elasticstack
when: elasticstack_variant == "elastic"

- name: Ensure Elastic Stack OSS apt repository is configured (Debian)
ansible.builtin.apt_repository:
repo: deb https://artifacts.elastic.co/packages/oss-{{ elasticstack_release }}.x/apt stable main
repo: deb [signed-by=/usr/share/keyrings/elasticsearch.asc] https://artifacts.elastic.co/packages/oss-{{ elasticstack_release }}.x/apt stable main
state: present
filename: elasticstack
when: elasticstack_variant == "oss"
6 changes: 3 additions & 3 deletions roles/repos/tasks/redhat.yml
Original file line number Diff line number Diff line change
@@ -36,7 +36,7 @@

- name: Ensure Elastic repository key is available (RedHat)
ansible.builtin.rpm_key:
key: https://artifacts.elastic.co/GPG-KEY-elasticsearch
key: "{{ elasticstack_repo_key }}"
state: present

- name: Ensure Elastic Stack yum repository is configured (RedHat)
@@ -46,7 +46,7 @@
file: elastic-release
baseurl: https://artifacts.elastic.co/packages/{{ elasticstack_release }}.x/yum
gpgcheck: yes
gpgkey: https://artifacts.elastic.co/GPG-KEY-elasticsearch
gpgkey: "{{ elasticstack_repo_key }}"
enabled: "{{ elasticstack_enable_repos | bool }}"
when: elasticstack_variant == "elastic"

@@ -57,6 +57,6 @@
file: elastic-oss-release
baseurl: https://artifacts.elastic.co/packages/oss-{{ elasticstack_release }}.x/yum
gpgcheck: yes
gpgkey: https://artifacts.elastic.co/GPG-KEY-elasticsearch
gpgkey: "{{ elasticstack_repo_key }}"
enabled: "{{ elasticstack_enable_repos | bool }}"
when: elasticstack_variant == "oss"

Unchanged files with check annotations Beta

success_msg: "'{{ item }}' was found in nodes.content"
with_inventory_hostnames: all
when: groups['elasticsearch'] | length > 1

Check warning on line 138 in molecule/elasticstack_default/verify.yml

GitHub Actions / lint

138:1 [empty-lines] too many blank lines (1 > 0)

Check warning on line 138 in molecule/elasticstack_default/verify.yml

GitHub Actions / lint_full / lint

138:1 [empty-lines] too many blank lines (1 > 0)
You are viewing a condensed version of this merge commit. You can view the full changes here.