addCiarpame: Automate your K8s configuration automation

Context: Spring microservice application to be deployed on K8s via helm + boring Friday

In this scenario, you end up writing the SAME configuration string in a lot of places:

  1. On at least 2 application.properties (main and test)
  2. On the final, helm-generated application properties (or in the relevant environment variable if you use them in place (1))
  3. On the default K8s values.yaml used by helm. Possibly on other yaml file too, all documented a bit to be kindly with the K8s SRE.
  4. On the relevant Java code, as a @Value annotation to finally use that damn config.
These configuration are not particular exciting: they are all similar, some case can change but, really, ChatGPT could do it for you. If you have 4 parameters, you end up losing half an hour to do everything and test it. We can do better, for sureTM

So, I engineered a small script to add ConfIgurAtion Relative to Project AMEnding config files, called addCiarpame for brevity.

Ciarpame is also an Italian word meaning "rubbish", which for sure it's just a coincidence :)

Ciarpame is not a finalized script, it is  just a proof-of-concept to show how to automate this needs: time taken for this script was about half an hour :) and you can do your own version in python, bash, lua, java, etc if you like (even better: put it in the comments your version).

A full automated solution should also be able to UPDATE the value or DELETE if if needed: a job for a perl script, if you are able to learn it.

#!/usr/bin/env bash

# Keep script in the root of your fantastic project
SCRIPT_DIR=$(dirname $(realpath "$0"))
cd $SCRIPT_DIR
set -euo pipefail

if [ "$#" != 3 ] ; then
  echo "add ConfIgurAtion Relative to Project AMEnding files: addCiarpame"
  echo "Usage: $0 property default_value comment"
  echo "Example:"
  echo "./sh/addCiarpame.sh atomic_timeout_hours 10 'joking'"
fi

property="$1"
default_value="$2"
comment="$3"


# skynet.monitoring.cron=\{\{ .Values.app.monitoringCron \}\}
helmValue="$(echo $property | tr '[:upper:]' '[:lower:] | tr -d _ ' | sed 's/^[A-Z]/\\L&/')"
appProp="skynet.$helmValue=\{\{  .Values.app.$helmValue \}\}"
if grep $helmValue helm/*/application.properties ; then
  echo "WARN: Value already defined in application property: cannot proceed"
  exit 1
fi

echo $appProp >>helm/*/application.properties
# Create the default for devs
echo "skynet.${helmValue}=${default_value}" >>src/main/resources/application.properties
echo "skynet.${helmValue}=${default_value}" >>src/test/resources/application.properties
# Update the values...(tabs are important, because it is below the app: hierarchy)
# It should ends below the skynet: declaration
cat  >>helm/*/values.yaml <<EOF

  # $comment
  ${helmValue}: ${default_value}
EOF

# Also check if we are friends
helm template test helm/project -f helm/project/values.yaml  | grep $helmValue

echo "Syntax to link to Spring java code (copy & paste where relevant)"
echo "@Value(\\"\\${skynet.$helmValue}\\")"