|
#!/bin/bash |
|
set -e |
|
set -o pipefail |
|
set -u |
|
|
|
# depends on cfparams: https://github.com/cultureamp/cfparams |
|
|
|
FARM=$1 |
|
|
|
CHANGE_SET_NAME="changeset-tags-$(date +%Y%m%d%H%M%S)-$(git rev-parse HEAD)" |
|
STACK_NAME="$FARM-influx-db" |
|
|
|
main() { |
|
echo "[>] Creating change set" |
|
create_change_set |
|
echo "[+] Change set created" |
|
local status; status="$(check_change_set)" |
|
|
|
case $status in |
|
"EMPTY") |
|
echo "[+] Empty change set created" |
|
delete_change_set |
|
echo "[+] Change set discarded" |
|
exit 0 |
|
;; |
|
|
|
"TAGS") |
|
echo "[+] Change set contains ONLY 'Tags' scope" |
|
execute_change_set |
|
echo "[+] Stack update complete!" |
|
exit 0 |
|
;; |
|
|
|
"FAILED") |
|
echo "[!] Change set creation failed for a reason other than being empty" |
|
exit 1 |
|
;; |
|
|
|
"OTHER") |
|
echo "[!] Change set contains scopes other than 'Tags' -- not executing" |
|
exit 1 |
|
;; |
|
|
|
*) |
|
echo "[!] Unknown change set status -- not executing" |
|
exit 1 |
|
esac |
|
} |
|
|
|
get_current_parameters() { |
|
aws cloudformation get-template --stack-name="$STACK_NAME" | yq -P .TemplateBody > "stack-${CHANGE_SET_NAME}.json" |
|
cfparams --template "stack-${CHANGE_SET_NAME}.json" |
|
rm "stack-${CHANGE_SET_NAME}.json" |
|
} |
|
|
|
get_tags() { |
|
cat "tags-$FARM.json" |
|
} |
|
|
|
get_change_set() { |
|
aws cloudformation describe-change-set \ |
|
--stack-name "${STACK_NAME}" \ |
|
--change-set-name "${CHANGE_SET_NAME}" |
|
} |
|
|
|
create_change_set() { |
|
aws cloudformation create-change-set \ |
|
--stack-name="$STACK_NAME" \ |
|
--capabilities=CAPABILITY_IAM \ |
|
--use-previous-template \ |
|
--parameters="$(get_current_parameters)" \ |
|
--tags="$(get_tags)" \ |
|
--change-set-name="$CHANGE_SET_NAME" \ |
|
--query=Id --output=text |
|
|
|
aws cloudformation wait change-set-create-complete \ |
|
--stack-name="$STACK_NAME" \ |
|
--change-set-name="$CHANGE_SET_NAME" || echo "[!] Continuing..." |
|
} |
|
|
|
check_change_set() { |
|
local change_set; change_set="$(get_change_set)" |
|
local is_failed; is_failed=$(echo $change_set | jq '.Status == "FAILED"') |
|
|
|
if [ $is_failed = "true" ]; then |
|
local empty_status_reason; empty_status_reason="The submitted information didn't contain changes. Submit different information to create a change set." |
|
local is_empty; is_empty=$(echo $change_set | jq ".StatusReason == \"$empty_status_reason\"") |
|
if [ $is_empty = "true" ]; then |
|
echo "EMPTY" |
|
else |
|
echo "FAILED" |
|
fi |
|
else |
|
local is_tags; is_tags=$(echo $change_set | jq '[.Changes[].ResourceChange.Scope] | flatten | [.[] == "Tags"] | all') |
|
if [ $is_tags = "true" ]; then |
|
echo "TAGS" |
|
else |
|
echo "OTHER" |
|
fi |
|
fi |
|
} |
|
|
|
execute_change_set() { |
|
echo "[>] Executing change set" |
|
aws cloudformation execute-change-set \ |
|
--stack-name "${STACK_NAME}" \ |
|
--change-set-name "${CHANGE_SET_NAME}" |
|
|
|
echo "[>] Waiting for stack update" |
|
aws cloudformation wait stack-update-complete \ |
|
--stack-name "${STACK_NAME}" |
|
} |
|
|
|
delete_change_set() { |
|
echo "[>] Deleting change set" |
|
aws cloudformation delete-change-set \ |
|
--stack-name "${STACK_NAME}" \ |
|
--change-set-name "${CHANGE_SET_NAME}" |
|
} |
|
|
|
main "$@" |