Install and Configure Elasticsearch

Download and Install Elasticsearch 8.x.x or 9.x.x

Official Documentation: For detailed installation guidance, see Elastic's official Elasticsearch installation documentation and Windows installation guide.

Download Elasticsearch 8.x.x or 9.x.x

  1. Visit Elastic's official download page.
  2. Download the 8.x.x or 9.x.x Windows ZIP version. Both Server 2024 and Server 2025 support Elasticsearch 8.x.x and 9.x.x.
  3. Before extracting, see How to Unblock Downloaded Files.
  4. Extract the files to C:\elastic

Install and Configure Elasticsearch 8.x.x or 9.x.x

  1. Open an elevated PowerShell window, navigate to Elasticsearch's bin folder (C:\elastic\elasticsearch-x.x.x\bin), and run the following command to start Elasticsearch and perform the auto-configuration steps:

    Copy
    .\elasticsearch.bat

    When starting Elasticsearch for the first time, security features are enabled and configured by default:

    • Authentication and authorization are enabled, and a password is generated for the elastic built-in superuser.
    • Certificates and keys are generated for the transport and HTTP layer, and TLS is enabled and configured with these keys and certificates.
    • An enrollment token is generated for Kibana, which is valid for 30 minutes.

    Single Cluster with Multiple Nodes: In a single cluster with multiple nodes setup, the enrollment token should be generated on a master-eligible node.

  2. Save the token for future reference. Once the enrollment token is displayed, you need to stop Elasticsearch so you can proceed with the next steps. To do this, return to the PowerShell window where Elasticsearch is running and press Ctrl+C on your keyboard. This will safely terminate the process. The enrollment token will look similar to:

    Copy
    Enrollment token for Kibana:
    eyJ2ZXIiOiI4LjE3LjMiLCJ...<rest_of_token>
  3. Open an elevated PowerShell window, navigate to Elasticsearch's bin folder (C:\elastic\elasticsearch-x.x.x\bin), and run the following command to install Elasticsearch as a Windows service:

    Copy
    .\elasticsearch-service.bat install
    Show sample output

    The output will look similar to:

    Copy
    Installing service      :  "elasticsearch-service-x64"
    Using JAVA_HOME (64-bit):  C:\Program Files\Java\jdk-17
    The service 'elasticsearch-service-x64' has been installed.

Run Elasticsearch as a Windows Service

  1. Open an elevated PowerShell window, navigate to Elasticsearch's bin folder (C:\elastic\elasticsearch-x.x.x\bin), and run the following command to start the Elasticsearch service:

    Copy
    .\elasticsearch-service.bat start
    Show sample output and alternative method

    The output will look similar to:

    Copy
    Starting service   :  "elasticsearch-service-x64"
    The service 'elasticsearch-service-x64' has been started.

    Alternative: If PowerShell fails to start the service, you can use the Windows Services application:

    1. Open the Start menu, type services.msc, and press Enter.
    2. In the Services window, locate elasticsearch-service-x64.
    3. Right-click the service and select Start.
    4. Use this method if you encounter permission or environment issues with PowerShell.

Stack Monitoring (Optional)

Click to expand Stack Monitoring details

Note: Stack Monitoring is disabled by default. It generates high transaction volume with minimal value. Enable only if needed for troubleshooting.

  1. Navigate to the Elasticsearch configuration folder (e.g., C:\elastic\elasticsearch-x.x.x\config) and open the elasticsearch.yml file.

  2. To enable Stack Monitoring (if needed), add the following line:

    Copy
    xpack.monitoring.collection.enabled: false  # Set to true only if needed
  3. Save the changes and restart the Elasticsearch service using the Windows Services application.

Configure Node Roles, Discovery and Network (Single Cluster with Multiple Nodes)

Purpose: This section covers configuration for a single Elasticsearch cluster with multiple nodes. All nodes configured here belong to the same cluster (same cluster.name). For multi-cluster architecture (separate independent clusters), see the Multi-Cluster Configuration section below.

