AWS : automatisierter shutdown der aws instanzen

Problem : Man hat ein paar Instanzen in der AWS installiert, diese werden aber nur für die Entwicklung bzw. Tests benötigt. Um zusätzliche Kosten zu sparen kann man diese automatisiert außerhalb der benötigten Zeiten herunterfahren.

Lösung : Man lässt dieses Skript auf einer Maschine/Instanz laufen auf der die aws cli konfiguriert ist. Das Beispiel hier läuft selbst eine AWS Instanz. Aus diesem Grund wird mit
OWN_INSTANCE_ID=$(curl -s http://169.254.169.254/latest/meta-data/instance-id)
die eigene ID ermittelt.
Das Skript fährt alle Instanzen herunter außer diese die in DO_NOT_SHUTDOWN definiert sind.

#!/bin/bash
# ----------------------------------
set -o nounset
set -o pipefail
# ----------------------------------
#
# Script fährt alle Instanzen herunter bis auf die unter DO_NOT_SHUTDOWN definierten
# die eigene Maschine bleibt natürlich auch online
# PFAD zu awscli
AWS_PATH="/root/.local/bin/"
OWN_INSTANCE_ID=$(curl -s http://169.254.169.254/latest/meta-data/instance-id)
# -----------------------------------------------------------
# Definieren der Maschinen die NICHT heruntergefahren werden
# -----------------------------------------------------------
# wenn die eigene Instanz geschützt werden soll diese mit ins Array aufnehmen. Nur so ist gewährleistet das alles abgearbeitet wird
# z.B. declare -a DO_NOT_SHUTDOWN=("${OWN_INSTANCE_ID}" "i-xxxxxxxxxxxxx" "i-xxxxxxxxxxxxx" "i-xxxxxxxxxxxxx")
#
declare -a DO_NOT_SHUTDOWN=("${OWN_INSTANCE_ID}")
# -----------------------------------------------------------
# nichts mehr ändern
# -----------------------------------------------------------
LOG_PATH="$(dirname $(readlink -f $0))/logs"
LOG_FILE="$(date +%Y%m%d)-awscli.log"
# -----------------------------------------------------------
# Funktionen
# -----------------------------------------------------------
function is_inList ()
{
  SERVER=${1}
  max=${#DO_NOT_SHUTDOWN[@]}
  RET=1

  for ((i = 0 ; i < max ; i++ )); do
    if [ "${DO_NOT_SHUTDOWN[i]}" = "${SERVER}" ]; then
      RET=0
      break
    fi
  done

  return $RET
}
function logger () {
        mkdir -p ${LOG_PATH}
        if [ -z ${2} ]; then
                STATI="INFO"
        else
                STATI="${2}"
        fi
        echo "$(date +%Y-%m-%d) | $(date +%R) | ${STATI} | ${1}" >> ${LOG_PATH}/${LOG_FILE}
}
# -----------------------------------------------------------
# Prüfen ob OWN_INSTANCE_ID einen Wert enthält
# -----------------------------------------------------------
logger "Starte -> ${0##*/}" "INFO"
if [ -z ${OWN_INSTANCE_ID} ]; then
        logger "OWN_INSTANCE_ID ist leer Skript wird nicht gestartet" "ERROR"
        logger "Beende AWS Script" "ERROR"
        exit 99
fi

for item in $(${AWS_PATH}aws ec2 describe-instances --query 'Reservations[].Instances[][InstanceId,Tags[?Key==`Name`].Value | [0],LaunchTime,State.Name]' --filters "Name=instance-state-name,Values=running" --output text | awk '{print $1}')
do
        is_inList ${item}
        RET=$?
        if [ $RET -eq 0 ]; then
                logger "${item} wird nicht heruntergefahren definiert in OWN_INSTANCE_ID oder DO_NOT_SHUTDOWN" "INFO"
                continue
        else
                logger "${item} wird heruntergerfahren" "INFO"
                #----  aws cli fährt kiste herunter
                ${AWS_PATH}aws ec2 stop-instances --instance-ids ${item} > /dev/null 2>&1
        fi
done
logger "Beende -> ${0##*/}" "INFO"
exit 0


“Das einzig sichere System müsste ausgeschaltet, in einem versiegelten und von Stahlbeton ummantelten Raum und von bewaffneten Schutztruppen umstellt sein.”
Gene Spafford (Sicherheitsexperte)