shoc-backend/scripts/deploy-api-tf.sh

114 lines
4.1 KiB
Bash
Raw Normal View History

#!/usr/bin/env bash
#
# deploy-api-tf.sh — local Elastic Beanstalk publish for the Terraform POC.
# Refuses live names. GitHub Actions is the real CD path once the branch is
# pushed; this script exists only because GHA cannot run until then.
#
# Usage:
# export AWS_PROFILE=seahaven-external-dev
# bash scripts/deploy-api-tf.sh
set -euo pipefail
REGION="${AWS_REGION:-us-east-1}"
APPLICATION_NAME="shoc-backend-tf-poc"
ENVIRONMENT_NAME="shoc-backend-tf-poc"
SMOKE_URL="https://tf-poc.api.dev.seahaven.com"
S3_BUCKET="elasticbeanstalk-us-east-1-396287094661"
log() { printf '\n\033[1m== %s ==\033[0m\n' "$1"; }
die() { printf '\033[31mERR\033[0m %s\n' "$1" >&2; exit 1; }
[[ "${APPLICATION_NAME}" != "shoc-backend" ]] \
|| die "refusing live Elastic Beanstalk application shoc-backend"
[[ "${ENVIRONMENT_NAME}" != "shoc-backend-dev" ]] \
|| die "refusing live Elastic Beanstalk environment shoc-backend-dev"
[[ "${SMOKE_URL}" != "https://api.dev.seahaven.com" ]] \
|| die "refusing live hostname api.dev.seahaven.com"
command -v aws >/dev/null 2>&1 || die "aws CLI is required"
command -v curl >/dev/null 2>&1 || die "curl is required"
ACCOUNT="$(aws sts get-caller-identity --query Account --output text)"
[[ "${ACCOUNT}" == "396287094661" ]] \
|| die "refusing to deploy outside seahaven-external-dev (caller account ${ACCOUNT})"
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "$REPO_ROOT"
log "package source bundle"
bash scripts/package-elastic-beanstalk.sh
VERSION_LABEL="local-$(date -u +%Y%m%d%H%M%S)-${USER:-unknown}"
BUNDLE=".artifacts/elastic-beanstalk/site.zip"
KEY="shoc-backend-tf-poc/${VERSION_LABEL}.zip"
log "capture current environment version"
prev="$(aws elasticbeanstalk describe-environments \
--environment-names "${ENVIRONMENT_NAME}" \
--region "${REGION}" \
--query 'Environments[0].VersionLabel' \
--output text)"
echo "${prev}" > .artifacts/elastic-beanstalk/previous-version.txt
echo "Previous version label: ${prev}"
log "upload bundle ${KEY}"
aws s3 cp "${BUNDLE}" "s3://${S3_BUCKET}/${KEY}" --region "${REGION}"
log "create application version ${VERSION_LABEL}"
aws elasticbeanstalk create-application-version \
--application-name "${APPLICATION_NAME}" \
--version-label "${VERSION_LABEL}" \
--source-bundle "S3Bucket=${S3_BUCKET},S3Key=${KEY}" \
--region "${REGION}"
log "update environment ${ENVIRONMENT_NAME}"
aws elasticbeanstalk update-environment \
--environment-name "${ENVIRONMENT_NAME}" \
--version-label "${VERSION_LABEL}" \
--region "${REGION}"
log "wait until expected version is Ready"
status="Unknown"
current="Unknown"
health="Unknown"
for _ in $(seq 1 80); do
read -r status current health < <(
aws elasticbeanstalk describe-environments \
--environment-names "${ENVIRONMENT_NAME}" \
--region "${REGION}" \
--query 'Environments[0].[Status,VersionLabel,Health]' \
--output text
)
echo "environment status: ${status}; version: ${current}; health: ${health}"
if [ "${status}" = "Ready" ]; then
if [ "${current}" = "${VERSION_LABEL}" ] && { [ "${health}" = "Green" ] || [ "${health}" = "Yellow" ]; }; then
echo "Expected application version is Ready and healthy."
break
fi
die "Environment became Ready without activating expected version ${VERSION_LABEL}."
fi
sleep 15
done
[[ "${status}" = "Ready" ]] || die "Expected application version did not become Ready."
log "smoke ${SMOKE_URL}"
bash scripts/smoke-elastic-beanstalk.sh "${SMOKE_URL}"
log "webhook secret source"
response_file="$(mktemp)"
trap 'rm -f "$response_file"' EXIT
status_code="$(curl --silent --show-error \
--output "$response_file" \
--write-out '%{http_code}' \
--request POST \
--header 'Content-Type: application/json' \
--header "X-SH-Timestamp: $(date +%s)" \
--header 'X-SH-Key-Id: deployment-smoke-invalid-key' \
--header "X-SH-Signature: v1=$(printf '0%.0s' {1..64})" \
--data '{}' \
"${SMOKE_URL}/api/webhooks/work-orders")"
if [ "${status_code}" != "401" ]; then
die "Expected enabled webhook to reject the invalid probe with 401; received ${status_code}."
fi
echo "webhook HTTP 401"