blog 2.26 KB
#!/usr/bin/env bash

set -euo pipefail

declare -r stack_name="blog"
declare -r region="eu-west-1"

usage() {
	echo "${0} COMMAND [options] [arguments]"
	echo
	echo "deploy  -- deploy clouformation changes"
	echo "status  -- show clouformation status"
	echo "ns      -- print NS records"
	echo "destroy -- Delete stack"
	echo "outputs -- Print cloudformation outputs"
	echo "url     -- Print URL"
}

cloudformation() {
	aws --region "${region}" cloudformation "$@"
}

s3() {
	aws --region "${region}" s3 "$@"
}

deploy() {
	if cloudformation describe-stacks --stack-name "${stack_name}" &> /dev/null ; then
		declare output update_status
		# NOTE: temporarily unset -e. This is because the update-stack
		# call fails if there is nothing to do. This case must be captured
		# and handled appropriately based on output.
		set +e
		output="$(cloudformation update-stack \
			--stack-name "${stack_name}" \
			--template-body "file://cloudformation.json" 2>&1)"
		update_status=$?
		set -e

		if echo "${output}" | grep -qF 'No updates'; then
			echo "CloudFormation stack up-to-date"
			return 0
		else
			return $update_status
		fi
	else
		cloudformation create-stack \
			--stack-name "${stack_name}" \
			--template-body "file://cloudformation.json"
	fi
}

destroy() {
	cloudformation delete-stack --stack-name "${stack_name}"
}

show_status() {
	cloudformation describe-stacks \
		--stack-name "${stack_name}" \
		| jq -re '.Stacks[0].StackStatus'
}

validate_stack() {
	cloudformation validate-template \
		--template-body "file://cloudformation.json"
}

show_outputs() {
	cloudformation describe-stacks --stack-name "${stack_name}" \
		| jq -re '.Stacks[0].Outputs | map("\(.OutputKey): \(.OutputValue)") | .[]'
}

publish() {
	declare bucket
	bucket="$(show_outputs | grep -iF 'bucket' | cut -d ' ' -f 2)"
	s3 sync dist "s3://${bucket}/" --delete
}

show_url() {
	show_outputs | grep -F 'PublicURL' | cut -d ' ' -f 2
}

main() {
	case "${1:-}" in
		deploy)
			shift
			deploy "$@"
			;;
		destroy)
			shift
			destroy "$@"
			;;
		status)
			shift
			show_status "$@"
			;;
		validate)
			shift
			validate_stack "$@"
			;;
		outputs)
			shift
			show_outputs "$@"
			;;
		url)
			shift
			show_url "$@"
			;;
		publish)
			shift
			publish "$@"
			;;
		*)
			usage 1>&2
			return 1
			;;
	esac
}

main "$@"