#!/usr/bin/env bash set -e if [ -z $PROJECT_NAME ]; then echo "PROJECT_NAME environment variable is not set." exit 1 fi if [ -z $AWS_ACCOUNT_ID ]; then echo "AWS_ACCOUNT_ID environment variable is not set." exit 1 fi if [ -z $AWS_DEFAULT_REGION ]; then echo "AWS_DEFAULT_REGION environment variable is not set." exit 1 fi if [ -z $ENVOY_IMAGE ]; then echo "ENVOY_IMAGE environment variable is not set to App Mesh Envoy, see https://docs.aws.amazon.com/app-mesh/latest/userguide/envoy.html" exit 1 fi if [ -z $KEY_PAIR ]; then echo "KEY_PAIR environment variable is not set. This must be the name of an SSH key pair, see https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-key-pairs.html" exit 1 fi AWS_CLI_VERSION=$(aws --version 2>&1 | cut -d/ -f2 | cut -d. -f1) DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)" ECR_URL="${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_DEFAULT_REGION}.amazonaws.com" ECR_IMAGE_PREFIX=${ECR_URL}/${PROJECT_NAME} ecr_login() { if [ $AWS_CLI_VERSION -gt 1 ]; then aws ecr get-login-password --region ${AWS_DEFAULT_REGION} | \ docker login --username AWS --password-stdin ${ECR_URL} else $(aws ecr get-login --no-include-email) fi } deploy_images() { echo "Deploying Color Client and Color Server images to ECR..." ecr_login for app in color_server; do aws ecr describe-repositories --repository-name ${PROJECT_NAME}/${app} >/dev/null 2>&1 || aws ecr create-repository --repository-name ${PROJECT_NAME}/${app} >/dev/null docker build -t ${ECR_IMAGE_PREFIX}/${app} ${DIR}/${app} --build-arg GO_PROXY=${GO_PROXY:-"https://proxy.golang.org"} docker push ${ECR_IMAGE_PREFIX}/${app} done } deploy_infra() { echo "Deploying Cloud Formation stack: \"${PROJECT_NAME}-infra\" containing VPC and Cloud Map namespace..." aws cloudformation deploy \ --no-fail-on-empty-changeset \ --stack-name "${PROJECT_NAME}-infra"\ --template-file "${DIR}/infra.yaml" \ --capabilities CAPABILITY_IAM \ --parameter-overrides "ProjectName=${PROJECT_NAME}" "KeyPair=${KEY_PAIR}" } deploy_app() { echo "Deploying Cloud Formation stack: \"${PROJECT_NAME}-app\" containing ALB, ECS Tasks, and Cloud Map Services..." aws cloudformation deploy \ --no-fail-on-empty-changeset \ --stack-name "${PROJECT_NAME}-app" \ --template-file "${DIR}/app.yaml" \ --capabilities CAPABILITY_IAM \ --parameter-overrides "ProjectName=${PROJECT_NAME}" "EnvoyImage=${ENVOY_IMAGE}" "ColorServerImage=${ECR_IMAGE_PREFIX}/color_server" } deploy_mesh() { echo "Deploying Cloud Formation stack: \"${PROJECT_NAME}-mesh\"..." aws cloudformation deploy \ --no-fail-on-empty-changeset \ --stack-name "${PROJECT_NAME}-mesh" \ --template-file "${DIR}/mesh.yaml" \ --capabilities CAPABILITY_IAM \ --parameter-overrides "ProjectName=${PROJECT_NAME}" } print_bastion() { echo "Bastion endpoint:" ip=$(aws cloudformation describe-stacks \ --stack-name="${PROJECT_NAME}-infra" \ --query="Stacks[0].Outputs[?OutputKey=='BastionIp'].OutputValue" \ --output=text) echo "${ip}" } print_endpoint() { echo "Public endpoint:" endpoint=$(aws cloudformation describe-stacks \ --stack-name="${PROJECT_NAME}-app" \ --query="Stacks[0].Outputs[?OutputKey=='PublicEndpoint'].OutputValue" \ --output=text) prefix='http://' suffix=':80' echo "${endpoint#$prefix}$suffix" } deploy_stacks() { deploy_images deploy_infra deploy_mesh deploy_app print_bastion print_endpoint } delete_cfn_stack() { stack_name=$1 echo "Deleting Cloud Formation stack: \"${stack_name}\"..." aws cloudformation delete-stack --stack-name $stack_name echo 'Waiting for the stack to be deleted, this may take a few minutes...' aws cloudformation wait stack-delete-complete --stack-name $stack_name echo 'Done' } delete_images() { for app in color_server; do echo "deleting repository \"${app}\"..." aws ecr delete-repository \ --repository-name $PROJECT_NAME/$app \ --force >/dev/null done } delete_stacks() { delete_cfn_stack "${PROJECT_NAME}-app" delete_cfn_stack "${PROJECT_NAME}-infra" delete_cfn_stack "${PROJECT_NAME}-mesh" delete_images echo "all resources from this tutorial have been removed" } action=${1:-"deploy"} if [ "$action" == "delete" ]; then delete_stacks exit 0 fi deploy_stacks