Simplify Elasticsearch and Kibana Installation

On this page

Why, You Ask?

Setting up Elasticsearch and Kibana involves the same steps each time: update the system, configure repositories, install packages, and apply the initial configuration. I wrote a script to automate that work and make the setup reusable.

It's time-consuming and frustrating. I'm tired of it.

Automating the Setup

This Bash script installs Elasticsearch and Kibana as a single-node cluster. I use it when I need a small, repeatable setup without adding another configuration tool.

Why Choose a Bash Script?

I chose Bash instead of Ansible because the script also works well with cloud-init and inside Docker environments. It has no extra tooling requirements and is easy to copy to a new machine.

Building the Script: A Step-by-Step Guide

Let's walk through the crafting of the script that automates setting up Elasticsearch and Kibana. Here's how I pieced it together, one step at a time:

  1. Checking for Superuser Privileges The script needs administrative access, so it starts by checking for root privileges.
if [ "$(id -u)" != "0" ]; then
   echo "This script must be run as root" 1>&2
   exit 1
fi
  1. Updating the System and Installing Essential Packages Updating the system first helps avoid installation problems caused by outdated packages.
apt update
apt install -y apt-transport-https gnupg curl jq
  1. Adding the Elasticsearch Repository Getting this right is like picking the perfect ingredients for a master chef recipe - it ensures the rest of the meal turns out just right.

  2. Installing Elasticsearch and Kibana Next, the script installs Elasticsearch and Kibana.

  3. Configuring and Starting Services The plot thickens! Setting up the services and getting them running is like reaching the climax of our story - where all elements come together to unveil the full potential of our setup.

Rather than churn out another cookie-cutter guide on setting up Elasticsearch and Kibana, you can view the complete script here. However, I do want to emphasize the initial configuration process involving enrollment tokens and security settings. I've automated these aspects because, let's face it, I've read too many guides that suggest just turning off security for the sake of simplicity. That's not my style - I'd rather keep things secure automatically. It's not rocket science, but it sure is critical. Why simplify by compromising security when you can automate it effectively, right?

This approach ensures you get the functionality you need without the hassle of manual setup or the risks of disabled security.

Perfecting the Automation: Securing and Finalizing the Setup

The final part configures security and leaves both services ready to use.

  1. Broadcasting the Good News First things first, let's make sure any user logging into the system knows what's been accomplished:
echo -e "=== init-vm.sh: Initial ===" >> /etc/motd
echo -e "[> Elasticsearch 'elastic' password: $ELASTIC_PASSWORD" >> /etc/motd
echo -e "[> Test instance with 'curl -k -X GET https://elastic:$ELASTIC_PASSWORD@localhost:9200'" >> /etc/motd
echo -e "=== init-vm.sh: Get started ===" >> /etc/motd
echo -e "[> Reset 'elastic' password with '/usr/share/elasticsearch/bin/elasticsearch-reset-password -u elastic'." >> /etc/motd

Here, we're updating the message of the day (MOTD) file to ensure anyone who logs in is immediately informed about how to interact with Elasticsearch and what steps to take next. It's like leaving a note on the fridge - impossible to ignore and incredibly helpful.

  1. Decoding the Secrets Automation isn't just about doing things without human intervention; it's also about doing them securely and wisely:
# Because who likes doing setup manually, right?
decoded_token=$(echo $KIBANA_ENROLLMENT_TOKEN | base64 --decode)
address=$(echo $decoded_token | jq -r '.adr[0]')
fingerprint=$(echo $decoded_token | jq -r '.fgr')
api_key=$(echo $decoded_token | jq -r '.key')

Decoding the enrollment token reveals the essential elements needed to securely configure Kibana: the address, fingerprint, and API key.

Harnessing Version and Build Information Knowing exactly which version and build of Kibana you're working with is required for the API, so let's get that:

ver=$(jq -r '.version' /usr/share/kibana/package.json)
build=$(jq -r '.build.number' /usr/share/kibana/package.json)
  1. Re-encoding and Verification Secrecy is paramount, and so is verification. Here's how we handle both:
encoded_api_key=$(echo -n $api_key | base64)
output=$(sudo /usr/share/kibana/bin/kibana-verification-code)
verification_code=$(echo $output | awk -F": " '{print $2}' | sed 's/ //g')

The API key needs to be re-encoded to maintain security, and we also extract a verification code necessary for the next step - enrolling Kibana.

The Final Act: Enrolling Kibana

And now, the final piece of our automation puzzle:

curl -k -v -X POST "http://localhost:5601/internal/interactive_setup/enroll" \
     -H "Accept: */*" \
     -H "Content-Type: application/json" \
     -H "Host: localhost:5601" \
     -H "Origin: http://localhost:5601" \
     -H "Referer: http://localhost:5601/" \
     -H "kbn-build-number: $build" \
     -H "kbn-version: $ver" \
     -H "x-elastic-internal-origin: Kibana" \
     -H "x-kbn-context: %7B%22type%22%3A%22application%22%2C%22name%22%3A%22interactiveSetup%22%2C%22url%22%3A%22%2F%22%7D" \
     -d '{"hosts":["https://'$address'"],"apiKey":"'$encoded_api_key'","caFingerprint":"'$fingerprint'","code":"'$verification_code'"}'

This curl command not only sends all the needed parameters to Kibana for configuration but also uses the verification code to ensure that the setup is both authorized and secure. It's akin to dotting the i's and crossing the t's in our setup script.

Summary

The script turns a fresh system into a secured, working Elasticsearch and Kibana installation. Feel free to adapt it to your own environment.

Check out the complete script here:

Happy automating, and here's to many insightful data explorations!

P.S.: This script is tailored for automating development environments. Remember, a single-node cluster isn’t suited for production use, and storing passwords in the message of the day (MOTD) file? That’s a no-go for serious deployments. 😏