I've written a small script that automates the tasks I previously did manually for deploying onto our kubernetes clusters and I am quite happy with the results I have, but I do think that what my approach was (building a command and executing it at the end) could probably be improved.
Especially the fn_magic part is something I dont know could be done better.
team="webdev"
project="sick-project"
registry="myfancyregistry"
tagPrefix="$registry/$team/$project"
namespace="webdev-dev"
kubectl="kubectl -n=$namespace"
declare -A NAME_TO_TAGS
declare COMMANDBUILDER
declare -A REPLACEMENTS
# Colors :)
RED='\033[0;31m'
GREEN='\033[0;32m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
function setReplacements() {
while IFS= read -r line
do
[ -z "$line" ] && continue
key=${line%%=*}
value=${line#*=}
REPLACEMENTS[$key]=$value
done < "${BASH_SOURCE%/*}/secrets"
}
function buildAndPush() {
function fn_magic() {
local dockerfile=$1
local name=$2
local context=$3
local tag=$(tar cf - --exclude='node_modules' $context | sha1sum | grep -o "\w*")
NAME_TO_TAGS["$name"]="$tag"
local output=$(docker images $tagPrefix/$project-$name:$tag | awk '{print $2}' | sed 1,1d)
printf "SHA1 for ${CYAN}$name${NC} is ${YELLOW}$tag${NC}.\n"
if [[ "$output" ]]; then
printf "Skipping building ${CYAN}$name${NC} because image already exists locally.\n"
COMMANDBUILDER="$COMMANDBUILDER && printf \"Pushing ${CYAN}$name${NC}.\n\" && docker push $tagPrefix/$project-$name:$tag"
return
fi
COMMANDBUILDER="$COMMANDBUILDER && printf \"Building ${CYAN}$name${NC}.\n\" && docker build -f dockerfiles/$dockerfile.dockerfile -t $tagPrefix/$project-$name:$tag $context"
COMMANDBUILDER="$COMMANDBUILDER && printf \"Pushing ${CYAN}$name${NC}.\n\" && docker push $tagPrefix/$project-$name:$tag"
return
}
local calls=(
"fn_magic ReactNginx frontend ./frontend"
"fn_magic DockerfileNode backend ./backend"
)
for call in "${calls[@]}"; do
eval $call
done
}
function deploy() {
local deployName="$1"
local tag="$2"
local filter=""
REPLACEMENTS[TAG]="$tag"
for key in "${!REPLACEMENTS[@]}"; do
local REPLACE=$(echo ${REPLACEMENTS[$key]} | sed -e 's/\\/\\\\/g; s/\//\\\//g; s/&/\\\&/g')
filter="$filter | sed \"s/{{$key}}/$REPLACE/g\""
done
COMMANDBUILDER="$COMMANDBUILDER && cat "${BASH_SOURCE%/*}/$deployName.yaml" $filter | $kubectl apply -f -"
}
setReplacements
buildAndPush
for name in "${!NAME_TO_TAGS[@]}"; do
deploy $name ${NAME_TO_TAGS[$name]}
done
COMMANDBUILDER="echo $COMMANDBUILDER"
eval "$COMMANDBUILDER"