From 29dd9ce2bdfb77207c826d402704862fec926eb6 Mon Sep 17 00:00:00 2001 From: eistrati Date: Fri, 26 Apr 2024 09:25:39 -0400 Subject: [PATCH] initial commit (#2) --- bin/deploy.sh | 112 +++++++++++++++++++++++++++++++++++++++++++++ bin/docker.sh | 122 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 234 insertions(+) create mode 100755 bin/deploy.sh create mode 100755 bin/docker.sh diff --git a/bin/deploy.sh b/bin/deploy.sh new file mode 100755 index 00000000..c21d3119 --- /dev/null +++ b/bin/deploy.sh @@ -0,0 +1,112 @@ +#!/bin/bash + +help() +{ + echo "Deploy AWS resource using Terraform and Terragrunt" + echo + echo "Syntax: deploy.sh [-a|-b|c|d|i|r|t]" + echo "Options:" + echo "a Specify AWS application ARN (e.g. arn:aws:resource-groups:us-east-1:123456789012:group/SPF/abcd1234)" + echo "b Specify Terraform backend config (e.g. {\"us-east-1\"=\"spf-backend-us-east-1\"})" + echo "c Specify cleanup / destroy resources (e.g. true)" + echo "d Specify directory (e.g. iac/cicd)" + echo "i Specify global id (e.g. abcd1234)" + echo "r Specify AWS region (e.g. us-east-1)" + echo "t Specify S3 bucket (e.g. spf-backend-us-east-1)" + echo +} + +set -o pipefail + +SPF_APP_ARN="" +SPF_REGION="" +SPF_BUCKET="" +SPF_BACKEND="" +SPF_GID="" +SPF_DIR="iac/cicd" +CLEANUP="" + +while getopts "h:a:b:c:d:i:r:t:" option; do + case $option in + h) + help + exit;; + a) + SPF_APP_ARN="$OPTARG";; + b) + SPF_BACKEND="$OPTARG";; + c) + CLEANUP="$OPTARG";; + d) + SPF_DIR="$OPTARG";; + i) + SPF_GID="$OPTARG";; + r) + SPF_REGION="$OPTARG";; + t) + SPF_BUCKET="$OPTARG";; + \?) + echo "[ERROR] invalid option" + echo + help + exit;; + esac +done + +aws --version > /dev/null 2>&1 || { echo "[ERROR] aws is missing. aborting..."; exit 1; } +terraform -version > /dev/null 2>&1 || { echo "[ERROR] terraform is missing. aborting..."; exit 1; } +terragrunt -version > /dev/null 2>&1 || { echo "[ERROR] terragrunt is missing. aborting..."; exit 1; } + +if [ -z "${SPF_REGION}" ] && [ ! -z "${AWS_DEFAULT_REGION}" ]; then SPF_REGION="${AWS_DEFAULT_REGION}"; fi +if [ -z "${SPF_REGION}" ] && [ ! -z "${AWS_REGION}" ]; then SPF_REGION="${AWS_REGION}"; fi + +if [ -z "${SPF_REGION}" ]; then + echo "[DEBUG] SPF_REGION: ${SPF_REGION}" + echo "[ERROR] SPF_REGION is missing..."; exit 1; +fi + +if [ -z "${SPF_BUCKET}" ]; then + echo "[DEBUG] SPF_BUCKET: ${SPF_BUCKET}" + echo "[ERROR] SPF_BUCKET is missing..."; exit 1; +fi + +if [ -z "${SPF_BACKEND}" ]; then + SPF_BACKEND={\"${SPF_REGION}\"=\"${SPF_BUCKET}\"} +fi + +WORKDIR="$( cd "$(dirname "$0")/../" > /dev/null 2>&1 || exit 1; pwd -P )" +OPTIONS="-var backend_bucket=${SPF_BACKEND}" + +if [ ! -z "${SPF_GID}" ]; then + OPTIONS="${OPTIONS} -var spf_gid=${SPF_GID}" +fi + +if [ ! -z "${SPF_ACCOUNT}" ]; then + OPTIONS="${OPTIONS} -var account=${SPF_ACCOUNT}" +fi + +if [ ! -z "${SPF_APP_ARN}" ]; then + OPTIONS="${OPTIONS} -var app_arn=${SPF_APP_ARN}" +fi + +if [ ! -d "${WORKDIR}/${SPF_DIR}/" ]; then + echo "[DEBUG] SPF_DIR: ${SPF_DIR}" + echo "[ERROR] ${WORKDIR}/${SPF_DIR}/ does not exist..."; exit 1; +fi + +echo "[EXEC] cd ${WORKDIR}/${SPF_DIR}/" +cd "${WORKDIR}/${SPF_DIR}/" + +echo "[EXEC] terragrunt run-all init -backend-config region=${SPF_REGION} -backend-config bucket=${SPF_BUCKET}" +terragrunt run-all init -backend-config region="${SPF_REGION}" -backend-config="bucket=${SPF_BUCKET}" || { echo "[ERROR] terragrunt run-all init failed. aborting..."; cd -; exit 1; } + +if [ ! -z "${CLEANUP}" ] && [ "${CLEANUP}" == "true" ]; then + echo "[EXEC] terragrunt run-all destroy -auto-approve -var-file default.tfvars ${OPTIONS}" + echo "Y" | terragrunt run-all destroy -auto-approve -var-file default.tfvars ${OPTIONS} || { echo "[ERROR] terragrunt run-all destroy failed. aborting..."; cd -; exit 1; } +else + echo "[EXEC] terragrunt run-all apply -auto-approve -var-file default.tfvars ${OPTIONS}" + echo "Y" | terragrunt run-all apply -auto-approve -var-file default.tfvars ${OPTIONS} || { echo "[ERROR] terragrunt run-all apply failed. aborting..."; cd -; exit 1; } +fi + +echo "[EXEC] cd -" +cd - diff --git a/bin/docker.sh b/bin/docker.sh new file mode 100755 index 00000000..0cb9d7c9 --- /dev/null +++ b/bin/docker.sh @@ -0,0 +1,122 @@ +#!/bin/bash + +help() +{ + echo "Build image based on Dockerfile and push it to private container registry" + echo + echo "Syntax: docker.sh [-q|r|p|t|s|d|f]" + echo "Options:" + echo "q Specify repository name (e.g. spf-fraud)" + echo "r Specify AWS region (e.g. us-east-1)" + echo "p Specify platform (e.g. linux/arm64)" + echo "t Specify version (e.g. latest)" + echo "s Specify CI/CD role name (e.g. spf-cicd-assume-role-abcd1234)" + echo "d Specify directory (e.g. app/fraud)" + echo "f Specify Dockerfile (e.g. Dockerfile)" + echo +} + +set -o pipefail + +SPF_REPOSITORY="" +SPF_REGION="" +SPF_VERSION="latest" +SPF_PLATFORM="linux/arm64" +SPF_ROLE_NAME="" +DIRECTORY="app/fraud" +DOCKERFILE="Dockerfile" + +while getopts "h:q:r:p:t:s:d:f:" option; do + case $option in + h) + help + exit;; + q) + SPF_REPOSITORY="$OPTARG";; + r) + SPF_REGION="$OPTARG";; + p) + SPF_PLATFORM="$OPTARG";; + t) + SPF_VERSION="$OPTARG";; + s) + SPF_ROLE_NAME="$OPTARG";; + d) + DIRECTORY="$OPTARG";; + f) + DOCKERFILE="$OPTARG";; + \?) + echo "[ERROR] invalid option" + echo + help + exit;; + esac +done + +aws --version > /dev/null 2>&1 || { pip install awscli; } +aws --version > /dev/null 2>&1 || { echo "[ERROR] aws is missing. aborting..."; exit 1; } +docker --version > /dev/null 2>&1 || { echo "[ERROR] docker is missing. aborting..."; exit 1; } + +if [ -z "${SPF_ROLE_NAME}" ] && [ ! -z "${TF_VAR_ROLE_NAME}" ]; then SPF_ROLE_NAME="${TF_VAR_ROLE_NAME}"; fi +if [ -z "${SPF_REGION}" ] && [ ! -z "${TF_VAR_SPF_REGION}" ]; then SPF_REGION="${TF_VAR_SPF_REGION}"; fi +if [ -z "${SPF_REGION}" ] && [ ! -z "${AWS_DEFAULT_REGION}" ]; then SPF_REGION="${AWS_DEFAULT_REGION}"; fi +if [ -z "${SPF_REGION}" ] && [ ! -z "${AWS_REGION}" ]; then SPF_REGION="${AWS_REGION}"; fi + +if [ -z "${SPF_REGION}" ]; then + echo "[DEBUG] SPF_REGION: ${SPF_REGION}" + echo "[ERROR] SPF_REGION is missing. aborting..."; exit 1; +fi + +if [ -z "${SPF_REPOSITORY}" ]; then + echo "[DEBUG] SPF_REPOSITORY: ${SPF_REPOSITORY}" + echo "[ERROR] SPF_REPOSITORY is missing. aborting..."; exit 1; +fi + +if [ -z "${SPF_VERSION}" ]; then + echo "[DEBUG] SPF_VERSION: ${SPF_VERSION}" + echo "[ERROR] SPF_VERSION is missing. aborting..."; exit 1; +fi + +if [ -z "${SPF_PLATFORM}" ]; then + echo "[DEBUG] SPF_PLATFORM: ${SPF_PLATFORM}" + echo "[ERROR] SPF_PLATFORM is missing. aborting..."; exit 1; +fi + +WORKDIR="$( cd "$(dirname "$0")/../" > /dev/null 2>&1 || exit 1; pwd -P )" +ACCOUNT=$(aws sts get-caller-identity --query Account --region "${SPF_REGION}") +ACCOUNT=${ACCOUNT//\"/} +ENDPOINT="${ACCOUNT}.dkr.ecr.${SPF_REGION}.amazonaws.com" +DOCKER_CONFIG="${WORKDIR}/.docker" +OPTIONS="" + +echo "[INFO] echo {\"credsStore\":\"ecr-login\"} > ${DOCKER_CONFIG}/config.json" +mkdir -p "${DOCKER_CONFIG}" && touch "${DOCKER_CONFIG}/config.json" && echo "{\"credsStore\":\"ecr-login\"}" > "${DOCKER_CONFIG}/config.json" + +echo "[INFO] aws ecr get-login-password --region ${SPF_REGION} | docker login --username AWS --password-stdin ${ENDPOINT}" +aws ecr get-login-password --region "${SPF_REGION}" | docker login --username AWS --password-stdin "${ENDPOINT}" || { echo "[ERROR] docker login failed. aborting..."; exit 1; } + +if [ ! -z "${SPF_ROLE_NAME}" ]; then + echo "[INFO] aws sts assume-role --role-arn arn:aws:iam::${ACCOUNT}:role/${SPF_ROLE_NAME} --role-session-name ${ACCOUNT}" + ASSUME_ROLE=$(aws sts assume-role --role-arn "arn:aws:iam::${ACCOUNT}:role/${SPF_ROLE_NAME}" --role-session-name "${ACCOUNT}") + OPTIONS="${OPTIONS} --build-arg AWS_DEFAULT_REGION=${SPF_REGION}" + OPTIONS="${OPTIONS} --build-arg AWS_ACCESS_KEY_ID=$(echo "${ASSUME_ROLE}" | jq -r '.Credentials.AccessKeyId')" + OPTIONS="${OPTIONS} --build-arg AWS_SECRET_ACCESS_KEY=$(echo "${ASSUME_ROLE}" | jq -r '.Credentials.SecretAccessKey')" + OPTIONS="${OPTIONS} --build-arg AWS_SESSION_TOKEN=$(echo "${ASSUME_ROLE}" | jq -r '.Credentials.SessionToken')" +fi + +echo "[INFO] docker build -t ${SPF_REPOSITORY}:${SPF_VERSION} -f ${WORKDIR}/${DOCKERFILE} ${WORKDIR}/${DIRECTORY}/ --platform ${SPF_PLATFORM}" +docker build -t "${SPF_REPOSITORY}:${SPF_VERSION}" -f "${WORKDIR}/${DOCKERFILE}" "${WORKDIR}/${DIRECTORY}/" --platform "${SPF_PLATFORM}" ${OPTIONS} || { echo "[ERROR] docker build failed. aborting..."; exit 1; } + +echo "[INFO] docker tag ${SPF_REPOSITORY}:${SPF_VERSION} ${ENDPOINT}/${SPF_REPOSITORY}:${SPF_VERSION}" +docker tag "${SPF_REPOSITORY}:${SPF_VERSION}" "${ENDPOINT}/${SPF_REPOSITORY}:${SPF_VERSION}" || { echo "[ERROR] docker tag failed. aborting..."; exit 1; } + +echo "[INFO] docker push ${ENDPOINT}/${SPF_REPOSITORY}:${SPF_VERSION}" +OUTPUT=$(docker push "${ENDPOINT}/${SPF_REPOSITORY}:${SPF_VERSION}") || { echo "[ERROR] docker push failed. aborting..."; exit 1; } + +echo "[INFO] OUTPUT: ${OUTPUT}" +IFS=' ' read -ra ARR <<< "$(echo "${OUTPUT}" | tr '\n' ' ')" + +# if [ ! -z "${UPDATE}" ] && [ "${UPDATE}" == "true" ]; then +# echo "[INFO] aws lambda update-function-code --region ${SPF_REGION} --function-name ${SPF_REPOSITORY} --image-uri ${ENDPOINT}/${SPF_REPOSITORY}@${ARR[${#ARR[@]} - 3]}" +# aws lambda update-function-code --region "${SPF_REGION}" --function-name "${SPF_REPOSITORY}" --image-uri "${ENDPOINT}/${SPF_REPOSITORY}@${ARR[${#ARR[@]} - 3]}" +# fi