Official Documentation: For comprehensive configuration details, see Elasticsearch configuration documentation, Node roles, and Discovery and cluster formation.

Master Nodes (node.roles: ["master"])
  • Manage cluster state and coordination
  • Lightweight operations - do NOT store data (verify that data is not present in node.roles)
  • Resources: 2-4 CPU, 8-16GB RAM
Data Nodes (node.roles: ["data", "ingest"])
  • Store indices and execute queries
  • Resource-intensive - when configured without the master role, data nodes do not participate in master elections
  • Minimum 2 nodes for redundancy
  • Resources: Based on data volume (high CPU, RAM, fast storage)
  1. Navigate to the Elasticsearch configuration folder (e.g., C:\elastic\elasticsearch-x.x.x\config), open the elasticsearch.yml file and configure node roles:

    Click to expand configuration parameters explanation
    • cluster.name:
    • node.name:
    • node.roles: {List of responsibilities the node performs (master, data, ingest, coordinating, ml)}
    • network.host: {The network interface/address Elasticsearch binds to for transport and HTTP. In production, bind to the server's private IP (or a specific hostname), and ensure firewall rules cover ports 9200 and 9300 appropriately. Avoid 0.0.0.0 unless you intentionally expose the service to all interfaces.}
    • http.port: {Port for the HTTP REST API (Kibana, APM, curl clients)}
    • discovery.seed_hosts:
    • cluster.initial_master_nodes:
    Sample Production Master Node Configuration
    Copy
    # ---------------------------------- Cluster -----------------------------------
    cluster.name: primary-cluster
    #
    # ------------------------------------ Node ------------------------------------
    node.name: es-master-01
    node.roles: [ "master" ]  # Master only - NO data role
    #
    # ---------------------------------- Network -----------------------------------
    network.host: <primary-master-01-ip>
    http.port: 9200
    #
    # --------------------------------- Discovery ----------------------------------
    discovery.seed_hosts: ["<primary-master-01-ip>","<primary-master-02-ip>","<primary-master-03-ip>"]
    cluster.initial_master_nodes: ["es-master-01","es-master-02","es-master-03"]
    Sample Production Data Node Configuration
    Copy
    # ---------------------------------- Cluster -----------------------------------
    cluster.name: primary-cluster
    #
    # ------------------------------------ Node ------------------------------------
    #
    # Use a descriptive name for the node:
    #
    node.name: es-data-01
    node.roles: [ "data", "ingest" ]
    #
    # ---------------------------------- Network -----------------------------------
    #
    network.host: <primary-data-01-ip>
    http.port: 9200
    #
    # --------------------------------- Discovery ----------------------------------
    #
    discovery.seed_hosts: ["<primary-master-01-ip>","<primary-master-02-ip>","<primary-master-03-ip>"]
    cluster.initial_master_nodes: ["es-master-01","es-master-02","es-master-03"]  # only on first cluster bootstrap
  2. For dedicated master nodes, use node.roles: ["master"] and verify that data is not present in node.roles.

IMPORTANT: Node roles and initial bootstrap configuration

cluster.initial_master_nodes is only for initial bootstrap

The cluster.initial_master_nodes setting is only for the very first cluster formation and must be removed or commented out on all nodes after the cluster has formed successfully to avoid accidental re-bootstrap scenarios.

Node role separation is the most critical production architectural difference

Separating master and data roles is the most critical architectural difference for production environments to achieve optimal performance and stability.

Critical Rules:

  • Recommended for production: Separate master and data roles.
  • Roles must be explicitly planned for 2-node, 3-node, or larger clusters.
  • Master and data nodes have very different configurations.
  • Proper master/data node setup is the most important production concern.

Development Environment:

For development purposes, a single node can have all roles assigned. Example configuration:

Copy
# Development single-node configuration
cluster.name: dev-cluster
node.name: dev-node-1
node.roles: ["master", "data", "ingest"]
network.host: localhost
http.port: 9200

Multi-Cluster Configuration (Optional for Single Cluster)

Click to expand Multi-Cluster Configuration details

Purpose: Multi-cluster setup is optional and used when you need to segregate data across independent Elasticsearch clusters (e.g., primary cluster for Environment Watch and a separate audit cluster for DataGrid Audit). Multi-cluster means two independent Elasticsearch clusters with different cluster.name values, connected via Cross-Cluster Search (CCS) or Cross-Cluster Replication (CCR). This is distinct from a single cluster with multiple nodes.

Network Ports for Multi-Cluster Communication

Elasticsearch uses two ports for cluster operations:

  • 9200/tcp: HTTP/REST API (for client connections, Kibana, APM, API requests)
  • 9300/tcp: Transport layer (for node-to-node communication and cross-cluster connectivity)

IMPORTANT: Port 9300 must be accessible between clusters for Cross-Cluster Search (CCS) or Cross-Cluster Replication (CCR). Ensure firewall rules allow traffic on port 9300 between the primary and audit cluster nodes.

Required Configuration Steps for Multi-Cluster

  1. Configure transport port on all nodes in both clusters:

    • Add transport.port: 9300 to elasticsearch.yml (default, but explicit configuration recommended)
  2. Add remote_cluster_client role to nodes that will initiate cross-cluster queries:

    • Not required on all nodes — only on nodes that will coordinate CCS/CCR requests
    • Recommended: Add to dedicated coordinating nodes (nodes with no master or data roles) or create a query tier
    • Alternative: Add to master-eligible nodes if they handle queries (less common in large deployments)
    • Do NOT add to data-only nodes unless they need to directly initiate cross-cluster queries (rare)
    • Primary cluster: Coordinating nodes that will query the audit cluster need this role
    • Audit/secondary cluster: Only needed if querying back to the primary cluster

    Example coordinating node configuration:

    Copy
    node.roles: [ "remote_cluster_client" ]  # Coordinating-only node for cross-cluster queries
  3. Configure firewall rules:

    • Allow bidirectional traffic on port 9300 between primary and audit cluster nodes
    • Allow traffic on port 9200 for HTTP/REST API access from Kibana and applications

IMPORTANT: Transport TLS and Remote Cluster Registration Required

CCS/CCR uses the transport layer (port 9300), so Transport Layer Security (TLS) must be properly configured between clusters.

TLS Trust Model Options:

  1. Shared CA (Recommended): Use the same Certificate Authority (CA) for both clusters

    • Generate one CA using elasticsearch-certutil ca
    • Use this CA to sign certificates for nodes in both clusters
    • Simplifies trust management — all nodes automatically trust each other
    • Both clusters use the same elastic-stack-ca.p12 as truststore
  2. Cross-Trust (Alternative): Each cluster has its own CA

    • Generate separate CAs for each cluster
    • Import the other cluster's CA certificate into each cluster's truststore
    • More complex but provides complete cluster isolation
    • Required if clusters are managed by different teams/organizations

Additional Requirements:

  • Proper Subject Alternative Names (SANs) in certificates to match node addresses
  • Consistent TLS settings across all nodes in both clusters
  • verification_mode should be consistent (recommend certificate or full)

See the Configure Transport Layer Security section for detailed certificate setup instructions. Configure transport TLS before attempting cross-cluster connections.

Configure Primary Cluster for Cross-Cluster Access

On primary cluster nodes that will initiate cross-cluster queries, add the remote_cluster_client role (typically on coordinating or master nodes, not data-only nodes):

Sample Primary Cluster Master Node (with remote_cluster_client)
Copy
# ---------------------------------- Cluster -----------------------------------
cluster.name: primary-cluster
#
# ------------------------------------ Node ------------------------------------
node.name: es-master-01
node.roles: [ "master", "remote_cluster_client" ]  # remote_cluster_client enables cross-cluster queries
#
# ---------------------------------- Network -----------------------------------
network.host: <primary-master-01-ip>
http.port: 9200
transport.port: 9300  # Required for cross-cluster communication
#
# --------------------------------- Discovery ----------------------------------
discovery.seed_hosts: ["<primary-master-01-ip>","<primary-master-02-ip>","<primary-master-03-ip>"]
cluster.initial_master_nodes: ["es-master-01","es-master-02","es-master-03"]
Sample Primary Cluster Data Node Configuration
Copy
# ---------------------------------- Cluster -----------------------------------
cluster.name: primary-cluster
#
# ------------------------------------ Node ------------------------------------
node.name: es-data-01
node.roles: [ "data", "ingest" ]  # Data nodes typically do not need remote_cluster_client
#
# ---------------------------------- Network -----------------------------------
network.host: <primary-data-01-ip>
http.port: 9200
transport.port: 9300  # Required for cross-cluster communication
#
# --------------------------------- Discovery ----------------------------------
discovery.seed_hosts: ["<primary-master-01-ip>","<primary-master-02-ip>","<primary-master-03-ip>"]
cluster.initial_master_nodes: ["es-master-01"]  # only on first cluster bootstrap

Sample Audit Cluster Node Configuration

Configure each audit cluster node with the following settings in elasticsearch.yml:

Sample Audit Cluster Node Configuration
Copy
# ---------------------------------- Cluster -----------------------------------
cluster.name: secondary-cluster
#
# ------------------------------------ Node ------------------------------------
node.name: es-audit-master-01
node.roles: [ "master", "data", "ingest" ]  # Add remote_cluster_client only if querying back to primary
#
# ---------------------------------- Network -----------------------------------
network.host: <secondary-node-01-ip>
http.port: 9200
transport.port: 9300  # Required for cross-cluster communication
#
# --------------------------------- Discovery ----------------------------------
discovery.seed_hosts: ["<secondary-node-01-ip>","<secondary-node-02-ip>","<secondary-node-03-ip>"]
cluster.initial_master_nodes: ["es-audit-master-01","es-audit-master-02","es-audit-master-03"]

Configure Storage Paths

Storage location is critical for Elasticsearch performance

Elasticsearch requires fast storage with high read/write performance.

Development:

  • May use OS disk (C:) temporarily
  • Still not recommended

Production:

  • NEVER use the OS drive (C:)
  • NEVER use a temporary drive for Elasticsearch data and logs.
  • Data MUST reside on a dedicated, high-performance disk
  • Fast storage (SSD/NVMe) is required
  • Never share disk with the operating system

Configuration is simple: Only two settings are needed to redirect data paths.

Understanding Elasticsearch directories:

  • path.data: Stores indices (the actual indexed documents, inverted indices, and metadata)
  • path.logs: Stores Elasticsearch application logs (startup, errors, warnings, query logs)

These are separate directories because data directories require high-performance storage and regular backups, while log directories primarily need adequate space for troubleshooting and monitoring.

  1. Configure path.data and path.logs in elasticsearch.yml to point to dedicated high-performance volumes:

    Copy
    # Production - use dedicated fast disk (D:, E:, or SAN)
    path.data: X:/esdata
    path.logs: X:/eslogs
  2. Save the changes and restart the Elasticsearch service:

    Copy
    Restart-Service -Name "elasticsearch-service-x64"

    Alternative: To restart using the Windows Services application:

    1. Open the Start menu, type services.msc, and press Enter.
    2. In the Services window, locate elasticsearch-service-x64.
    3. Right-click the service and select Restart.

Development Environment: If you are running a single-node development environment and have changed the data path, you may need to reset the elastic user password after restarting the service. Use the following command in the Elasticsearch bin directory:

Copy
.\elasticsearch-reset-password.bat -u elastic

This ensures you can log in to Kibana and perform admin tasks after moving the data directory.

Configure Transport Layer Security for Single Cluster with Multiple Nodes (Production)

Purpose: This step is only required for single cluster with multiple nodes in production. Single-node development environments use Elasticsearch's default auto-generated certificates for transport layer security. A single cluster with multiple nodes requires explicit transport TLS configuration to ensure secure communication between nodes using certificates signed by a Certificate Authority (CA). If you are running a single-node development environment, you can skip this section and proceed to the mapper-size plugin installation.

Official Documentation: For comprehensive transport layer security details, see Elastic's security configuration documentation and TLS encryption documentation.

Create a Certificate Authority (CA)

Purpose: To create a root CA used for signing and issuing certificates for nodes in the cluster. The CA ensures mutual trust among cluster nodes using certificates signed by the same authority.

Single Cluster with Multiple Nodes: Generate certificates on a dedicated master-eligible node server.

Follow these steps on a master-eligible node server:

  1. Open PowerShell in admin mode.
  2. Navigate to the bin folder of Elasticsearch (e.g., C:\elastic\elasticsearch-x.x.x\bin).
  3. Run the following command:
    Copy
    .\elasticsearch-certutil ca
  4. This will generate an elastic-stack-ca.p12 file, which acts as the root CA certificate.

Generate Certificates and Private Keys for Nodes

Purpose: To create unique certificates and private keys for each node in the cluster. These certificates, signed by the CA, enable secure inter-node communication.

  1. Open PowerShell in admin mode.
  2. Navigate to the bin folder of Elasticsearch (e.g., C:\elastic\elasticsearch-x.x.x\bin).
  3. Run the following command:
    Copy
    .\elasticsearch-certutil cert --ca elastic-stack-ca.p12
  4. During execution:
    • Certificate Name: Provide a unique name for each node (e.g., node1.p12, node2.p12).
    • Password: Set a password (use the same password for all nodes).
  5. Repeat this command for each node in the cluster.
  6. After creation of certificates, copy each certificate to its corresponding node server in the same directory where the certificate was generated.

Distribute Certificates and Configure elasticsearch.yml

Purpose: To distribute the generated certificates to all nodes and configure transport layer security settings in elasticsearch.yml.

Follow these steps on all nodes in the cluster:

  1. Copy the generated certificate files to each respective node:

    • Copy elastic-stack-ca.p12 to each node (e.g., C:\elastic\elasticsearch-x.x.x\config\certs\)
    • Copy the node-specific certificate (e.g., node1.p12, node2.p12) to its corresponding node
  2. On each node, open the elasticsearch.yml file (e.g., C:\elastic\elasticsearch-x.x.x\config\elasticsearch.yml)

  3. Add the following transport layer security configuration (update keystore.path to match the node-specific certificate):

    Show transport SSL configuration examples

    Example for Node 1:

    Copy
    xpack.security.transport.ssl.enabled: true
    xpack.security.transport.ssl.verification_mode: certificate
    xpack.security.transport.ssl.keystore.path: certs/node1.p12
    xpack.security.transport.ssl.truststore.path: certs/node1.p12

    Example for Node 2:

    Copy
    xpack.security.transport.ssl.enabled: true
    xpack.security.transport.ssl.verification_mode: certificate
    xpack.security.transport.ssl.keystore.path: certs/node2.p12
    xpack.security.transport.ssl.truststore.path: certs/node2.p12
  4. Save the changes to elasticsearch.yml

Configure Keystore for Secure Password Management

Purpose: To securely store the keystore and truststore passwords, ensuring encrypted access to certificates and private keys.

Follow these steps on all servers and use the same password on all servers:

  1. For each node, execute the following commands in the bin folder of Elasticsearch:

    Show keystore password commands

    Remove Existing Passwords (if any):

    • Keystore Password:
      Copy
      .\elasticsearch-keystore remove xpack.security.transport.ssl.keystore.secure_password
    • Truststore Password:
      Copy
      .\elasticsearch-keystore remove xpack.security.transport.ssl.truststore.secure_password

    Add New Passwords:

    • Keystore Password:

      Enter the password created during certificate generation when prompted.

      Copy
      .\elasticsearch-keystore add xpack.security.transport.ssl.keystore.secure_password
    • Truststore Password:

      Enter the same password used during certificate generation when prompted.

      Copy
      .\elasticsearch-keystore add xpack.security.transport.ssl.truststore.secure_password

Use identical passwords on all nodes in the cluster for proper inter-node communication.

Install the 'mapper-size' plugin

Purpose: To enable Elasticsearch to index the size of each document in bytes, which is required for storage management and reporting purposes.

  1. Open an elevated PowerShell window, navigate to Elasticsearch's bin folder (C:\elastic\elasticsearch-x.x.x\bin), and run the following command to install the 'mapper-size' plugin:

    Copy
    .\elasticsearch-plugin install mapper-size
  2. To verify the 'mapper-size' plugin is installed, run:

    Copy
    .\elasticsearch-plugin list
  3. Restart the Elasticsearch service by running the following command in an elevated PowerShell session:

    Copy
    Restart-Service -Name "elasticsearch-service-x64"
    Show sample output

    The output will look similar to:

    Copy
    WARNING: Waiting for service 'Elasticsearch x.x.x (elasticsearch-service-x64) (elasticsearch-service-x64)' to stop...

Configure JVM Heap Settings (Production)

Official Documentation: For detailed JVM configuration guidance, see Elastic's JVM heap size documentation.

Proper JVM heap configuration is critical for Elasticsearch performance and stability.

  • Navigate to C:\elastic\elasticsearch-x.x.x\config\jvm.options

  • Set heap size to 50% of available RAM, with a maximum of 31GB per node:

    Show JVM heap configuration
    Copy
    # Xms represents the initial heap size
    # Xmx represents the maximum heap size
    # Both values should be equal to avoid heap resizing

    -Xms16g
    -Xmx16g

    Production Sizing Guidelines:

    • For 32GB RAM server: -Xms16g -Xmx16g
    • For 64GB RAM server: -Xms31g -Xmx31g (do not exceed 31GB)
    • For 128GB RAM server: -Xms31g -Xmx31g (leave remainder for OS and Lucene)
  • Never set heap size above 31GB (compressed OOPs threshold)
  • Always set Xms and Xmx to the same value
  • Reserve at least 50% of RAM for the operating system and Lucene file cache
  • Monitor heap usage and adjust based on actual workload
  • Restart the Elasticsearch service after making changes:
Copy
Restart-Service -Name "elasticsearch-service-x64"

Verify Elasticsearch Server

  1. To verify Elasticsearch is running, open an elevated Command Prompt and run the following command (replace <username>, <password>, and <hostname_or_ip> with your actual values). In production, do NOT use -k; validate the server certificate using the CA certificate you installed:

    Copy
    curl.exe -u <username>:<password> --cacert "C:\elastic\elasticsearch-x.x.x\config\certs\http_ca.crt" --ssl-no-revoke https://<hostname_or_ip>:9200

    Or with PowerShell (validates TLS by default):

    Copy
    Invoke-RestMethod -Uri https://<hostname_or_ip>:9200 -Credential (Get-Credential)

Browser Access: While you can navigate to https://<hostname_or_ip>:9200 in a browser, authentication may not work reliably in all browsers. The curl or PowerShell methods above are recommended for consistent results.

  1. The response should show basic cluster information in JSON format if the server is running and accessible.

    Sample JSON response
    Copy
    {
    "name" : "emttest",
    "cluster_name" : "elasticsearch",
    "cluster_uuid" : "q5VtYDCQT2iNHU9dOdqomw",
    "version" : {
        "number" : "8.x.x",
        "build_flavor" : "default",
        "build_type" : "zip",
        "build_hash" : "a091390de485bd4b127884f7e565c0cad59b10d2",
        "build_date" : "2025-02-28T10:07:26.089129809Z",
        "build_snapshot" : false,
        "lucene_version" : "9.12.0",
        "minimum_wire_compatibility_version" : "7.17.0",
        "minimum_index_compatibility_version" : "7.0.0"
    },
    "tagline" : "You Know, for Search"
    }
Return to top of the page
Feedback