diff --git a/Jenkinsfile b/Jenkinsfile index 32495ca..a846962 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -31,11 +31,7 @@ def wrap = { fn-> variable: 'GOOGLE_APPLICATION_CREDENTIALS_OVERRIDE')]) { withCredentials([string(credentialsId: 'newrelic.license.key', variable: 'NEWRELIC_LICENSE_KEY_OVERRIDE')]) { - sh (""" - cp env.sh.sample env.sh - rm -rf build - mkdir build - """) + sh ("bin/clean-workspace.sh") fn() } } @@ -182,7 +178,7 @@ stage('Build CodeDeploy Archive') { node { unstash 'src' wrap.call({ - sh ("./codedeploy/bin/build.sh") + sh ("./bin/build-codedeploy.sh") }) } } diff --git a/ansible/bakery.yml b/ansible/bakery.yml index 606dcc1..59827fe 100644 --- a/ansible/bakery.yml +++ b/ansible/bakery.yml @@ -14,7 +14,7 @@ nrinfragent_os_version: 7 nrinfragent_config: license_key: ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ - log_file: /var/log/newrelic/nr-infra.log + log_file: /var/log/newrelic-infra/nr-infra.log log_to_stdout: false - name: Install Web Application diff --git a/ansible/newrelic-infrastructure.yml b/ansible/newrelic-infrastructure.yml new file mode 100644 index 0000000..b0ec75d --- /dev/null +++ b/ansible/newrelic-infrastructure.yml @@ -0,0 +1,20 @@ +--- +# Use ansible to install the newrelic infra agent. + +# Thanks https://www.tricksofthetrades.net/2017/10/02/ansible-local-playbooks/ for +# the trick on installing locally using "hosts: 127.0.0.1" and "connection:local" + +- name: Set the newrelic license key + hosts: 127.0.0.1 + connection: local + become: yes + tasks: + - command: bash /app/bin/set-newrelic-license-key.sh + +- name: Restart newrelic + hosts: 127.0.0.1 + connection: local + become: yes + tasks: + - command: service newrelic-infra restart + \ No newline at end of file diff --git a/codedeploy/bin/build.sh b/bin/build-codedeploy.sh similarity index 78% rename from codedeploy/bin/build.sh rename to bin/build-codedeploy.sh index e61b0de..126fe6c 100755 --- a/codedeploy/bin/build.sh +++ b/bin/build-codedeploy.sh @@ -13,11 +13,9 @@ export PS4='+(${BASH_SOURCE}:${LINENO}): ${FUNCNAME[0]:+${FUNCNAME[0]}(): }' DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" BASE_DIR="$DIR/.." BUILD_DIR="$BASE_DIR/build" -ANSIBLE_DIR="$BASE_DIR/../ansible" -APPLICTION_DIR="$BASE_DIR/../application" -SRC_DIR="$BASE_DIR/../src" -VENV_DIR="$BASE_DIR/../venv" -DOCKER_DIR="$BASE_DIR/.." +ANSIBLE_DIR="$BASE_DIR/ansible" +APPLICTION_DIR="$BASE_DIR/application" +SRC_DIR="$BASE_DIR/src" GIT_REV="$(git rev-parse --short HEAD)" BUILD_NUMBER=${BUILD_NUMBER:-0} @@ -39,20 +37,22 @@ fi mkdir -p "$BUILD_DIR/socket" echo Build docker container $CONTAINERNAME -docker build -f=Dockerfile -t "$CONTAINERNAME" "$DOCKER_DIR" +docker build -f=Dockerfile -t "$CONTAINERNAME" "$BASE_DIR" echo Create python virtual environment -docker run --rm -v "$DOCKER_DIR:/src" "$CONTAINERNAME" /bin/bash -c \ - "mkdir -p /src/venv ; \ - cp -fa /app/venv/* /src/venv" +docker run \ + --rm \ + -v "$BASE_DIR:/src" \ + "$CONTAINERNAME" \ + /bin/bash -c \ + "mkdir -p /src/build/venv ; \ + cp -fa /app/venv/* /src/build/venv" SOURCES="$BASE_DIR/bin $ANSIBLE_DIR $APPLICTION_DIR $SRC_DIR -$BASE_DIR/appspec.yml -$BASE_DIR/bin -$VENV_DIR" +$BASE_DIR/codedeploy/appspec.yml" for src in $SOURCES; do cp -a "$src" "$BUILD_DIR" done @@ -70,7 +70,7 @@ done ) echo Remove docker generated files -docker run --rm -v "$DOCKER_DIR:/src" "$CONTAINERNAME" /bin/bash -c \ +docker run --rm -v "$BASE_DIR:/src" "$CONTAINERNAME" /bin/bash -c \ "rm -rf /src/venv" cd "$BUILD_DIR" diff --git a/bin/clean-workspace.sh b/bin/clean-workspace.sh new file mode 100755 index 0000000..a227196 --- /dev/null +++ b/bin/clean-workspace.sh @@ -0,0 +1,25 @@ +#!/usr/bin/env bash +# clean workspace +# +# Set bash unofficial strict mode http://redsymbol.net/articles/unofficial-bash-strict-mode/ +set -euo pipefail + +# Set DEBUG to true for enhanced debugging: run prefixed with "DEBUG=true" +${DEBUG:-false} && set -vx +# Credit to https://stackoverflow.com/a/17805088 +# and http://wiki.bash-hackers.org/scripting/debuggingtips +export PS4='+(${BASH_SOURCE}:${LINENO}): ${FUNCNAME[0]:+${FUNCNAME[0]}(): }' + +# Credit to http://stackoverflow.com/a/246128/424301 +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +BASE_DIR="$DIR/.." +BUILD_DIR="$BASE_DIR/build" +export BASE_DIR + +# shellcheck disable=SC1090 +. "$DIR/common.sh" + +cp "$BASE_DIR/env.sh.sample" "$BASE_DIR/env.sh" +clean_root_owned_docker_files +rm -rf "$BUILD_DIR" +mkdir "$BUILD_DIR" diff --git a/codedeploy/bin/AfterInstall.sh b/bin/codedeploy/AfterInstall.sh similarity index 98% rename from codedeploy/bin/AfterInstall.sh rename to bin/codedeploy/AfterInstall.sh index 93d1db5..2fcbca4 100755 --- a/codedeploy/bin/AfterInstall.sh +++ b/bin/codedeploy/AfterInstall.sh @@ -16,7 +16,7 @@ export PS4='+(${BASH_SOURCE}:${LINENO}): ${FUNCNAME[0]:+${FUNCNAME[0]}(): }' # Credit to http://stackoverflow.com/a/246128/424301 DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -BASE_DIR="$DIR/.." +BASE_DIR="$DIR/../.." ANSIBLE_DIR="$BASE_DIR/ansible" # Invoke Ansible for final set up diff --git a/codedeploy/bin/ApplicationStart.sh b/bin/codedeploy/ApplicationStart.sh similarity index 97% rename from codedeploy/bin/ApplicationStart.sh rename to bin/codedeploy/ApplicationStart.sh index 5d08139..c2698ca 100755 --- a/codedeploy/bin/ApplicationStart.sh +++ b/bin/codedeploy/ApplicationStart.sh @@ -16,7 +16,7 @@ export PS4='+(${BASH_SOURCE}:${LINENO}): ${FUNCNAME[0]:+${FUNCNAME[0]}(): }' # Credit to http://stackoverflow.com/a/246128/424301 DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -BASE_DIR="$DIR/.." +BASE_DIR="$DIR/../.." ANSIBLE_DIR="$BASE_DIR/ansible" # Invoke Ansible for final set up diff --git a/codedeploy/bin/ApplicationStop.sh b/bin/codedeploy/ApplicationStop.sh similarity index 100% rename from codedeploy/bin/ApplicationStop.sh rename to bin/codedeploy/ApplicationStop.sh diff --git a/codedeploy/bin/BeforeInstall.sh b/bin/codedeploy/BeforeInstall.sh similarity index 100% rename from codedeploy/bin/BeforeInstall.sh rename to bin/codedeploy/BeforeInstall.sh diff --git a/codedeploy/bin/ValidateService.sh b/bin/codedeploy/ValidateService.sh similarity index 100% rename from codedeploy/bin/ValidateService.sh rename to bin/codedeploy/ValidateService.sh diff --git a/bin/set-newrelic-license-key.sh b/bin/set-newrelic-license-key.sh new file mode 100755 index 0000000..6d60f5b --- /dev/null +++ b/bin/set-newrelic-license-key.sh @@ -0,0 +1,30 @@ +#!/usr/bin/env bash +# Set the newrelic license key fron AWS credentials +# +# Set bash unofficial strict mode http://redsymbol.net/articles/unofficial-bash-strict-mode/ +set -euo pipefail + +# Set DEBUG to true for enhanced debugging: run prefixed with "DEBUG=true" +${DEBUG:-false} && set -vx +# Credit to https://stackoverflow.com/a/17805088 +# and http://wiki.bash-hackers.org/scripting/debuggingtips +export PS4='+(${BASH_SOURCE}:${LINENO}): ${FUNCNAME[0]:+${FUNCNAME[0]}(): }' + +# Credit to http://stackoverflow.com/a/246128/424301 +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +BASE_DIR="$DIR/.." +export BASE_DIR + +NEWRELIC_CONFIG_FILE="/etc/newrelic-infra.yml" +# Thanks Stack Overflow https://stackoverflow.com/a/9735663/424301 +EC2_AVAIL_ZONE=$(curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone) +EC2_REGION="$(sed 's/[a-z]$//' <<<"$EC2_AVAIL_ZONE")" + +NEWRELIC_LICENSE_KEY=$(aws secretsmanager get-secret-value \ + --region="$EC2_REGION" \ + --secret-id newrelic_license \ + --output text \ + --query '[SecretString]') + +cp -a "${NEWRELIC_CONFIG_FILE}" "${NEWRELIC_CONFIG_FILE}.orig" +sed "s/ZZZZ*ZZZZ/${NEWRELIC_LICENSE_KEY}/" "${NEWRELIC_CONFIG_FILE}.orig" > "${NEWRELIC_CONFIG_FILE}" diff --git a/codedeploy/appspec.yml b/codedeploy/appspec.yml index e0f94aa..6c7275f 100644 --- a/codedeploy/appspec.yml +++ b/codedeploy/appspec.yml @@ -6,19 +6,23 @@ files: destination: /app/application - source: src destination: /app/src + - source: bin + destination: /app/bin + - source: ansible + destination: /app/ansible hooks: ApplicationStop: - - location: bin/ApplicationStop.sh + - location: bin/codedeploy/ApplicationStop.sh timeout: 600 BeforeInstall: - - location: bin/BeforeInstall.sh + - location: bin/codedeploy/BeforeInstall.sh timeout: 30 AfterInstall: - - location: bin/AfterInstall.sh + - location: bin/codedeploy/AfterInstall.sh timeout: 300 ApplicationStart: - - location: bin/ApplicationStart.sh + - location: bin/codedeploy/ApplicationStart.sh timeout: 120 ValidateService: - - location: bin/ValidateService.sh + - location: bin/codedeploy/ValidateService.sh timeout: 60 diff --git a/terraform/cloud-config.yml b/terraform/cloud-config.yml index 3872c61..9e449bb 100644 --- a/terraform/cloud-config.yml +++ b/terraform/cloud-config.yml @@ -1,3 +1,3 @@ #cloud-config runcmd: - - sudo -u centos ansible-playbook -l localhost /app/ansible/codedeploy.yml + - ansible-playbook -l localhost /app/ansible/codedeploy.yml /app/ansible/newrelic-infrastructure.yml