This is a script I've written to deploy the Elastic Stack.

Can you help me improve it? Especially the parts called out with *** markings.


#!/usr/bin/env bash
sudo sysctl -w vm.max_map_count=262144
#use the elastic utility to gen certs
docker-compose -f create-certs.yml run --rm create_certs
# Start the stack initially per Elastic documentation
docker-compose up -d
#run a password gen script to make some passwords
docker exec elasticsearch /bin/bash -c "bin/elasticsearch-setup-passwords \
auto --batch \
--url https://elasticsearch:9200" | tee es_passes.txt
#sub generated kibana and es passes into .env -> *** This could be better ***
cat es_passes.txt  | grep 'PASSWORD kibana' | awk '{print $4}' | xargs -I {} sed -r -i 's/(KIBANA_PASS=)\w/\1{}/gip' .env
cat es_passes.txt  | grep 'PASSWORD elastic' | awk '{print $4}' | xargs -I {} sed -r -i 's/(ES_PASS=)\w/\1{}/gip' .env
#eliminate duplicate lines -> *** How can I do this better ***
awk '!seen[$0]++' .env > .env_dedup
mv .env_dedup .env
#show the contents of .env
cat .env
#restart the stack after setting the passwords
docker-compose stop
docker-compose up -d



other files:

  • docker-compose.yml
  • create-certs.yml

update: I have fixed the substitution lines. They now read:

cat es_passes.txt  | grep 'PASSWORD kibana' | awk '{print $4}' | xargs -I {} sed -r -i 's/^KIBANA_PASS=.*$/KIBANA_PASS={}/' .env
cat es_passes.txt  | grep 'PASSWORD elastic' | awk '{print $4}' | xargs -I {} sed -r -i 's/^ES_PASS=.*$/ES_PASS={}/' .env
  • 2
    \$\begingroup\$ (Down-voters please comment.) You are right: "the cat|grep|awk|sed pipes" leave ample room for improvement. Let me add security concerns. \$\endgroup\$ – greybeard Mar 25 at 22:02
  • \$\begingroup\$ Not only is this deploy script piping everything here and there and saving passwords to plaintext files in the dir where it is deployed(!), it is also not functional :( The .env currently does not substitute the old password with the new completely. I end up with: ``` KIBANA_PASS=newly_genned_passsome_supersecure_kibana_pass ES_PASS=newly_genned_passsome_supersecure_elasticseach_pass ``` Fixing that now... \$\endgroup\$ – David West Mar 26 at 13:15
  • \$\begingroup\$ Please don't update the code in your question after answers come in. Feel free to ask a new question instead. \$\endgroup\$ – Mast Mar 26 at 14:25

Shots from the hip, three decades since I seriously programmed shell notwithstanding:

  • document your code - in the code.
    The comments presented are a good start - in the middle, irritatingly.
    What is the whole script useful for, how shall it be used?
    You can even have executable comments:
    if called incorrectly or with -h, --help (or even -?), print a
    Usage: to "standard error output"/file descriptor 2
    Then there are things left open:
    Why tee to es_passes.txt instead of redirect, have sed print the pattern space? (I read Spanish_passes at first - the reason why in the following comment es may be as appropriate as elastic needed horizontal scrolling)
  • with security related artefacts, assess security implications
  • choose the right tool
    this does not just depend on task at hand and tools available, but on "craftsperson", too
    (Here, I might have chosen perl in the 90ies and Python in the current millenium century)
  • the options and commands to sed speak of GNU sed
    • mention such in your question
    • consider using --posix
  • don't use cat | command where command allows specifying input file(s)
  • prefer using awks patterns over separate filtering (e.g.,grep)
    (unless input is massive):
    awk '/PASSWORD kibana|elastic/{print $4}' es_passes.txt …
    (not convinced piping to xargs -I is the way to proceed.)
  • the conventional "unix" way to eliminate duplicate lines is uniq, preceded with a sort where global uniqueness is necessary and altering line sequence admissible.
|improve this answer|||||

Your Answer

