-
-
Save fizz/0563c32e824e2350ddb405d13bb48bb8 to your computer and use it in GitHub Desktop.
Find yourself creating the same AWS CFN stack a lot during testing? Wasting too much time repeating tags? Put your tags and params in json files and use this bash wrapper script to create the cloudformation stack. Provide your own template file, and modify the stackParams and stackTags to your own needs.
This file contains 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
# Create AWS CFN Stack - wrapper for `aws cloudformation create-stack` | |
#Example Usage: | |
[ $# -eq 0 ] && { echo -e "\nUsage `basename $0` <stack name> <CFN template file> <JSON parameters file> <JSON tags file>\n\nExample:\n`basename $0` mystackname MyCfn.template stackParams.json stackTags.json\n"; exit 1; } | |
#Inputs | |
stackName=${1?param missing - Stack Name} | |
templateFile=${2?param missing - Template File} | |
paramsFile=${3?param missing - Json Parameters file} | |
tagsFile=${4?param missing - Json Tags file} | |
if [ $# -gt 4 ]; then | |
echo 1>&2 "$0: too many arguments" | |
exit 1 | |
fi | |
#Functions | |
#------------------------------------------------------------------------------- | |
# Retrieve the status of a cfn stack | |
# | |
# Args: | |
# $1 The name of the stack | |
#------------------------------------------------------------------------------- | |
getStackStatus() { | |
aws cloudformation describe-stacks \ | |
--stack-name $1 \ | |
--query Stacks[].StackStatus \ | |
--output text | |
} | |
#------------------------------------------------------------------------------- | |
# Waits for a stack to reach a given status. If the stack ever reports any | |
# status other thatn *_IN_PROGRESS we will return failure status, as all other | |
# statuses that are not the one we are waiting for are considered terminal | |
# | |
# Args: | |
# $1 Stack name | |
# $2 The stack status to wait for | |
#------------------------------------------------------------------------------- | |
waitForState() { | |
local status | |
status=$(getStackStatus $1) | |
while [[ "$status" != "$2" ]]; do | |
echo "Waiting for stack $1 to obtain status $2 - Current status: $status" | |
# If the status is not one of the "_IN_PROGRESS" status' then consider | |
# this an error | |
if [[ "$status" != *"_IN_PROGRESS"* ]]; then | |
exitWithErrorMessage "Unexpected status '$status'" | |
fi | |
status=$(getStackStatus $1) | |
sleep 5 | |
done | |
echo "Stack $1 obtained $2 status" | |
} | |
#------------------------------------------------------------------------------- | |
# Returns content of JSON file containing params or tags | |
# Strips out all spaces, newlines etc. for input to aws cli command | |
# Spaces you want in Values should be encoded. e.g. | |
# {"Key":"Project","Value":"My\u0020Text"} | |
# | |
# Args: | |
# $1 Path to json file of parameters | |
#------------------------------------------------------------------------------- | |
getJsonFileContents() { | |
json=$(awk -v ORS= -v OFS= '{$1=$1}1' ${1}) | |
echo "$json" | |
} | |
#------------------------------------------------------------------------------- | |
# Exit the program with error status 1. | |
# | |
# Args: | |
# $1 Error message to display when exiting | |
#------------------------------------------------------------------------------- | |
exitWithErrorMessage() { | |
echo "ERROR: $1" | |
exit 1 | |
} | |
#------------------------------------------------------------------------------- | |
# Returns a file URL for the given path | |
# | |
# Args: | |
# $1 Path | |
#------------------------------------------------------------------------------- | |
getFileUrl() { | |
if [[ "$(uname -s)" == "Linux"* ]]; then | |
# The real thing | |
echo "file://${1}" | |
elif [[ "$(uname -s)" == "MINGW"* ]]; then | |
# Git Bash Hack | |
echo "file://${1:1:1}:${1:2}" | |
else | |
# Mac OS X Hack | |
echo "file:///${1}" | |
fi | |
} | |
#Create Stack | |
aws cloudformation create-stack \ | |
--capabilities CAPABILITY_IAM \ | |
--disable-rollback \ | |
--parameters $(getJsonFileContents ${paramsFile}) \ | |
--tags $(getJsonFileContents ${tagsFile}) \ | |
--stack-name ${stackName} \ | |
--template-body $(getFileUrl ${templateFile}) | |
if ! [ "$?" = "0" ]; then | |
exitWithErrorMessage "Cannot create stack ${stackName}!" | |
fi | |
#Wait for completion | |
waitForState ${stackName} "CREATE_COMPLETE" |
This file contains 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
[ | |
{"ParameterKey": "AMI", "ParameterValue": "ami-d5b59eb6"}, | |
{"ParameterKey": "VPC", "ParameterValue": "vpc-12345678"}, | |
{"ParameterKey": "AZaSubnet", "ParameterValue": "subnet-a1b2c3d4"}, | |
{"ParameterKey": "AZbSubnet", "ParameterValue": "subnet-1a2b3c4d"}, | |
{"ParameterKey": "ECSKey", "ParameterValue": "MyKey"}, | |
{"ParameterKey": "InstanceType", "ParameterValue": "t2.micro"} | |
] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment