Init
This commit is contained in:
commit
0029086b3f
148 changed files with 19047 additions and 0 deletions
57
scripts/README.md
Normal file
57
scripts/README.md
Normal file
|
@ -0,0 +1,57 @@
|
|||
# Scripts
|
||||
|
||||
Baseline root level scripts are designed for common actions required on the project rather than client/api specific actions (these live in their respective client e.g. `/api/scripts`). Running scripts directly should be avoided by the project developers, instead make the scripts npm scripts so that future changes to the script does not affect how developers use Baseline.
|
||||
|
||||
## Deploy
|
||||
|
||||
A generic script for handling the deployment for a specific client/api. Only used for deployment in GitHub or Bitbucket pipelines.
|
||||
|
||||
The single argument is the folder path which we are installing. This allows use to call the appropriate npm script, such as `npm run deploy:prod`.
|
||||
|
||||
Expected usage
|
||||
|
||||
```
|
||||
./scripts/deploy.sh api
|
||||
```
|
||||
|
||||
## Setup AWS Profile
|
||||
|
||||
A script for managing the AWS profile easily for the project. Only expected to be used by developers locally.
|
||||
|
||||
The developer will always need AWS I AM security credentials for local deployment or utilizing any AWS feature that requires the API to hit an AWS service.
|
||||
|
||||
Includes testing the AWS credentials
|
||||
|
||||
Expected usage
|
||||
|
||||
```
|
||||
./scripts/setup-aws-profile.sh
|
||||
```
|
||||
|
||||
Developer usage
|
||||
|
||||
```
|
||||
npm run aws:profile
|
||||
```
|
||||
|
||||
It is recommended that clients also add the ability to run in client/api folders to make it easy to access as some projects will use SSO with frequently expiring credentials.
|
||||
|
||||
## Setup AWS
|
||||
|
||||
A script designed for use in GitHub and Bitbucket deployments for setting the correct AWS profiles values based on the pipeline environment variables. Since GitHub and Bitbucket work differently there is some logic to handle things differently, see code for specifics.
|
||||
|
||||
Expected usage
|
||||
|
||||
```
|
||||
./scripts/setup-aws.sh
|
||||
```
|
||||
|
||||
## Setup NPM
|
||||
|
||||
Setup NPM variables, set npm version, install pnpm which is required for the remaining deployment operations. Only used in GitHub/Bitbucket deployment pipelines and is expected to run first.
|
||||
|
||||
Expected usage
|
||||
|
||||
```
|
||||
./scripts/setup-npm.sh
|
||||
```
|
131
scripts/add-env-var.sh
Executable file
131
scripts/add-env-var.sh
Executable file
|
@ -0,0 +1,131 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# Sets REGION, APP_NAME, AWS_REGION, AWS_PROFILE
|
||||
. ./scripts/project-variables.sh
|
||||
|
||||
STAGE="${1:-"local"}"
|
||||
|
||||
echo "App Name: [${APP_NAME}]"
|
||||
echo "Profile: [${AWS_PROFILE}]"
|
||||
echo "Region: [${REGION}]"
|
||||
echo "Stage: [${STAGE}]"
|
||||
|
||||
echo "Create new environment variable for stage [$STAGE]"
|
||||
|
||||
PARAMETER_TYPE=""
|
||||
ENV_LOCATION="backend"
|
||||
|
||||
printf 'Used in Frontend or Backend (f/B)? '
|
||||
old_stty_cfg=$(stty -g)
|
||||
stty raw -echo
|
||||
answer=$(head -c 1)
|
||||
stty "$old_stty_cfg"
|
||||
if echo "$answer" | grep -iq "^f"; then
|
||||
echo Frontend
|
||||
PARAMETER_TYPE="String"
|
||||
ENV_LOCATION="frontend"
|
||||
else
|
||||
echo Backend
|
||||
fi
|
||||
|
||||
printf "Enter new variable name (in CAPS): "
|
||||
read -r NAME
|
||||
|
||||
if [ ! $PARAMETER_TYPE ]; then
|
||||
printf 'Is it secret (y/n)? '
|
||||
old_stty_cfg=$(stty -g)
|
||||
stty raw -echo
|
||||
answer=$(head -c 1)
|
||||
stty "$old_stty_cfg"
|
||||
if echo "$answer" | grep -iq "^y"; then
|
||||
echo Yes
|
||||
PARAMETER_TYPE="SecureString"
|
||||
printf "Enter new value: "
|
||||
while IFS= read -p "$prompt" -r -s -n 1 char; do
|
||||
if [[ $char == $'\0' ]]; then
|
||||
break
|
||||
fi
|
||||
prompt='*'
|
||||
VALUE+="$char"
|
||||
done
|
||||
echo
|
||||
else
|
||||
echo No
|
||||
PARAMETER_TYPE="String"
|
||||
printf "Enter new value: "
|
||||
read -r VALUE
|
||||
fi
|
||||
else
|
||||
echo "Frontend env vars are never secret, using plaintext."
|
||||
printf "Enter new value: "
|
||||
read -r VALUE
|
||||
fi
|
||||
|
||||
echo "Checking AWS SSM for existing record..."
|
||||
if ! aws ssm get-parameter --name "/$APP_NAME/$STAGE/$NAME" --profile "$AWS_PROFILE" --region "$REGION" >/dev/null; then
|
||||
echo "No existing record"
|
||||
echo "Pushing to AWS SSM..."
|
||||
aws ssm put-parameter --name "/$APP_NAME/$STAGE/$NAME" \
|
||||
--value "$VALUE" --type $PARAMETER_TYPE --overwrite --profile "$AWS_PROFILE" --region "$REGION" >/dev/null
|
||||
echo "done"
|
||||
else
|
||||
aws ssm get-parameter --name "/$APP_NAME/$STAGE/$NAME" --profile "$AWS_PROFILE" --region "$REGION"
|
||||
printf 'Existing record, do you want to update? (y/n)? '
|
||||
old_stty_cfg=$(stty -g)
|
||||
stty raw -echo
|
||||
answer=$(head -c 1)
|
||||
stty "$old_stty_cfg"
|
||||
if echo "$answer" | grep -iq "^y"; then
|
||||
echo Yes
|
||||
echo "Pushing to AWS SSM..."
|
||||
aws ssm put-parameter --name "/$APP_NAME/$STAGE/$NAME" \
|
||||
--value "$VALUE" --type $PARAMETER_TYPE --overwrite --profile "$AWS_PROFILE" --region "$REGION" >/dev/null
|
||||
echo "done"
|
||||
else
|
||||
echo No
|
||||
echo "Leaving existing value"
|
||||
exit
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$ENV_LOCATION" == "backend" ]; then
|
||||
if grep -q "$NAME:" "packages/api/serverless.yml"; then
|
||||
echo "Variable is already in packages/api/serverless.yml, will not duplicate"
|
||||
else
|
||||
echo "Updating packages/api/serverless.yml..."
|
||||
sed -i.bak "s/.* environment:.*/&\n $NAME: \${ssm:\/\${env:APP_NAME}\/\${opt:stage}\/$NAME, \"\"}/" packages/api/serverless.yml
|
||||
rm packages/api/serverless.yml.bak
|
||||
fi
|
||||
else
|
||||
if grep -q "$NAME=" "scripts/generate-env-vars.sh"; then
|
||||
echo "Variable is already in scripts/generate-env-vars.sh, will not duplicate"
|
||||
else
|
||||
echo "Updating scripts/generate-env-vars.sh..."
|
||||
NEW_VAR_CODE="$NAME=\$(aws ssm get-parameter --name \"\/$APP_NAME\/\$STACK_STAGE\/$NAME\" --with-decryption --query 'Parameter.Value' --output text --profile \"\${AWS_PROFILE}\" --region \"\${REGION}\")\nOUTPUT=\$(printf \"%s\\\nREACT_APP_$NAME=%s\" \"\${OUTPUT}\" \"\${$NAME}\"\)"
|
||||
sed -i.bak "s/.*# Additional.*/&\n${NEW_VAR_CODE}/g" scripts/generate-env-vars.sh
|
||||
rm scripts/generate-env-vars.sh.bak
|
||||
fi
|
||||
|
||||
if grep -q " 'REACT_APP_$NAME" "packages/web/vite.config.ts"; then
|
||||
echo "Variable is already in packages/web/vite.config.ts, will not duplicate"
|
||||
else
|
||||
echo "Updating packages/web/vite.config.ts..."
|
||||
NEW_VAR_TYPE=" 'REACT_APP_$NAME'"
|
||||
sed -i.bak "s/.* EnvironmentPlugin(\[.*/&\n${NEW_VAR_TYPE},/g" packages/web/vite.config.ts
|
||||
rm packages/web/vite.config.ts.bak
|
||||
fi
|
||||
|
||||
if grep -q " 'REACT_APP_$NAME" "packages/admin/vite.config.ts"; then
|
||||
echo "Variable is already in packages/admin/vite.config.ts, will not duplicate"
|
||||
else
|
||||
echo "Updating packages/admin/vite.config.ts..."
|
||||
NEW_VAR_TYPE=" 'REACT_APP_$NAME'"
|
||||
sed -i.bak "s/.* EnvironmentPlugin(\[.*/&\n${NEW_VAR_TYPE},/g" packages/admin/vite.config.ts
|
||||
rm packages/admin/vite.config.ts.bak
|
||||
fi
|
||||
|
||||
echo "Generating fresh env vars file..."
|
||||
pnpm run generate:env:"${STAGE}" >/dev/null
|
||||
fi
|
||||
|
||||
echo "done - don't forget to add the variable to all stages"
|
31
scripts/deploy.sh
Executable file
31
scripts/deploy.sh
Executable file
|
@ -0,0 +1,31 @@
|
|||
#!/usr/bin/env bash
|
||||
shopt -s failglob
|
||||
set -eu -o pipefail
|
||||
|
||||
CURRENT_DIR="$(pwd -P)"
|
||||
PARENT_PATH="$(
|
||||
cd "$(dirname "${BASH_SOURCE[0]}")" || exit
|
||||
pwd -P
|
||||
)/.."
|
||||
cd "$PARENT_PATH" || exit
|
||||
|
||||
# Move to the component to deploy (api or web)
|
||||
PACKAGE_PATH="${1:-""}"
|
||||
cd "$PACKAGE_PATH"
|
||||
|
||||
# Install required modules
|
||||
# pnpm install
|
||||
|
||||
if [ "${BITBUCKET_BRANCH:-${GITHUB_REF##*/}}" == "prod" ]; then
|
||||
# pnpm run serverless deploy --stage prod --region $AWS_REGION"
|
||||
# Downside: this will override the AWS_PROFILE used in the pipeline
|
||||
pnpm run deploy:prod
|
||||
else
|
||||
# pnpm run serverless deploy --stage staging --region $AWS_REGION"
|
||||
# Downside: this will override the AWS_PROFILE used in the pipeline
|
||||
pnpm run deploy:staging
|
||||
fi
|
||||
|
||||
echo "Done!"
|
||||
|
||||
cd "$CURRENT_DIR" || exit
|
183
scripts/experimental-install-requirements.sh
Executable file
183
scripts/experimental-install-requirements.sh
Executable file
|
@ -0,0 +1,183 @@
|
|||
#!/bin/bash
|
||||
|
||||
install_curl() {
|
||||
if command -v curl >/dev/null 2>&1; then
|
||||
echo "Curl is already installed."
|
||||
return 0
|
||||
fi
|
||||
echo "Installing curl..."
|
||||
if [ $OS == "mac" ]; then
|
||||
brew install curl
|
||||
else
|
||||
if [ -x "$(command -v yum)" ]; then
|
||||
sudo yum install -y curl
|
||||
elif [ -x "$(command -v apt-get)" ]; then
|
||||
sudo apt-get install -y curl
|
||||
else
|
||||
echo "Package manager not supported. Cannot install curl."
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
install_node() {
|
||||
if [ -f "$HOME/.nvm/nvm.sh" ]; then
|
||||
NVM_EXISTS=true
|
||||
else
|
||||
NVM_EXISTS=false
|
||||
fi
|
||||
if $NVM_EXISTS; then
|
||||
echo "NVM is already installed."
|
||||
else
|
||||
echo "Installing NVM..."
|
||||
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
|
||||
export NVM_DIR="$HOME/.nvm"
|
||||
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
|
||||
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion
|
||||
fi
|
||||
echo "Setting correct node, npm, and pnpm versions..."
|
||||
bash -i -c 'source ~/.bashrc; nvm install 20; nvm use 20; nvm alias default 20; nvm install-latest-npm; npm install -g pnpm@9; exit;'
|
||||
}
|
||||
|
||||
install_aws_cli() {
|
||||
if command -v aws >/dev/null 2>&1; then
|
||||
echo "AWS CLI is already installed."
|
||||
return 0
|
||||
fi
|
||||
|
||||
echo "Installing AWS CLI v2..."
|
||||
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
|
||||
unzip awscliv2.zip
|
||||
sudo ./aws/install
|
||||
rm -rf awscliv2.zip aws
|
||||
}
|
||||
|
||||
install_homebrew() {
|
||||
if [ "$OS" != "mac" ]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
if command -v brew >/dev/null 2>&1; then
|
||||
echo "Homebrew is already installed."
|
||||
return 0
|
||||
fi
|
||||
echo "Installing Homebrew..."
|
||||
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
|
||||
}
|
||||
|
||||
install_jq() {
|
||||
if command -v jq >/dev/null 2>&1; then
|
||||
echo "jq is already installed."
|
||||
return 0
|
||||
fi
|
||||
case $1 in
|
||||
mac)
|
||||
brew install jq
|
||||
;;
|
||||
linux)
|
||||
if [ -x "$(command -v yum)" ]; then
|
||||
sudo yum install -y jq
|
||||
elif [ -x "$(command -v apt-get)" ]; then
|
||||
sudo apt-get install -y jq
|
||||
else
|
||||
echo "Package manager not supported. Cannot install jq."
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
install_java() {
|
||||
if command -v java >/dev/null 2>&1; then
|
||||
echo "Java is already installed."
|
||||
return 0
|
||||
fi
|
||||
case $1 in
|
||||
mac)
|
||||
brew install java
|
||||
;;
|
||||
linux)
|
||||
if [ -x "$(command -v yum)" ]; then
|
||||
sudo yum install -y java
|
||||
elif [ -x "$(command -v apt-get)" ]; then
|
||||
sudo apt-get install -y openjdk-8-jdk
|
||||
else
|
||||
echo "Package manager not supported. Cannot install Java."
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Detect OS and install packages
|
||||
OS="unknown"
|
||||
if [ "$(uname)" == "Darwin" ]; then
|
||||
OS="mac"
|
||||
elif [ -f "/etc/redhat-release" ]; then
|
||||
OS="linux"
|
||||
elif [ -f "/etc/debian_version" ]; then
|
||||
OS="linux"
|
||||
fi
|
||||
|
||||
usage() {
|
||||
echo "Usage: $0 [-f function]"
|
||||
echo "Available functions:"
|
||||
echo " all Install all dependencies"
|
||||
echo " brew Install Homebrew"
|
||||
echo " curl Install curl"
|
||||
echo " node Install Node.js and NVM"
|
||||
echo " aws Install AWS CLI"
|
||||
echo " jq Install jq"
|
||||
echo " java Install Java"
|
||||
exit 1
|
||||
}
|
||||
|
||||
while getopts "f:" opt; do
|
||||
case ${opt} in
|
||||
f)
|
||||
FUNCTION=$OPTARG
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ -z "$FUNCTION" ]; then
|
||||
# Default to running all
|
||||
FUNCTION="all"
|
||||
fi
|
||||
|
||||
case $FUNCTION in
|
||||
brew)
|
||||
install_homebrew
|
||||
;;
|
||||
curl)
|
||||
install_curl
|
||||
;;
|
||||
node)
|
||||
install_node
|
||||
;;
|
||||
node-version)
|
||||
get_node_version
|
||||
;;
|
||||
aws)
|
||||
install_aws_cli
|
||||
;;
|
||||
jq)
|
||||
install_jq $OS
|
||||
;;
|
||||
java)
|
||||
install_java $OS
|
||||
;;
|
||||
all)
|
||||
install_homebrew
|
||||
install_curl
|
||||
install_node
|
||||
install_aws_cli
|
||||
install_jq $OS
|
||||
install_java $OS
|
||||
echo "Installation complete. Please verify the installation by checking the versions of the installed software."
|
||||
echo "Open a new terminal session to start using everything."
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
;;
|
||||
esac
|
55
scripts/generate-env-vars.sh
Executable file
55
scripts/generate-env-vars.sh
Executable file
|
@ -0,0 +1,55 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
CURRENT_DIR="$(pwd -P)"
|
||||
PARENT_PATH="$(
|
||||
cd "$(dirname "${BASH_SOURCE[0]}")" || exit
|
||||
pwd -P
|
||||
)/.."
|
||||
cd "$PARENT_PATH" || exit
|
||||
|
||||
# Sets REGION, APP_NAME, AWS_REGION, AWS_PROFILE
|
||||
. ./scripts/project-variables.sh
|
||||
|
||||
STACK_STAGE=$1 # local/staging/prod
|
||||
echo "App Name: [${APP_NAME}]"
|
||||
echo "Profile: [${AWS_PROFILE}]"
|
||||
echo "Region: [${REGION}]"
|
||||
echo "Stack Stage: [${STACK_STAGE}]"
|
||||
|
||||
STACK=$STACK_STAGE
|
||||
if [ "$STACK_STAGE" == "local" ]; then
|
||||
STACK="staging"
|
||||
fi
|
||||
|
||||
# Get stack outputs
|
||||
. ./scripts/get-stack-outputs.sh "${STACK}" >/dev/null
|
||||
|
||||
if [ "$STACK_STAGE" == "local" ]; then
|
||||
OUTPUT_FILENAME=.env.development
|
||||
ServiceEndpoint=http://localhost:4000/local
|
||||
if [ "$CODESPACE_NAME" ]; then
|
||||
ServiceEndpoint="https://${CODESPACE_NAME}-4000.${GITHUB_CODESPACES_PORT_FORWARDING_DOMAIN}/local"
|
||||
fi
|
||||
else
|
||||
OUTPUT_FILENAME=.env.production
|
||||
fi
|
||||
|
||||
OUTPUT=$(
|
||||
cat <<EOF
|
||||
REACT_APP_APP_NAME=${APP_NAME:-}
|
||||
REACT_APP_AWS_PROFILE=${AWS_PROFILE:-}
|
||||
REACT_APP_API_URL=${ServiceEndpoint:-}/
|
||||
REACT_APP_COGNITO_IDENTITY_POOL_ID=${IdentityPoolId:-}
|
||||
REACT_APP_COGNITO_USER_POOL_ID=${UserPoolId:-}
|
||||
REACT_APP_COGNITO_USER_POOL_WEB_CLIENT_ID=${UserPoolClientId:-}
|
||||
EOF
|
||||
)
|
||||
|
||||
# Comment below is used to determine where to add new env vars, please do not modify
|
||||
# Additional variables are set here
|
||||
echo "$OUTPUT" >./packages/web/$OUTPUT_FILENAME
|
||||
printf "\033[32m[%s] has been generated successfully!\033[39m\n" "./web/${OUTPUT_FILENAME}"
|
||||
echo "$OUTPUT" >./packages/admin/$OUTPUT_FILENAME
|
||||
printf "\033[32m[%s] has been generated successfully!\033[39m\n" "./admin/${OUTPUT_FILENAME}"
|
||||
|
||||
cd "$CURRENT_DIR" || exit
|
86
scripts/get-stack-outputs.sh
Executable file
86
scripts/get-stack-outputs.sh
Executable file
|
@ -0,0 +1,86 @@
|
|||
#!/usr/bin/env bash
|
||||
# shellcheck disable=SC2207
|
||||
|
||||
CURRENT_DIR="$(pwd -P)"
|
||||
PARENT_PATH="$(
|
||||
cd "$(dirname "${BASH_SOURCE[0]}")" || exit
|
||||
pwd -P
|
||||
)/.."
|
||||
cd "$PARENT_PATH" || exit
|
||||
|
||||
# Sets REGION, APP_NAME, AWS_REGION, AWS_PROFILE
|
||||
. ./scripts/project-variables.sh
|
||||
|
||||
STAGE=$1
|
||||
|
||||
echo "Begin: exporting cloudformation outputs as environment variables"
|
||||
start=$(date +%s)
|
||||
|
||||
echo "App Name: [${APP_NAME}]"
|
||||
echo "Profile: [${AWS_PROFILE}]"
|
||||
echo "Region: [${REGION}]"
|
||||
echo "Stage: [${STAGE}]"
|
||||
|
||||
if [ "$AWS_PROFILE" == "" ] || [ "$STAGE" == "" ] || [ "$REGION" == "" ]; then
|
||||
echo "Error: No profile, stage or region passed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
IS_STACK="$(aws cloudformation describe-stacks --region "${REGION}" --profile "${AWS_PROFILE}" --max-items 1 >/dev/null)"
|
||||
if ! $IS_STACK; then
|
||||
echo "No stacks found in region, nothing to export"
|
||||
elif [[ "$(aws cloudformation describe-stacks --region "${REGION}" --profile "${AWS_PROFILE}" --max-items 1 --query "Stacks[]")" == "[]" ]]; then
|
||||
echo "Empty set of stacks found, nothing to export"
|
||||
else
|
||||
stacksForRegion=$(aws cloudformation describe-stacks --region "${REGION}")
|
||||
|
||||
echo "Env Stack filter: [$APP_NAME] && [$STAGE]"
|
||||
|
||||
stacksForEnvFilter="$(echo "${stacksForRegion:-}" | grep "StackName" | { grep -i "$APP_NAME" | grep -i "$STAGE" || true; })"
|
||||
|
||||
if [ "${stacksForEnvFilter:-}" != "" ]; then
|
||||
stacksForEnv="$(echo "${stacksForEnvFilter:-}" | cut -d\" -f4)"
|
||||
|
||||
if [ "${stacksForEnv:-}" != "" ]; then
|
||||
for stack in $stacksForEnv; do
|
||||
echo
|
||||
echo "Outputs for: $stack"
|
||||
echo
|
||||
stack_info=$(aws cloudformation describe-stacks \
|
||||
--region "$REGION" \
|
||||
--stack-name "$stack" \
|
||||
--profile "${AWS_PROFILE}" \
|
||||
--output json)
|
||||
|
||||
if [[ "$stack_info" =~ "OutputKey" ]]; then
|
||||
outputKeys=($(echo "$stack_info" | jq ".Stacks[].Outputs[].OutputKey"))
|
||||
outputValues=($(echo "$stack_info" | jq ".Stacks[].Outputs[].OutputValue"))
|
||||
|
||||
for ((i = 0; i < ${#outputKeys[@]}; i++)); do
|
||||
keyTmp=${outputKeys[i]#\"*}
|
||||
key=${keyTmp%\"*}
|
||||
valTmp=${outputValues[i]#\"*}
|
||||
val=${valTmp%\"*}
|
||||
echo "export $key=$val"
|
||||
export "$key"="$val"
|
||||
done
|
||||
fi
|
||||
done
|
||||
else
|
||||
echo "No stacks found for environment filter, nothing to export"
|
||||
fi
|
||||
else
|
||||
echo "No stacks found for environment filter, nothing to export"
|
||||
fi
|
||||
fi
|
||||
|
||||
AWS_ACCOUNT_ID="$(aws sts get-caller-identity --profile "$AWS_PROFILE" --region us-east-1 --output text --query 'Account')"
|
||||
export AWS_ACCOUNT_ID
|
||||
|
||||
echo AWS_ACCOUNT_ID="$AWS_ACCOUNT_ID"
|
||||
|
||||
end=$(date +%s)
|
||||
runtime=$((end - start))
|
||||
echo "Finish ($runtime secs): exporting cloudformation outputs as environment variables"
|
||||
|
||||
cd "$CURRENT_DIR" || exit
|
18
scripts/project-urls.sh
Executable file
18
scripts/project-urls.sh
Executable file
|
@ -0,0 +1,18 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
CURRENT_DIR="$(pwd -P)"
|
||||
PARENT_PATH="$(
|
||||
cd "$(dirname "${BASH_SOURCE[0]}")" || exit
|
||||
pwd -P
|
||||
)/.."
|
||||
cd "$PARENT_PATH" || exit
|
||||
|
||||
echo "Stage [$1]"
|
||||
|
||||
. ./scripts/get-stack-outputs.sh $1 >/dev/null
|
||||
|
||||
echo "Web: https://${WebCloudFrontUrl:-}"
|
||||
echo "Admin: https://${AdminCloudFrontUrl:-}"
|
||||
echo "API: ${ServiceEndpoint:-}"
|
||||
|
||||
cd "$CURRENT_DIR" || exit
|
8
scripts/project-variables-github.sh
Executable file
8
scripts/project-variables-github.sh
Executable file
|
@ -0,0 +1,8 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
. ./scripts/project-variables.sh
|
||||
|
||||
echo "APP_NAME=$APP_NAME" >>"$GITHUB_ENV"
|
||||
echo "AWS_PROFILE_GITHUB=$AWS_PROFILE" >>"$GITHUB_ENV" # AWS_PROFILE is a reserved variable
|
||||
echo "REGION=$REGION" >>"$GITHUB_ENV"
|
||||
echo "AWS_REGION=$AWS_REGION" >>"$GITHUB_ENV"
|
10
scripts/project-variables.sh
Executable file
10
scripts/project-variables.sh
Executable file
|
@ -0,0 +1,10 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# Consolidate setting of profile and region. This script is expected to be run before other
|
||||
# scripts (or inside them if in `./scripts`). This makes it easier to manage these values
|
||||
# across the project as it grows.
|
||||
|
||||
export APP_NAME="bms-repository"
|
||||
export AWS_PROFILE="bms-repository"
|
||||
export REGION="us-east-1"
|
||||
export AWS_REGION="us-east-1"
|
11
scripts/set-region.sh
Executable file
11
scripts/set-region.sh
Executable file
|
@ -0,0 +1,11 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
CURRENT_DIR="$(pwd -P)"
|
||||
PARENT_PATH="$( cd "$(dirname "${BASH_SOURCE[0]}")" || exit ; pwd -P )/.."
|
||||
cd "$PARENT_PATH" || exit
|
||||
|
||||
echo "Changing region to [$1]"
|
||||
|
||||
sed -i '' -e "s|ap-southeast-2|$1|g" ./scripts/project-variables.sh
|
||||
|
||||
cd "$CURRENT_DIR" || exit
|
56
scripts/setup-aws-profile.sh
Executable file
56
scripts/setup-aws-profile.sh
Executable file
|
@ -0,0 +1,56 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
CURRENT_DIR="$(pwd -P)"
|
||||
PARENT_PATH="$(
|
||||
cd "$(dirname "${BASH_SOURCE[0]}")" || exit
|
||||
pwd -P
|
||||
)/.."
|
||||
cd "$PARENT_PATH" || exit
|
||||
|
||||
# Sets REGION, APP_NAME, AWS_REGION, AWS_PROFILE
|
||||
. ./scripts/project-variables.sh
|
||||
|
||||
if ! command -v aws &>/dev/null; then
|
||||
echo "AWS CLI could not be found, please install it before continuing."
|
||||
echo "You can find instructions here: https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html"
|
||||
exit
|
||||
fi
|
||||
|
||||
printf "Setup AWS profile [\033[32m%s\033[39m]\n" "$AWS_PROFILE"
|
||||
|
||||
printf "Enter the AWS Access Key: "
|
||||
read -r AWS_ACCESS_KEY_ID
|
||||
printf "Enter the AWS Secret Key: "
|
||||
read -sr AWS_SECRET_ACCESS_KEY
|
||||
printf "\nAWS Session Token (optional): "
|
||||
read -sr AWS_SESSION_TOKEN
|
||||
printf "\n"
|
||||
|
||||
echo "Configuring AWS...."
|
||||
# If you specify a profile with --profile on an individual command, that overrides the setting specified in the environment variable for only that command.
|
||||
aws configure set aws_access_key_id "${AWS_ACCESS_KEY_ID:-}" --profile "$AWS_PROFILE"
|
||||
aws configure set aws_secret_access_key "${AWS_SECRET_ACCESS_KEY:-}" --profile "$AWS_PROFILE"
|
||||
if [ "$AWS_SESSION_TOKEN" ]; then
|
||||
echo "Setting session token"
|
||||
aws configure set aws_session_token "${AWS_SESSION_TOKEN:-}" --profile "$AWS_PROFILE"
|
||||
else
|
||||
EXISTING_SESSION=$(aws configure get aws_session_token --profile "$AWS_PROFILE")
|
||||
if [ "$EXISTING_SESSION" ]; then
|
||||
echo "Existing session token found, removing"
|
||||
aws configure set aws_session_token "" --profile "$AWS_PROFILE"
|
||||
else
|
||||
echo "No existing session token... ignoring"
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "Testing AWS Keys..."
|
||||
IAM_RESULT=$(aws sts get-caller-identity --query "Account" --output text --profile "$AWS_PROFILE")
|
||||
if [ "$IAM_RESULT" ]; then
|
||||
echo "Credentials work!"
|
||||
else
|
||||
echo "AWS Keys did not work!"
|
||||
fi
|
||||
|
||||
echo "Done"
|
||||
|
||||
cd "$CURRENT_DIR" || exit
|
90
scripts/setup-aws.sh
Executable file
90
scripts/setup-aws.sh
Executable file
|
@ -0,0 +1,90 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
shopt -s failglob
|
||||
set -eu -o pipefail
|
||||
|
||||
CURRENT_DIR="$(pwd -P)"
|
||||
PARENT_PATH="$(
|
||||
cd "$(dirname "${BASH_SOURCE[0]}")" || exit
|
||||
pwd -P
|
||||
)/.."
|
||||
cd "$PARENT_PATH" || exit
|
||||
|
||||
echo "Begin: Setup AWS"
|
||||
|
||||
# Only install AWS CLI if deployed from Bitbucket
|
||||
if [ "${BITBUCKET_BRANCH:-}" ]; then
|
||||
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
|
||||
unzip -qq awscliv2.zip
|
||||
./aws/install -i /usr/local/aws-cli -b /usr/local/bin
|
||||
fi
|
||||
|
||||
# Sets REGION, APP_NAME, AWS_REGION, AWS_PROFILE
|
||||
. ./scripts/project-variables.sh
|
||||
|
||||
echo "App Name: [$APP_NAME]"
|
||||
echo "Profile: [$AWS_PROFILE]"
|
||||
echo "Region: [$AWS_REGION]"
|
||||
|
||||
export AWS_HOME="/usr/local/bin/aws"
|
||||
export PATH="${AWS_HOME:-}:$PATH"
|
||||
|
||||
# Todo: Allow access keys for other pipeline environments
|
||||
# if [ "$AWS_ACCESS_KEY_ID" == "" ] || [ "$AWS_SECRET_ACCESS_KEY" == "" ]; then
|
||||
# # These can be used if master and prod are in different accounts or the IAM roles have different access
|
||||
# if [ "$BITBUCKET_BRANCH" == "prod" ]; then
|
||||
# export AWS_ACCESS_KEY_ID="${PROD_AWS_ACCOUNT_ACCESS_KEY_ID}"
|
||||
# export AWS_SECRET_ACCESS_KEY="${PROD_AWS_ACCOUNT_SECRET_ACCESS_KEY}"
|
||||
# else
|
||||
# export AWS_ACCESS_KEY_ID="${NON_AWS_ACCOUNT_ACCESS_KEY_ID}"
|
||||
# export AWS_SECRET_ACCESS_KEY="${NON_AWS_ACCOUNT_SECRET_ACCESS_KEY}"
|
||||
# fi
|
||||
# fi
|
||||
|
||||
# if [ "$AWS_ACCESS_KEY_ID" == "" ] || [ "$AWS_SECRET_ACCESS_KEY" == "" ]; then
|
||||
# echo "Warning: No AWS_ACCESS_KEY_ID or AWS_SECRET_ACCESS_KEY provided."
|
||||
# echo "You will not be able to deploy some of the AWS components of the environment."
|
||||
# fi
|
||||
|
||||
# Todo: Allow access keys for other pipeline environments
|
||||
# aws configure set aws_access_key_id "${AWS_ACCESS_KEY_ID:-}"
|
||||
# aws configure set aws_secret_access_key "${AWS_SECRET_ACCESS_KEY:-}"
|
||||
|
||||
# https://support.atlassian.com/bitbucket-cloud/docs/deploy-on-aws-using-bitbucket-pipelines-openid-connect/
|
||||
export AWS_WEB_IDENTITY_TOKEN_FILE="$CURRENT_DIR/web-identity-token"
|
||||
echo "$BITBUCKET_STEP_OIDC_TOKEN" >"$AWS_WEB_IDENTITY_TOKEN_FILE"
|
||||
|
||||
aws --version
|
||||
aws configure set cli_follow_urlparam false
|
||||
aws configure set region "${AWS_REGION:-}"
|
||||
aws configure set region "${AWS_REGION:-}" --profile "$AWS_PROFILE"
|
||||
# https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-role.html
|
||||
aws configure set role_arn "${AWS_ROLE_ARN:-}" --profile "$AWS_PROFILE"
|
||||
aws configure set web_identity_token_file "${AWS_WEB_IDENTITY_TOKEN_FILE:-}" --profile "$AWS_PROFILE"
|
||||
|
||||
echo "Current AWS Account:"
|
||||
aws sts get-caller-identity --query "Account" --output text --profile "$AWS_PROFILE"
|
||||
|
||||
# https://docs.aws.amazon.com/cli/latest/reference/sts/assume-role-with-web-identity.html
|
||||
TOKEN_JSON="$(
|
||||
aws sts assume-role-with-web-identity \
|
||||
--duration-seconds 3600 \
|
||||
--role-session-name "baseline-core-deploy" \
|
||||
--role-arn "$AWS_ROLE_ARN" \
|
||||
--web-identity-token "$BITBUCKET_STEP_OIDC_TOKEN"
|
||||
)"
|
||||
|
||||
ACCESS_KEY_ID="$(echo "${TOKEN_JSON}" | jq '.Credentials.AccessKeyId' -r)"
|
||||
SECRET_ACCESS_KEY="$(echo "${TOKEN_JSON}" | jq '.Credentials.SecretAccessKey' -r)"
|
||||
SESSION_TOKEN="$(echo "${TOKEN_JSON}" | jq '.Credentials.SessionToken' -r)"
|
||||
|
||||
aws configure set aws_access_key_id "${ACCESS_KEY_ID:-}" --profile "$AWS_PROFILE"
|
||||
aws configure set aws_secret_access_key "${SECRET_ACCESS_KEY:-}" --profile "$AWS_PROFILE"
|
||||
aws configure set aws_session_token "${SESSION_TOKEN:-}" --profile "$AWS_PROFILE"
|
||||
|
||||
echo "Current AWS Account:"
|
||||
aws sts get-caller-identity --query "Account" --output text --profile "$AWS_PROFILE"
|
||||
|
||||
echo "Finish: Setup AWS"
|
||||
|
||||
cd "$CURRENT_DIR" || exit
|
18
scripts/setup-npm.sh
Executable file
18
scripts/setup-npm.sh
Executable file
|
@ -0,0 +1,18 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
shopt -s failglob
|
||||
set -eu -o pipefail
|
||||
|
||||
echo "Begin: setup npm"
|
||||
|
||||
npm install npm@10.5.0 -g
|
||||
|
||||
export NODE_OPTIONS=--max-old-space-size=6144
|
||||
npm config set user 0
|
||||
npm config set unsafe-perm true
|
||||
|
||||
npm --version
|
||||
|
||||
npm install -g pnpm@9
|
||||
|
||||
echo "Finish: setup npm"
|
95
scripts/setup.sh
Executable file
95
scripts/setup.sh
Executable file
|
@ -0,0 +1,95 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
CURRENT_DIR="$(pwd -P)"
|
||||
PARENT_PATH="$(
|
||||
cd "$(dirname "${BASH_SOURCE[0]}")" || exit
|
||||
pwd -P
|
||||
)/.."
|
||||
cd "$PARENT_PATH" || exit
|
||||
|
||||
echo
|
||||
printf "\033[32m%s\033[39m\n" "Welcome to Baseline"
|
||||
echo "-------------------"
|
||||
echo
|
||||
echo "Lets setup your new application!"
|
||||
echo
|
||||
if ! command -v aws &>/dev/null; then
|
||||
echo "AWS CLI could not be found, please install it before continuing."
|
||||
echo "You can find instructions here: https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html"
|
||||
exit
|
||||
fi
|
||||
printf "Enter the name of your new application (e.g. my-new-app): "
|
||||
read -r PROJECT_NAME
|
||||
sed -i '' -e "s|bms-repository|$PROJECT_NAME|g" ./scripts/project-variables.sh >/dev/null 2>&1
|
||||
sed -i '' -e "s|bms-repository|$PROJECT_NAME|g" ./scripts/setup.sh >/dev/null 2>&1
|
||||
echo
|
||||
echo "Awesome, lets set a region where the app will be hosted!"
|
||||
echo
|
||||
echo "AWS uses regions to store your app, you can find a list of regions here: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-regions-availability-zones.html#concepts-available-regions"
|
||||
echo
|
||||
echo "Please select a region: "
|
||||
options=(
|
||||
"us-east-1 (US East - N. Virginia)"
|
||||
"us-east-2 (US East - Ohio)"
|
||||
"us-gov-east-1 (US Gov East)"
|
||||
"us-gov-west-1 (US Gov West)"
|
||||
"us-iso-east-1 (US ISO East)"
|
||||
"us-iso-west-1 (US ISO West)"
|
||||
"us-isob-east-1 (US ISOB East - Ohio)"
|
||||
"us-west-1 (US West - N. California)"
|
||||
"us-west-2 (US West - Oregon)"
|
||||
"af-south-1 (Africa - Cape Town)"
|
||||
"ap-east-1 (Asia Pacific - Hong Kong)"
|
||||
"ap-northeast-1 (Asia Pacific - Tokyo)"
|
||||
"ap-northeast-2 (Asia Pacific - Seoul)"
|
||||
"ap-northeast-3 (Asia Pacific - Osaka)"
|
||||
"ap-south-1 (Asia Pacific - Mumbai)"
|
||||
"ap-south-2 (Asia Pacific - Hyderabad)"
|
||||
"ap-southeast-1 (Asia Pacific - Singapore)"
|
||||
"ap-southeast-2 (Asia Pacific - Sydney)"
|
||||
"ap-southeast-3 (Asia Pacific - Jakarta)"
|
||||
"ap-southeast-4 (Asia Pacific - Melbourne)"
|
||||
"ca-central-1 (Canada - Central)"
|
||||
"cn-north-1 (China - Beijing)"
|
||||
"cn-northwest-1 (China - Ningxia)"
|
||||
"eu-central-1 (Europe - Frankfurt)"
|
||||
"eu-central-2 (Europe - Zurich)"
|
||||
"eu-north-1 (Europe - Stockholm)"
|
||||
"eu-south-1 (Europe - Milan)"
|
||||
"eu-south-2 (Europe - Spain)"
|
||||
"eu-west-1 (Europe - Ireland)"
|
||||
"eu-west-2 (Europe - London)"
|
||||
"eu-west-3 (Europe - Paris)"
|
||||
"me-central-1 (Middle East - UAE)"
|
||||
"me-south-1 (Middle East - Bahrain)"
|
||||
"sa-east-1 (South America - São Paulo)"
|
||||
)
|
||||
APP_REGION=""
|
||||
select opt in "${options[@]}"; do
|
||||
# Remove the description by deleting everything from " (" to the end
|
||||
APP_REGION="${opt%% (*}"
|
||||
echo "You selected $APP_REGION"
|
||||
break
|
||||
done
|
||||
sed -i '' -e "s|ap-southeast-2|$APP_REGION|g" ./scripts/project-variables.sh >/dev/null 2>&1
|
||||
echo
|
||||
echo "Great, lets get started!"
|
||||
echo "------------------------"
|
||||
echo "To finish setting up your application you will need to run the following commands:"
|
||||
echo "- [pnpm run aws:profile] to setup your AWS credentials profile"
|
||||
echo "- [pnpm run deploy:staging] to deploy api/web/admin"
|
||||
echo "- [pnpm run add:user:staging] to add an admin user to the application"
|
||||
echo "- [pnpm run urls:staging] To see your project URLs"
|
||||
echo
|
||||
echo "After that you will be able to run it locally! 🎉"
|
||||
echo "-----------------------------------------------"
|
||||
echo "1. [pnpm run generate:env:local]" to generate env files for admin and web
|
||||
echo "2. [pnpm run start:api]"
|
||||
echo "3. [pnpm run start:admin]"
|
||||
echo "4. [pnpm run start:web]"
|
||||
echo
|
||||
echo "If you have any questions or need help, please reach out to us at https://baselinejs.com"
|
||||
echo
|
||||
printf "\033[32m%s\033[39m\n" "Happy coding!"
|
||||
|
||||
cd "$CURRENT_DIR" || exit
|
Loading…
Add table
Add a link
Reference in a new issue