Operations 12 min read

How to Build a Secure 3‑Node Elasticsearch 7.9 Cluster with Vagrant

This guide walks through the new features of Elastic Stack 7.9 and shows step‑by‑step how to provision a three‑node Elasticsearch cluster on a local Mac using Vagrant, enabling security, TLS, API keys, and providing all necessary scripts, configuration files, and verification commands.

DevOps Coach
DevOps Coach
DevOps Coach
How to Build a Secure 3‑Node Elasticsearch 7.9 Cluster with Vagrant

Elastic Stack 7.9 introduces several new components such as Elastic Agent for unified data collection, Enterprise Search, Endpoint Security, and an enhanced Ingest Manager that centralizes Beat configuration, moving the platform closer to a SaaS‑style monitoring solution.

Enable username/password authentication.

Enable transport SSL encryption between ES nodes.

Enable HTTP SSL encryption for client connections.

Include certificate‑generation commands in the provisioning script to avoid manual effort.

Demo Environment Overview

The demonstration uses a local test environment with the following stack:

Mac OS host.

Vagrant for VM orchestration.

VirtualBox running CentOS 8.

Elastic Stack 7.9.0.

IP addresses and hostnames defined in the Vagrantfile.

The vagrant-hostsupdater plugin synchronizes the host's /etc/hosts file with all VMs, mimicking a production DNS setup.

All configuration files and provisioning scripts are available at:

https://github.com/DevOps-Coach/elasticstack.git

➜  elasticstack git:(master) ✗ vagrant up es1 es2 es3
Bringing machine 'es1' up with 'virtualbox' provider...
Bringing machine 'es2' up with 'virtualbox' provider...
Bringing machine 'es3' up with 'virtualbox' provider...
==> es1: Importing base box 'bento/centos-8'...
... (output omitted) ...
    es3: ● elasticsearch.service - Elasticsearch
    es3:    Loaded: loaded (/usr/lib/systemd/system/elasticsearch.service; enabled; vendor preset: disabled)
    es3:    Active: active (running) since Thu 2020-08-27 05:55:21 UTC; 223ms ago
    es3:    Docs: https://www.elastic.co
    es3:    Main PID: 4205 (java)
    es3:    Memory: 1.2G
    es3: Provisioning script works good!
    es3: Please access Elasticsearch https://192.168.50.13:9200

Verification of the cluster can be performed with the following curl command (replace the password when prompted):

➜  elasticstack git:(master) ✗ curl --cacert certs/ca/ca.crt -u elastic 'https://es1.zenlab.local:9200/_cat/nodes?v'
Enter host password for user 'elastic':
ip            heap.percent ram.percent cpu load_1m load_5m load_15m node.role master name
192.168.50.13           26          95   8    0.03    0.31     0.18 dilmrt    -      es3
192.168.50.12           33          95   0    0.01    0.14     0.09 dilmrt    -      es2
192.168.50.11           36          93   1    0.06    0.16     0.12 dilmrt    *      es1

The password for the built‑in elastic user is displayed during the initial setup and should be saved for later use.

Certificate generation is driven by the instance.yml seed file, which defines all nodes that may appear in the test environment:

# instance.yml
instances:
  - name: 'es1'
    ip: ['192.168.50.11']
    dns: ['es1.zenlab.local']
  - name: 'es2'
    ip: ['192.168.50.12']
    dns: ['es2.zenlab.local']
  - name: 'es3'
    ip: ['192.168.50.13']
    dns: ['es3.zenlab.local']
  # additional nodes (es4‑es9, lk) are defined similarly

Elasticsearch Installation Script

The first node is provisioned with the following Bash script ( pre-install-es1.sh). It installs the package, configures system limits, generates TLS certificates, copies them into place, applies the custom elasticsearch.yml, and starts the service.

#!/bin/bash
# author: Martin Liu
# url: martinliu.cn

elastic_version='7.9.0'

echo "Provisioning a Elasticsearch $elastic_version Server..."
sudo date > /etc/vagrant_provisioned_at

