Last active
October 20, 2016 21:32
-
-
Save davidporter-id-au/77b8aa20eeb4b0720ffba328173373bd to your computer and use it in GitHub Desktop.
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
#!/bin/bash -e | |
REGION="ap-southeast-2" | |
function waitForStack { | |
# to avoid a race condition with AWS, wait a moment for the build to start | |
sleep 4 | |
TIMEOUT_IN_SECONDS=600 | |
START=$(date +%s) | |
TIMEOUT=$(($START + $TIMEOUT_IN_SECONDS)) | |
stackName=$1 | |
echo "Waiting for Stack: $stackName" | |
while [[ 1 ]]; do | |
# check stack exists: | |
CODE=$(echo $(aws cloudformation describe-stacks --stack-name $stackName &> /dev/null ) $?) | |
if [[ $CODE -eq 255 ]]; then | |
echo "Stack Deleted." | |
exit 1 | |
fi | |
stackStatus=$(aws cloudformation describe-stacks --region $REGION --output text \ | |
--stack-name $stackName --query "Stacks[0].StackStatus" | sed -e 's/^"//' -e 's/"$//') | |
echo "StackStatus: $stackStatus" | |
if echo $stackStatus | grep -i 'rollback'; then | |
echo "stack creation failed: $stackStatus" | |
echo "========================= Stack Events ==============================" | |
aws cloudformation describe-stack-events --stack-name $stackName | jq '.StackEvents[].ResourceStatusReason | select (. != null)' -r | |
echo "=====================================================================" | |
exit 1 | |
elif echo $stackStatus | grep -i 'fail'; then | |
echo "stack creation failed: $stackStatus" | |
exit 1 | |
elif [[ "$stackStatus" == "CREATE_COMPLETE" ]]; then | |
echo "stack creation completed successfully" | |
break | |
elif [[ "$stackStatus" == "UPDATE_COMPLETE" ]]; then | |
echo "stack update completed successfully" | |
break | |
fi | |
if [[ $(date +%s) -gt $TIMEOUT ]]; then | |
echo 'Timeout exceeded. Failure to deploy stack' | |
exit 1 | |
fi | |
# Sleep for 5 seconds, if stack creation in progress | |
sleep 5 | |
done | |
} | |
if [[ $# -ne 1 ]]; then | |
echo "A mongoose-deploy compatable cloudformation tool" | |
echo "" | |
echo "Usage: $0 <upsert/delete>" | |
exit 1 | |
fi | |
# Parse parameters | |
accountNumber=$(aws sts get-caller-identity --output text --query 'Account') | |
config=$(python -c 'import sys, yaml, json; json.dump(yaml.load(sys.stdin), sys.stdout, indent=4)' < mongoose.yaml) | |
stackName=$(echo $config | jq 'keys[0]' -r) | |
cfnParameters=$(echo $config | jq ".[\"$stackName\"].parameters | .[\"$accountNumber\"]" -r) | |
templatePath=$(echo $config | jq ".[\"$stackName\"] | .[\"template-path\"]" -r) | |
paramKeys=$(echo $cfnParameters | jq 'keys[]' -r) | |
parameters='--parameters ' | |
# format the parameters in the stupid array style required by the CLI | |
for key in $paramKeys; do | |
paramValue=$(echo $cfnParameters | jq ".$key" -r) | |
parameters=$(echo "$parameters ParameterKey=$key,ParameterValue=$paramValue") | |
done | |
if [[ "$1" == "upsert" ]]; then | |
if [[ "$(aws cloudformation describe-stacks --stack-name $stackName 2> /dev/null | jq '.Stacks | length')" -eq 0 ]]; then | |
echo "Stack does not exist" | |
echo aws cloudformation create-stack \ | |
--stack-name "$stackName" \ | |
--capabilities CAPABILITY_IAM \ | |
--capabilities CAPABILITY_NAMED_IAM \ | |
--template-body "file://$templatePath" \ | |
"$parameters" | bash | |
else | |
echo "Stack exists" | |
echo aws cloudformation update-stack \ | |
--stack-name "$stackName" \ | |
--capabilities CAPABILITY_IAM \ | |
--capabilities CAPABILITY_NAMED_IAM \ | |
--template-body "file://$templatePath" \ | |
"$parameters" | bash # Wooo! like lisp | |
fi | |
waitForStack $stackName | |
elif [[ $1 == "delete" ]]; then | |
if [[ "$(aws cloudformation describe-stacks --stack-name $stackName 2> /dev/null | jq '.Stacks | length')" -eq 0 ]]; then | |
echo "Stack does not exist" | |
exit 0 | |
else | |
echo "Stack exists" | |
aws cloudformation delete-stack \ | |
--stack-name "$stackName" | |
waitForStack "$stackName" | |
fi | |
elif [[ $1 == "show" ]]; then | |
if [[ "$(aws cloudformation describe-stacks --stack-name $stackName 2> /dev/null | jq '.Stacks | length')" -eq 0 ]]; then | |
echo "Stack does not exist" | |
exit 0 | |
else | |
aws cloudformation describe-stacks \ | |
--stack-name "$stackName" | |
fi | |
elif [[ $1 == "outputs" ]]; then | |
if [[ "$(aws cloudformation describe-stacks --stack-name $stackName 2> /dev/null | jq '.Stacks | length')" -eq 0 ]]; then | |
echo "Stack does not exist" | |
exit 0 | |
else | |
aws cloudformation describe-stacks \ | |
--stack-name "$stackName" | jq '.Stacks[0].Outputs' | |
fi | |
else | |
echo "Options are 'upsert', 'delete', 'show' or 'outputs'" | |
exit 1 | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment