Last active
May 26, 2020 06:24
-
-
Save qoomon/d6633abe35eea297f475260478f86c8c to your computer and use it in GitHub Desktop.
Watch CloudFormation Events during `aws cloudformation deploy`
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
set -o errexit # exit when a command line fails | |
set -o pipefail # pipes exit code will be the last non-zero exit code of all pipe commands | |
set -o nounset # exit on read a undeclared variable | |
#set -o xtrace # enable debug logging | |
#### Source: https://gist.github.com/qoomon/d6633abe35eea297f475260478f86c8c | |
### Usage ### | |
# | |
# aws cloudformation deploy --stack-name "$STACK_NAME" ... \ | |
# | ./aws-cloudformation-deploy-watcher.sh --stack-name "$STACK_NAME" ... | |
# | |
############# | |
WATCH_TIMEOUT=$(( 60 * 15 )) # in seconds | |
WATCH_INTERVAL=2 # in seconds | |
function echo_help { | |
echo "usage: $0 [options]" | |
echo "" | |
echo "example: aws cloudformation deploy ... | $0 [options]" | |
echo "" | |
echo "options:" | |
echo " --stack-name" | |
echo " --profile" | |
echo " --region" | |
echo " --help" | |
} | |
function reverse { sed '1!G;h;$!d'; } | |
while [[ $# -gt 0 ]] | |
do | |
case $1 in | |
--stack-name) opt_stack_name="$2"; shift 2;; | |
--profile) opt_profile="$2"; shift 2;; | |
--region) opt_region="$2"; shift 2;; | |
--help) echo_help; exit 0;; | |
*) | |
>&2 echo "[ERROR] unexpected argument: $1" | |
>&2 echo_help | |
exit 1;; | |
esac | |
done | |
if [[ ! "${opt_stack_name:-}" ]] | |
then | |
>&2 echo "[ERROR] '--stack-name' parameter missing" | |
>&2 echo_help | |
exit 1 | |
fi | |
while read -r line | |
do | |
echo "${line}" | |
if [[ "${line}" = "Waiting for stack create/update to complete" ]] | |
then | |
echo | |
start_watch_time=$(date +%s) | |
while [[ $(( $(date +%s) - $start_watch_time )) -lt WATCH_TIMEOUT ]] | |
do | |
sleep $WATCH_INTERVAL | |
prior_deploy_events="${recent_deploy_events:-}" | |
# get recent stack events since last 'User Initiated' change | |
recent_deploy_events="$(aws cloudformation describe-stack-events --stack-name "${opt_stack_name}" \ | |
${opt_profile:+ --profile "${opt_profile}"} \ | |
${opt_region:+ --region "${opt_region}"} \ | |
--query 'StackEvents[*].[Timestamp,ResourceType,LogicalResourceId,ResourceStatus,ResourceStatusReason]' --output text \ | |
| awk "NR==1,/\tAWS::CloudFormation::Stack\t${opt_stack_name}\t.*\tUser Initiated\$/" \ | |
| reverse)" | |
# determine new events | |
new_deploy_events="$(comm -13 <(echo "${prior_deploy_events}") <(echo "${recent_deploy_events}"))" | |
if [ -n "$new_deploy_events" ] | |
then | |
printf '\r' | |
# print new event | |
echo "${new_deploy_events}" \ | |
| awk -F '\t' '{printf "%s %-32s %-32s %-24s %s\n",$1,$2,$3,$4,$5}' \ | |
| sed 's/None$//' | |
TAB_CHAR=$'\t' | |
# check for final ERROR state | |
if (echo "${new_deploy_events}" | grep -q "AWS::CloudFormation::Stack${TAB_CHAR}${opt_stack_name}${TAB_CHAR}.*\(_ROLLBACK_COMPLETE|_FAILED\)${TAB_CHAR}") | |
then | |
exit_code=1 | |
break | |
fi | |
# check for final Success state | |
if (echo "${new_deploy_events}" | grep -q "AWS::CloudFormation::Stack${TAB_CHAR}${opt_stack_name}${TAB_CHAR}.*\(_COMPLETE\)${TAB_CHAR}") | |
then | |
exit_code=0 | |
break | |
fi | |
else | |
printf '.' | |
fi | |
done | |
echo | |
fi | |
done | |
exit ${exit_code:-0} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment