-
-
Save mdjnewman/b9d722188f4f9c6bb277a37619665e77 to your computer and use it in GitHub Desktop.
| #!/usr/bin/env bash | |
| usage="Usage: $(basename "$0") region stack-name [aws-cli-opts] | |
| where: | |
| region - the AWS region | |
| stack-name - the stack name | |
| aws-cli-opts - extra options passed directly to create-stack/update-stack | |
| " | |
| if [ "$1" == "-h" ] || [ "$1" == "--help" ] || [ "$1" == "help" ] || [ "$1" == "usage" ] ; then | |
| echo "$usage" | |
| exit -1 | |
| fi | |
| if [ -z "$1" ] || [ -z "$2" ] || [ -z "$3" ] ; then | |
| echo "$usage" | |
| exit -1 | |
| fi | |
| shopt -s failglob | |
| set -eu -o pipefail | |
| echo "Checking if stack exists ..." | |
| if ! aws cloudformation describe-stacks --region $1 --stack-name $2 ; then | |
| echo -e "\nStack does not exist, creating ..." | |
| aws cloudformation create-stack \ | |
| --region $1 \ | |
| --stack-name $2 \ | |
| ${@:3} | |
| echo "Waiting for stack to be created ..." | |
| aws cloudformation wait stack-create-complete \ | |
| --region $1 \ | |
| --stack-name $2 \ | |
| else | |
| echo -e "\nStack exists, attempting update ..." | |
| set +e | |
| update_output=$( aws cloudformation update-stack \ | |
| --region $1 \ | |
| --stack-name $2 \ | |
| ${@:3} 2>&1) | |
| status=$? | |
| set -e | |
| echo "$update_output" | |
| if [ $status -ne 0 ] ; then | |
| # Don't fail for no-op update | |
| if [[ $update_output == *"ValidationError"* && $update_output == *"No updates"* ]] ; then | |
| echo -e "\nFinished create/update - no updates to be performed" | |
| exit 0 | |
| else | |
| exit $status | |
| fi | |
| fi | |
| echo "Waiting for stack update to complete ..." | |
| aws cloudformation wait stack-update-complete \ | |
| --region $1 \ | |
| --stack-name $2 \ | |
| fi | |
| echo "Finished create/update successfully!" |
Also useful as a workaround to serverless/serverless#2233 and serverless/serverless#2831.
The logic between lines 53 and 63 can be removed by simply adding --no-fail-on-empty-changeset to the aws cloudformation update-stack ... command.
Changed my mind - you actually do need separate logic for handling the case of "deploy to an existing stack, but there are no updates to apply". Consider a stack in CREATE_COMPLETE status, and we go to perform another deploy as an update. If we have no changes to apply, the stack will remain in CREATE_COMPLETE status, and we must not attempt to use aws cloudformation wait stack-update-complete because this command would hang forever. So I think the existing snippet is correct, and you should not use --no-fail-on-empty-changeset
Am getting the below error while trying to update the existing stack. What do I need to change in the script?
An error occurred (AlreadyExistsException) when calling the CreateStack operation: Stack [Test-stack] already exists
@viveksamaga I've not tested this since 2016 sorry, it's possible the AWS CLI has introduced some breaking changes
also deploy does not support rollback configuration