Skip to content

Instantly share code, notes, and snippets.

@davidporter-id-au
Last active October 20, 2016 21:32
Show Gist options
  • Save davidporter-id-au/77b8aa20eeb4b0720ffba328173373bd to your computer and use it in GitHub Desktop.
Save davidporter-id-au/77b8aa20eeb4b0720ffba328173373bd to your computer and use it in GitHub Desktop.
#!/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