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:
- On at least 2 application.properties (main and test)
- On the final, helm-generated application properties (or in the relevant environment variable if you use them in place (1))
- 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.
- On the relevant Java code, as a @Value annotation to finally use that damn config.
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}\\")"