Builds a multi-node Elasticsearch 9.x cluster on Debian, with authentication, TLS on both the transport and HTTP layers, and ILM-based index retention.
This role replaces elastic.elasticsearch, which Elastic archived in 2022 and
which never supported 8.x or 9.x.
- Adds the Elastic apt repository (
signed-bya key in/etc/apt/keyrings, sinceapt_keyis deprecated andtrusted.gpgis ignored on Debian 13) and installs a pinned, dpkg-held package version. - Tunes the host:
vm.max_map_count, a systemdLimitMEMLOCKoverride forbootstrap.memory_lock, and swap off. - Undoes the package's security auto-configuration — see below.
- Issues a cluster CA and a certificate per node with
elasticsearch-certutil, and mirrors the material back to the controller so thelogstashandkibanaroles can trust the same CA. - Templates
elasticsearch.yml, seedsbootstrap.passwordinto the keystore, and starts the service. - Once the cluster is up: sets the
kibana_systempassword, creates a least-privilege writer role and user for Logstash, and installs the ILM policy and composable index template.
On a fresh install the Elasticsearch .deb runs auto-configure-node from its
postinst. That generates its own PKCS#12 keypair, appends an
xpack.security block to elasticsearch.yml, and writes an
autoconfiguration.password_hash entry into the keystore.
That hash takes precedence over bootstrap.password, so the elastic user
would never receive the password this role sets. There is no environment
variable to opt out — the postinst calls the tool unconditionally on a fresh
install, and only skips when it detects security is already configured, which
is not knowable before the package directory exists.
So the role installs first and reclaims afterwards: it deletes the generated
http.p12, transport.p12 and http_ca.crt, removes the auto-configuration
keystore entries, and overwrites elasticsearch.yml wholesale. The service is
never started before that has happened, because the role — not the package —
owns the service state (RESTART_ON_UPGRADE=false during install).
There are no default credentials. The role asserts on these before doing anything:
elasticsearch_elastic_password
elasticsearch_kibana_system_password
elasticsearch_logstash_password
elasticsearch_seed_hosts
elasticsearch_initial_master_nodes
See molecule/default/converge.yml for a complete working configuration.
elasticsearch_ca_host (the first host in the play by default) generates
everything, and the material is mirrored to elasticsearch_local_certs_dir
(.elastic-certs/, git-ignored) on the controller. Each node then receives
ca.crt, node.crt and node.key into /etc/elasticsearch/certs.
Generation is guarded by creates:, so adding a node to the inventory will
not issue a certificate for it on its own. Rerun with
-e elasticsearch_regenerate_certs=true to throw away the CA and reissue the
whole set — which is a full-cluster restart, not a rolling one.
elasticsearch_manage_ilm installs an ILM policy (named tpot, matching T-Pot
upstream) and a composable index template covering logstash-* and fails-*.
This replaces the geerlingguy.elasticsearch-curator cron job; Curator is
end-of-life and does not support 9.x.
The policy has a delete phase at elasticsearch_ilm_delete_after (30 days)
and deliberately no rollover action. Logstash writes one index per
honeypot per day, so min_age measured from index creation already means
"older than N days" — and rollover would fail anyway, because it requires a
data stream or a rollover alias.
node.master/node.data/node.ingestwere removed in 8.0. Useelasticsearch_node_roles. The role asserts the values are ones 9.x knows.transport.tcp.portwas removed in 8.0; the setting istransport.port.cluster.initial_master_nodesis ignored after the cluster bootstraps. Elasticsearch logs a notice suggesting its removal; it is kept here so that rebuilding from scratch still works.
- hosts: elasticsearch
roles:
- role: honeynet.elasticsearch
vars:
elastic_version: "9.3.5"
elastic_repo_channel: "9.x"
elasticsearch_elastic_password: "{{ vault_elasticsearch_elastic_password }}"
elasticsearch_kibana_system_password: "{{ vault_elasticsearch_kibana_system_password }}"
elasticsearch_logstash_password: "{{ vault_elasticsearch_logstash_password }}"
elasticsearch_seed_hosts:
- elasticsearch-01.example.org
- elasticsearch-02.example.org
- elasticsearch-03.example.org
elasticsearch_initial_master_nodes:
- elasticsearch-01
- elasticsearch-02
- elasticsearch-03
See defaults/main.yml for the full set of variables, and
molecule/default/converge.yml for a complete working configuration.
MIT
The Honeynet Project.