Skip to content

Instantly share code, notes, and snippets.

@tomwwright
Created December 6, 2022 00:26
Show Gist options
  • Save tomwwright/e8e21a82ab3eaba085b2c84aa9b89fa2 to your computer and use it in GitHub Desktop.
Save tomwwright/e8e21a82ab3eaba085b2c84aa9b89fa2 to your computer and use it in GitHub Desktop.
Script to create a change set against a stack and execute it if it is exclusively Tags in scope
#!/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 "$@"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment