Initial AWS deployment config and scripts

- bin/deploy is executed by CircleCI to push deploy to AWS
- bin/deployment/* are executed by CodeDeploy in AWS
- appspec.yml is used by CodeDeploy to execute bin/deployment scripts
based on lifecycle events
pull/181/head
Paul Schoenfelder 7 years ago
parent ce6b98f868
commit 41efc21fa5
  1. 13
      .circleci/config.yml
  2. 19
      appspec.yml
  3. 119
      bin/deploy
  4. 16
      bin/deployment/build
  5. 15
      bin/deployment/health_check
  6. 9
      bin/deployment/migrate
  7. 7
      bin/deployment/start
  8. 9
      bin/deployment/stop

@ -145,8 +145,6 @@ jobs:
docker:
# Ensure .tool-versions matches
- image: circleci/elixir:1.6.4
environment:
MIX_ENV: test
working_directory: ~/app
@ -158,14 +156,14 @@ jobs:
fingerprints:
- "c4:fd:a8:f8:48:a8:09:e5:3e:be:30:62:4d:6f:6f:36"
# TODO update for deployment to AWS
- run:
name: Deploy Production to AWS
command: bin/deploy production
deploy_staging:
docker:
# Ensure .tool-versions matches
- image: circleci/elixir:1.6.4
environment:
MIX_ENV: test
working_directory: ~/app
@ -177,7 +175,10 @@ jobs:
fingerprints:
- "c4:fd:a8:f8:48:a8:09:e5:3e:be:30:62:4d:6f:6f:36"
# TODO update for deployment to AWS
- run:
name: Deploy Staging to AWS
command: bin/deploy staging
dialyzer:
docker:
# Ensure .tool-versions matches

@ -0,0 +1,19 @@
version: 0.0
os: linux
files:
- source: .
destination: /opt/app
hooks:
ApplicationStop:
- location: bin/deployment/stop
timeout: 300
AfterInstall:
- location: bin/deployment/build
ApplicationStart:
- location: bin/deployment/migrate
timeout: 300
- location: bin/deployment/start
timeout: 3600
ValidateService:
- location: bin/deployment/health_check
timeout: 3600

@ -0,0 +1,119 @@
#!/usr/bin/env bash
set -x
# Log a timestamped message to the console
function log() {
ts=$(date '+%Y-%m-%dT%H:%M:%SZ')
printf '%s [bin/deploy] %s\n' "$ts" "$1"
}
# Log an error message to the console and exit
function error() {
log "$1"
exit 1
}
# Perform the deployment for a specific chain
function deploy_chain() {
chain="$1"
if [ -z "$chain" ]; then
error "Expected a chain name as the first argument to 'deploy_chain', but did not get one!"
fi
chain_index="$2"
if [ -z "$chain_index" ]; then
error "Expected a chain index as the second argument to 'deploy_chain', but did not get one!"
fi
log "Creating deployment for chain '${chain}'.."
ts="$(date --utc '+%Y-%m-%dT%H:%M:%SZ')"
app="${PREFIX}-explorer"
bucket="${PREFIX}-explorer-codedeploy-releases"
release_name="${CIRCLE_SHA1}_${CIRCLE_BUILD_NUM}"
log "Pushing new revision to CodeDeploy app '${app}' in S3 bucket '${bucket}', as '${release_name}.zip'.."
aws deploy push \
--description="${PREFIX} release at commit ${CIRCLE_SHA1} via build ${CIRCLE_BUILD_NUM} at ${ts}" \
--application-name="${app}" \
--s3-location="s3://${bucket}/${release_name}.zip" \
--source=./
log "Push successful!"
deploy_config="CodeDeployDefault.OneAtATime"
deploy_group="${PREFIX}-explorer-dg${chain_index}"
log "Creating deployment for CodeDeploy app '${app}', using deployment config ${deploy_config}, and group ${deploy_group}"
aws create-deployment \
--description="${PREFIX} deployment of commit ${CIRCLE_SHA1} via build ${CIRCLE_BUILD_NUM} at ${ts}" \
--application-name="${app}" \
--deployment-config-name="${deploy_config}" \
--deployment-group-name="${deploy_group}" \
--s3-location="bucket=${bucket},key=${release_name}.zip,bundleType=zip"
log 'Deployment successfully created!'
log 'You may check deploy progress via the AWS Console or AWS CLI using the deployment ID shown above.'
return 0
}
# Make sure we got an environment as an argument to this script
DEPLOY_ENV="$1"
if [ -z "$DEPLOY_ENV" ]; then
error "Expected deployment environment as an argument, but none was provided!"
fi
# Convert it to uppercase for environment variable lookups
DEPLOY_ENV="$(echo "$DEPLOY_ENV" | tr '[:lower:]' '[:upper:]')"
log "Deploying to environment '${DEPLOY_ENV}'"
# Make sure we have credentials set
log "Verifying credentials.."
if [ -z "$AWS_ACCESS_KEY_ID" ] || [ -z "$AWS_SECRET_ACCESS_KEY" ]; then
error "Unable to perform deploy: missing AWS credentials!"
fi
# Lookup the infrastructure prefix for the target system in the environment
log "Verifying infrastructure prefix.."
PREFIX_VAR="AWS_${DEPLOY_ENV}_PREFIX"
PREFIX="${!PREFIX_VAR}"
if [ -z "$PREFIX" ]; then
error "Unknown deploy environment '$DEPLOY_ENV', or AWS_${DEPLOY_ENV}_PREFIX is unset!"
exit 1
fi
# Lookup the list of chains for the target system in the environment
log "Verifying deployment groups.."
CHAINS_VAR="AWS_${DEPLOY_ENV}_CHAINS"
CHAINS="${!CHAINS_VAR}"
if [ -z "$CHAINS" ]; then
error "AWS_${DEPLOY_ENV}_CHAINS is unset!"
fi
# Convert the comma-separated list of names into a newline-separated list of names
CHAINS="$(echo "$CHAINS" | tr ',' '\n')"
# Install AWS CLI
if ! which aws >/dev/null; then
log "Installing AWS CLI.."
mkdir -p ~/bin
wget "https://s3.amazonaws.com/aws-cli/awscli-bundle.zip"
unzip awscli-bundle.zip
./awscli-bundle/install -b ~/bin/aws
export PATH=$HOME/bin:$PATH
log "Install completed successfully!"
fi
# For each chain perform a deployment
i=0
for chain in $CHAINS; do
deploy_chain "$chain" "$i"
i=$((i+1))
done
log "Deployment task has succesfully completed!"
exit 0

@ -0,0 +1,16 @@
#!/usr/bin/env bash
set -x
cd /opt/app || exit 1
export MIX_ENV=prod
mix local.rebar --force
mix local.hex --force
mix deps.get
mix compile
exit 0

@ -0,0 +1,15 @@
#!/usr/bin/env bash
set -x
# Wait until an HTTP request succeeds against localhost:PORT
function ping_server(){
while true; do
if curl -sSf "http://localhost:${PORT:-80}" >/dev/null; then
exit 0
fi
done
}
# Timeout after 2 min if we still haven't gotten a response
timeout 120s ping_server

@ -0,0 +1,9 @@
#!/usr/bin/env bash
set -x
cd /opt/app || exit 1
mix ecto.migrate
exit 0

@ -0,0 +1,7 @@
#!/usr/bin/env bash
set -x
systemctl start explorer.service
exit 0

@ -0,0 +1,9 @@
#!/usr/bin/env bash
set -x
if systemctl is-active explorer.service; then
systemctl stop explorer.service
fi
exit 0
Loading…
Cancel
Save