# OS tuning
sudo swapoff -a
sudo sysctl -w vm.max_map_count=262144
sudo sysctl -p
sudo sh -c "echo 'elasticsearch  -  nofile  65535' >> /etc/security/limits.conf"

# Custom MOTD
sudo sh -c "echo '**** --  --  --  --  --  --  --  -- ****' > /etc/motd"
sudo sh -c "echo '**** Welcome to Elastic Stack Labs' >> /etc/motd"
sudo sh -c "echo '**** --  --  --  --  --  --  --  -- ****' >> /etc/motd"
sudo sh -c "echo '*' >> /etc/motd"

# Install package
sudo rpm -ivh /vagrant/rpm/elasticsearch-$elastic_version-x86_64.rpm

# Generate certificates
sudo rm -f /vagrant/certs/certs.zip
sudo rm -rf /vagrant/certs/es*
sudo rm -rf /vagrant/certs/ca
sudo rm -rf /vagrant/certs/lk
sudo /usr/share/elasticsearch/bin/elasticsearch-certutil cert -in /vagrant/certs/instance.yml -pem -out /vagrant/certs/certs.zip -s

# Unzip certificates
sudo /usr/bin/unzip /vagrant/certs/certs.zip -d /vagrant/certs/

# Deploy certificates
sudo cp /vagrant/certs/ca/ca.crt /etc/elasticsearch/
sudo cp /vagrant/certs/es1/* /etc/elasticsearch/

# Apply configuration
sudo cp /vagrant/es1.yml /etc/elasticsearch/elasticsearch.yml

# Enable and start service
sudo systemctl daemon-reload
sudo systemctl enable elasticsearch.service
sudo systemctl start elasticsearch.service
sudo systemctl status elasticsearch

# Auto‑generate built‑in user passwords
sudo /usr/share/elasticsearch/bin/elasticsearch-setup-passwords auto -b

echo "Provisioning script works good!"
echo "Please access Elasticsearch https://192.168.50.11:9200"

For non‑Vagrant environments, adjust file paths accordingly. Scripts for the second and third nodes are similar and can be found in the repository.

Elasticsearch Configuration File

The reference elasticsearch.yml for the first node includes cluster naming, node naming, data and log paths, network host, discovery settings, and all security‑related toggles:

# ---------------------------------- Cluster -----------------------------------
cluster.name: elk4devops

# ------------------------------------ Node ------------------------------------
node.name: es1

# ----------------------------------- Paths ------------------------------------
path.data: /var/lib/elasticsearch
path.logs: /var/log/elasticsearch

# ---------------------------------- Network -----------------------------------
network.host: es1.zenlab.local

# --------------------------------- Discovery ----------------------------------
cluster.initial_master_nodes: ["es1"]
discovery.seed_hosts: ["es1.zenlab.local"]

# ------------------------------- TLS and Cert ---------------------------------
xpack.security.enabled: true
xpack.security.transport.ssl.enabled: true
xpack.security.transport.ssl.certificate_authorities: ca.crt
xpack.security.transport.ssl.key: ${node.name}.key
xpack.security.transport.ssl.certificate: ${node.name}.crt
xpack.security.http.ssl.enabled: true
xpack.security.http.ssl.certificate_authorities: ca.crt
xpack.security.http.ssl.key: ${node.name}.key
xpack.security.http.ssl.certificate: ${node.name}.crt
xpack.security.authc.api_key.enabled: true
xpack.monitoring.collection.enabled: true

# ------------------------------- App Search ---------------------------------
action.auto_create_index: ".app-search-*-logs-*,-.app-search-*,+*"

Configuration files for the remaining nodes differ slightly; see the codebase for details.

Conclusion

When building a three‑node Elasticsearch cluster, enabling the full suite of security and encryption options via automated scripts dramatically reduces manual effort and creates a robust foundation for adding future Elastic Stack components. A well‑configured cluster minimizes later re‑configuration work and simplifies subsequent testing and development.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

ElasticsearchInstallationTLSElastic StackVagrant
DevOps Coach
Written by

DevOps Coach

Master DevOps precisely and progressively.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.