From eaac2e597bb85623e5981467e773732db11fc785 Mon Sep 17 00:00:00 2001 From: Richard Bullington-McGuire Date: Fri, 8 Nov 2019 00:14:23 -0500 Subject: [PATCH 01/55] Started work on bsidesct conference preso --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 8d432ca..73a18f0 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,10 @@ See the branch [demo-20180926](https://github.com/ModusCreateOrg/devops-infra-de See the branch [demo-20181205](https://github.com/ModusCreateOrg/devops-infra-demo/tree/demo-20181205) for the code for the demo for the [Ansible NYC talk _Ansible Image Bakeries: Best Practices & Pitfalls_](https://www.meetup.com/Ansible-NYC/events/256728741/). Slides from this presentation are on [SlideShare](https://www.slideshare.net/RichardBullingtonMcG/ansible-image-bakeries-best-practices-and-pitfalls). -See the branch [demo-20190130](https://github.com/ModusCreateOrg/devops-infra-demo/tree/demo-20180130) for the code for the demo for the [Big Apple DevOps talk _Monitoring and Alerting as code with Terraform and New Relic_](https://www.meetup.com/Big-Apple-DevOps/events/257744262/). Slides from this presentation are on [Slideshare](https://www.slideshare.net/RichardBullingtonMcG/monitoring-and-alerting-as-code-with-terraform-and-new-relic). +See the branch [demo-20190130](https://github.com/ModusCreateOrg/devops-infra-demo/tree/demo-20190130) for the code for the demo for the [Big Apple DevOps talk _Monitoring and Alerting as code with Terraform and New Relic_](https://www.meetup.com/Big-Apple-DevOps/events/257744262/). Slides from this presentation are on [Slideshare](https://www.slideshare.net/RichardBullingtonMcG/monitoring-and-alerting-as-code-with-terraform-and-new-relic). + +See the branch [demo-20191109](https://github.com/ModusCreateOrg/devops-infra-demo/tree/demo-20191l09) for the code for the demo for the [BSidesCT 2019 talk g Apple DevOps talk _Extensible DevSecOps pipelines with Jenkins, Docker, Terraform, and a kitchen sink full of scanners_](https://bsidesct.org/schedule/). Slides from this presentation are on +[Slideshare](https://www.slideshare.net/RichardBullingtonMcG/extensible-devsecops-pipelines-with-jenkins-docker-terrraform-and-a-kitchen-sink-full-of-scanners) Instructions ------------ From 6bb953c58c4aa8417b20be5522e298a142778b68 Mon Sep 17 00:00:00 2001 From: Richard Bullington-McGuire Date: Fri, 8 Nov 2019 00:47:40 -0500 Subject: [PATCH 02/55] Stub in new variables for build --- Jenkinsfile | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/Jenkinsfile b/Jenkinsfile index bd300fb..e012fab 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -55,6 +55,11 @@ properties([ defaultValue: false, description: 'Run Packer for this build?' ), + booleanParam( + name: 'Package_CodeDeploy', + defaultValue: false, + description: 'Package CodeDeploy application on this build?' + ), booleanParam( name: 'Apply_Terraform', defaultValue: false, @@ -79,6 +84,12 @@ properties([ Put one variable per line, in JSON or HCL like this: associate_public_ip_address = "true"''' ), + string( + name: 'CodeDeploy_Target', + defaultValue: '', + description: '''Deploy either a specific build's CodeDeploy archive (specify build number) + or the latest archive (specify "latest")''' + ), booleanParam( name: 'Rotate_Servers', defaultValue: false, @@ -122,7 +133,7 @@ properties([ stage('Preflight') { // Check CAPTCHA - def should_validate_captcha = params.Run_Packer || params.Apply_Terraform || params.Destroy_Terraform || params.Run_JMeter + def should_validate_captcha = params.Run_Packer || params.Apply_Terraform || params.Destroy_Terraform || params.Run_JMeter || params.CodeDeploy_Target if (should_validate_captcha) { if (params.CAPTCHA_Guess == null || params.CAPTCHA_Guess == "") { @@ -137,6 +148,20 @@ stage('Preflight') { } else { echo "No CAPTCHA required, continuing" } + + def build_number = ${env.BUILD_NUMBER} as Long + switch (params.CodeDeploy_Target.toLowerCase()) { + case "latest": + echo "CodeDeploy targeting latest build" + break + case { it instanceof Integer && it > 0 && it <= build_number }: + echo "CodeDeploy targeting build ${build_number}" + break + default: + throw Exception("CodeDeploy build_number ${build_number} is not understood") + break + } + } stage('Checkout') { From 133819fe9ad6ac3beb83325cd4e74fcab417e058 Mon Sep 17 00:00:00 2001 From: Richard Bullington-McGuire Date: Sat, 9 Nov 2019 00:27:44 -0500 Subject: [PATCH 03/55] Try to fix syntax issue --- Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jenkinsfile b/Jenkinsfile index e012fab..ea3f1c0 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -149,7 +149,7 @@ stage('Preflight') { echo "No CAPTCHA required, continuing" } - def build_number = ${env.BUILD_NUMBER} as Long + def build_number = env.BUILD_NUMBER as Long switch (params.CodeDeploy_Target.toLowerCase()) { case "latest": echo "CodeDeploy targeting latest build" From 4f721bd78de811379bcb8ccd50835e51a95f047c Mon Sep 17 00:00:00 2001 From: Richard Bullington-McGuire Date: Sat, 9 Nov 2019 00:35:29 -0500 Subject: [PATCH 04/55] Try different strategy for case --- Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jenkinsfile b/Jenkinsfile index ea3f1c0..5e53722 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -154,7 +154,7 @@ stage('Preflight') { case "latest": echo "CodeDeploy targeting latest build" break - case { it instanceof Integer && it > 0 && it <= build_number }: + case 1..build_number: echo "CodeDeploy targeting build ${build_number}" break default: From 1e63d881a2c40092072bf2be996e963bef0838b8 Mon Sep 17 00:00:00 2001 From: Richard Bullington-McGuire Date: Sat, 9 Nov 2019 00:48:02 -0500 Subject: [PATCH 05/55] Stub in Package_CodeDeploy conditional --- Jenkinsfile | 41 ++++++++++++++++++++++++++++++++--------- 1 file changed, 32 insertions(+), 9 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 5e53722..bb660e5 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -11,6 +11,7 @@ import java.util.Random // Set default variables final default_timeout_minutes = 20 +final codedeploy_target_skip = -1 /** Set up CAPTCHA*/ def get_captcha(Long hash_const) { @@ -150,18 +151,27 @@ stage('Preflight') { } def build_number = env.BUILD_NUMBER as Long + Long codedeploy_target + switch (params.CodeDeploy_Target.toLowerCase()) { + case "": + echo "CodeDeploy target is blank, skipping codedeploy step" + codedeploy_target = codedeploy_target_skip + break case "latest": - echo "CodeDeploy targeting latest build" + // when codedeploy_target > build number, count backwards + codedeploy_target = build_number + 1 + echo "CodeDeploy targeting latest build (will look for build <= ${build_number}" break case 1..build_number: echo "CodeDeploy targeting build ${build_number}" + codedeploy_target = build_number break default: - throw Exception("CodeDeploy build_number ${build_number} is not understood") + currentBuild.result = 'ABORTED' + error "CodeDeploy build_number ${build_number} is not understood" break } - } stage('Checkout') { @@ -216,12 +226,14 @@ if (params.Run_Packer) { } } -stage('Build CodeDeploy Archive') { - node { - wrap.call({ - unstash 'src' - sh ("./bin/build-codedeploy.sh") - }) +if (params.Package_CodeDeploy) { + stage('Package CodeDeploy Archive') { + node { + wrap.call({ + unstash 'src' + sh ("./bin/build-codedeploy.sh") + }) + } } } @@ -277,6 +289,17 @@ if (params.Rotate_Servers) { } } +if (params.Rotate_Servers) { + stage('Rotate Servers') { + node { + wrap.call({ + unstash 'src' + sh ("./bin/rotate-asg.sh infra-demo-asg") + }) + } + } +} + if (params.Run_JMeter) { stage('Run JMeter') { node { From c003e77e5e201350b36c43d309247c7df0a60f0f Mon Sep 17 00:00:00 2001 From: Richard Bullington-McGuire Date: Sat, 9 Nov 2019 01:22:21 -0500 Subject: [PATCH 06/55] Add s3 prefix for branch name for CD artifact --- Jenkinsfile | 11 ++++++++--- bin/build-codedeploy.sh | 4 +++- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index bb660e5..6b9abf3 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -12,6 +12,8 @@ import java.util.Random // Set default variables final default_timeout_minutes = 20 final codedeploy_target_skip = -1 +// See generally safe key names from https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingMetadata.html +final s3_safe_branch_name = env.BRANCH_NAME.replaceAll(/[^0-9a-zA-Z!\-_\.\*\'()], "_") /** Set up CAPTCHA*/ def get_captcha(Long hash_const) { @@ -161,10 +163,13 @@ stage('Preflight') { case "latest": // when codedeploy_target > build number, count backwards codedeploy_target = build_number + 1 - echo "CodeDeploy targeting latest build (will look for build <= ${build_number}" + echo """CodeDeploy: targeting latest build + CodeDeploy: Will look for build <= ${build_number} + CodeDeploy: Will use prefix ${s3_safe_branch_name}""" break case 1..build_number: - echo "CodeDeploy targeting build ${build_number}" + echo """CodeDeploy: targeting build ${build_number} for ${env.BRANCH_NAME} + CodeDeploy: Will use name ${s3_safe_build_number}-${build_number}""" codedeploy_target = build_number break default: @@ -231,7 +236,7 @@ if (params.Package_CodeDeploy) { node { wrap.call({ unstash 'src' - sh ("./bin/build-codedeploy.sh") + sh ("./bin/build-codedeploy.sh ${s3_safe_branch_name}") }) } } diff --git a/bin/build-codedeploy.sh b/bin/build-codedeploy.sh index 126fe6c..22d46a8 100755 --- a/bin/build-codedeploy.sh +++ b/bin/build-codedeploy.sh @@ -19,10 +19,12 @@ SRC_DIR="$BASE_DIR/src" GIT_REV="$(git rev-parse --short HEAD)" BUILD_NUMBER=${BUILD_NUMBER:-0} -ARCHIVE="codedeploy-$BUILD_NUMBER-$GIT_REV.zip" +BRANCH_PREFIX=${1:-master} +ARCHIVE="codedeploy-$BRANCH_PREFIX-$BUILD_NUMBER-$GIT_REV.zip" CONTAINERNAME=infra-demo echo "GIT_REV=$GIT_REV" +echo "BRANCH_PREFIX=$BUILD_NUMBER" echo "BUILD_NUMBER=$BUILD_NUMBER" echo "ARCHIVE=$ARCHIVE" From 7c64607d839e7b469a112bdf1ab5606b6795c56e Mon Sep 17 00:00:00 2001 From: Richard Bullington-McGuire Date: Sat, 9 Nov 2019 01:26:32 -0500 Subject: [PATCH 07/55] Scaffolding for CodeDeploy --- Jenkinsfile | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 6b9abf3..b4d7369 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -63,6 +63,15 @@ properties([ defaultValue: false, description: 'Package CodeDeploy application on this build?' ), + string( + name: 'CodeDeploy_Target', + defaultValue: '', + description: '''Deploy a CodeDeploy archive. + Specify one of the following: + 1. "latest" - deploy the latest build from this branch + 2. a build number - deploy that build number from this branch + 3. a full S3 URL''' + ), booleanParam( name: 'Apply_Terraform', defaultValue: false, @@ -87,12 +96,6 @@ properties([ Put one variable per line, in JSON or HCL like this: associate_public_ip_address = "true"''' ), - string( - name: 'CodeDeploy_Target', - defaultValue: '', - description: '''Deploy either a specific build's CodeDeploy archive (specify build number) - or the latest archive (specify "latest")''' - ), booleanParam( name: 'Rotate_Servers', defaultValue: false, From bc9f2d01933667cc2b0f987cd18678be77d357a5 Mon Sep 17 00:00:00 2001 From: Richard Bullington-McGuire Date: Sat, 9 Nov 2019 01:27:34 -0500 Subject: [PATCH 08/55] Fix up syntax --- Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jenkinsfile b/Jenkinsfile index b4d7369..bf9f231 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -13,7 +13,7 @@ import java.util.Random final default_timeout_minutes = 20 final codedeploy_target_skip = -1 // See generally safe key names from https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingMetadata.html -final s3_safe_branch_name = env.BRANCH_NAME.replaceAll(/[^0-9a-zA-Z!\-_\.\*\'()], "_") +final s3_safe_branch_name = env.BRANCH_NAME.replaceAll(/[^0-9a-zA-Z!\-_\.\*\'\(\)], "_") /** Set up CAPTCHA*/ def get_captcha(Long hash_const) { From 250e17c6cc162afb8973bdd1ec9754e36d485803 Mon Sep 17 00:00:00 2001 From: Richard Bullington-McGuire Date: Sat, 9 Nov 2019 01:30:31 -0500 Subject: [PATCH 09/55] Fix syntax --- Jenkinsfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Jenkinsfile b/Jenkinsfile index bf9f231..8fc0d2d 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -13,7 +13,8 @@ import java.util.Random final default_timeout_minutes = 20 final codedeploy_target_skip = -1 // See generally safe key names from https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingMetadata.html -final s3_safe_branch_name = env.BRANCH_NAME.replaceAll(/[^0-9a-zA-Z!\-_\.\*\'\(\)], "_") +//final s3_safe_branch_name = env.BRANCH_NAME.replaceAll(/[^0-9a-zA-Z\!\-_\.\*\'\(\)], "_") +final s3_safe_branch_name = env.BRANCH_NAME.replaceAll(/[^0-9a-zA-Z\!\-_\.\*\'\(\)]/ , "_") /** Set up CAPTCHA*/ def get_captcha(Long hash_const) { From 6b7380812cb0f8c78b46ef90cbf08fd715719c3c Mon Sep 17 00:00:00 2001 From: Richard Bullington-McGuire Date: Sat, 9 Nov 2019 01:40:56 -0500 Subject: [PATCH 10/55] Use error macro --- Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jenkinsfile b/Jenkinsfile index 8fc0d2d..96a4b2e 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -144,7 +144,7 @@ stage('Preflight') { if (should_validate_captcha) { if (params.CAPTCHA_Guess == null || params.CAPTCHA_Guess == "") { - throw new Exception("No CAPTCHA guess detected, try again!") + error "No CAPTCHA guess detected, try again!" } def guess = params.CAPTCHA_Guess as Long def hash = params.CAPTCHA_Hash as Long From e4a64c5757db4eb582cbfb705fc73d52e185e14b Mon Sep 17 00:00:00 2001 From: Richard Bullington-McGuire Date: Sat, 9 Nov 2019 01:44:00 -0500 Subject: [PATCH 11/55] Fix up output --- bin/build-codedeploy.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/build-codedeploy.sh b/bin/build-codedeploy.sh index 22d46a8..2afb714 100755 --- a/bin/build-codedeploy.sh +++ b/bin/build-codedeploy.sh @@ -24,7 +24,7 @@ ARCHIVE="codedeploy-$BRANCH_PREFIX-$BUILD_NUMBER-$GIT_REV.zip" CONTAINERNAME=infra-demo echo "GIT_REV=$GIT_REV" -echo "BRANCH_PREFIX=$BUILD_NUMBER" +echo "BRANCH_PREFIX=$BRANCH_PREFIX" echo "BUILD_NUMBER=$BUILD_NUMBER" echo "ARCHIVE=$ARCHIVE" From 1079a54b7baebb1134a99b62d478e5777c3050d1 Mon Sep 17 00:00:00 2001 From: Richard Bullington-McGuire Date: Sat, 9 Nov 2019 02:21:02 -0500 Subject: [PATCH 12/55] First cut of deploy --- bin/build-codedeploy.sh | 9 +++--- bin/deploy-codedeploy.sh | 66 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+), 4 deletions(-) create mode 100755 bin/deploy-codedeploy.sh diff --git a/bin/build-codedeploy.sh b/bin/build-codedeploy.sh index 2afb714..3612b3e 100755 --- a/bin/build-codedeploy.sh +++ b/bin/build-codedeploy.sh @@ -22,16 +22,17 @@ BUILD_NUMBER=${BUILD_NUMBER:-0} BRANCH_PREFIX=${1:-master} ARCHIVE="codedeploy-$BRANCH_PREFIX-$BUILD_NUMBER-$GIT_REV.zip" CONTAINERNAME=infra-demo +# Thanks https://stackoverflow.com/questions/33791069/quick-way-to-get-aws-account-number-from-the-cli-tools +AWS_ACCOUNT_ID=$(aws sts get-caller-identity --output text --query 'Account') +BUCKET="codedeploy-$AWS_ACCOUNT_ID" +S3_URL="s3://$BUCKET/$ARCHIVE" echo "GIT_REV=$GIT_REV" echo "BRANCH_PREFIX=$BRANCH_PREFIX" echo "BUILD_NUMBER=$BUILD_NUMBER" echo "ARCHIVE=$ARCHIVE" +echo "S3_URL=$S3_URL" -# Thanks https://stackoverflow.com/questions/33791069/quick-way-to-get-aws-account-number-from-the-cli-tools -AWS_ACCOUNT_ID=$(aws sts get-caller-identity --output text --query 'Account') -BUCKET="codedeploy-$AWS_ACCOUNT_ID" -S3_URL="s3://$BUCKET/$ARCHIVE" if [[ -d "$BUILD_DIR" ]]; then rm -rf "$BUILD_DIR" diff --git a/bin/deploy-codedeploy.sh b/bin/deploy-codedeploy.sh new file mode 100755 index 0000000..68e2b27 --- /dev/null +++ b/bin/deploy-codedeploy.sh @@ -0,0 +1,66 @@ +#!/usr/bin/env bash + +# 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" +ANSIBLE_DIR="$BASE_DIR/ansible" +APPLICTION_DIR="$BASE_DIR/application" +SRC_DIR="$BASE_DIR/src" + +BUILD_NUMBER=${BUILD_NUMBER:-0} +PARAM=${1:-} +BRANCH_PREFIX=${2:-master} +APP_NAME=${3:-tf-infra-demo-app} +DEPLOYMENT_GROUP_NAME=${4:-dev} + +# Thanks https://stackoverflow.com/questions/33791069/quick-way-to-get-aws-account-number-from-the-cli-tools +AWS_ACCOUNT_ID=$(aws sts get-caller-identity --output text --query 'Account') +BUCKET="codedeploy-$AWS_ACCOUNT_ID" + + +case $PARAM in +latest) + Message="CodeDeploy: finding latest build for $BRANCH_PREFIX" + ARCHIVE="s3://$BUCKET/$(aws s3 ls "$BUCKET/codedeploy-$BRANCH_PREFIX-" | sort | tail -1 | cut -f 6)" + S3_URL="s3://$BUCKET/$ARCHIVE" + ;; +[0-9][0-9]+) + ARCHIVE="$(aws s3 ls "$BUCKET/codedeploy-$BRANCH_PREFIX-" | sort | tail -1)" + S3_URL="s3://$BUCKET/$ARCHIVE" + ;; +s3[:]//[a-z0-9]*) + S3_URL="$PARAM" + ARCHIVE=$(cut -d/ -f 3- <<<"$S3_URL") + ;; +*) + echo "ERROR: Unknown format for $PARAM, exiting" + exit 1 + ;; +esac + + +echo "BRANCH_PREFIX=$BRANCH_PREFIX" +echo "BUILD_NUMBER=$BUILD_NUMBER" +echo "ARCHIVE=$ARCHIVE" +echo "S3_URL=$S3_URL" + + +DEPLOYMENT=$(aws deploy create-deployment \ + --output table \ + --application-name "$APP_NAME" \ + --deployment-group-name "$DEPLOYMENT_GROUP_NAME" \ + --description "deployment initiated by deploy-codedeploy.sh" \ + --no-ignore-application-stop-failures \ + --s3-location "$S3_URL") +echo "CodeDeploy: deployment started $DEPLOYMENT" +echo "CodeDeploy: see https://console.aws.amazon.com/codesuite/codedeploy/deployments/$DEPLOYMENT" From 6dc0db2347be082aa6e1aed1b731f38752d037d1 Mon Sep 17 00:00:00 2001 From: Richard Bullington-McGuire Date: Sat, 9 Nov 2019 02:23:50 -0500 Subject: [PATCH 13/55] Hook up deploy --- Jenkinsfile | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Jenkinsfile b/Jenkinsfile index 96a4b2e..94e5ebc 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -298,6 +298,18 @@ if (params.Rotate_Servers) { } } +if (params.Deploy_CodeDeploy) { + stage('DeployCodeDeploy Archive') { + node { + wrap.call({ + unstash 'src' + sh ("./bin/deploy-codedeploy.sh ${codedeploy_target} ${s3_safe_branch_name}") + }) + } + } +} + + if (params.Rotate_Servers) { stage('Rotate Servers') { node { From 9c0696955fe3cd8bd0d43487ba1f61fe886964ff Mon Sep 17 00:00:00 2001 From: Richard Bullington-McGuire Date: Sat, 9 Nov 2019 02:26:47 -0500 Subject: [PATCH 14/55] Fix shellcheck linting issues --- bin/deploy-codedeploy.sh | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/bin/deploy-codedeploy.sh b/bin/deploy-codedeploy.sh index 68e2b27..3360d4f 100755 --- a/bin/deploy-codedeploy.sh +++ b/bin/deploy-codedeploy.sh @@ -9,14 +9,6 @@ ${DEBUG:-false} && set -vx # 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" -ANSIBLE_DIR="$BASE_DIR/ansible" -APPLICTION_DIR="$BASE_DIR/application" -SRC_DIR="$BASE_DIR/src" - BUILD_NUMBER=${BUILD_NUMBER:-0} PARAM=${1:-} BRANCH_PREFIX=${2:-master} @@ -30,7 +22,7 @@ BUCKET="codedeploy-$AWS_ACCOUNT_ID" case $PARAM in latest) - Message="CodeDeploy: finding latest build for $BRANCH_PREFIX" + echo "CodeDeploy: finding latest build for $BRANCH_PREFIX" ARCHIVE="s3://$BUCKET/$(aws s3 ls "$BUCKET/codedeploy-$BRANCH_PREFIX-" | sort | tail -1 | cut -f 6)" S3_URL="s3://$BUCKET/$ARCHIVE" ;; From dd146d1e0d276600d5271a2fb4aa12bf0e978179 Mon Sep 17 00:00:00 2001 From: Richard Bullington-McGuire Date: Sat, 9 Nov 2019 02:31:26 -0500 Subject: [PATCH 15/55] Fix up deployment hopefully --- Jenkinsfile | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 94e5ebc..214c950 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -65,7 +65,7 @@ properties([ description: 'Package CodeDeploy application on this build?' ), string( - name: 'CodeDeploy_Target', + name: 'Deploy_CodeDeploy', defaultValue: '', description: '''Deploy a CodeDeploy archive. Specify one of the following: @@ -159,21 +159,21 @@ stage('Preflight') { def build_number = env.BUILD_NUMBER as Long Long codedeploy_target - switch (params.CodeDeploy_Target.toLowerCase()) { + switch (params.Deploy_CodeDeploy.toLowerCase()) { case "": - echo "CodeDeploy target is blank, skipping codedeploy step" + echo "CodeDeploy deployment target is blank, skipping codedeploy step" codedeploy_target = codedeploy_target_skip break case "latest": // when codedeploy_target > build number, count backwards codedeploy_target = build_number + 1 echo """CodeDeploy: targeting latest build - CodeDeploy: Will look for build <= ${build_number} - CodeDeploy: Will use prefix ${s3_safe_branch_name}""" +CodeDeploy: Will look for build <= ${build_number} +CodeDeploy: Will use prefix ${s3_safe_branch_name}""" break case 1..build_number: echo """CodeDeploy: targeting build ${build_number} for ${env.BRANCH_NAME} - CodeDeploy: Will use name ${s3_safe_build_number}-${build_number}""" +CodeDeploy: Will use name ${s3_safe_build_number}-${build_number}""" codedeploy_target = build_number break default: From 9eb1a41a94a96bdac94c8a5553d955aa3a7c0629 Mon Sep 17 00:00:00 2001 From: Richard Bullington-McGuire Date: Sat, 9 Nov 2019 02:44:11 -0500 Subject: [PATCH 16/55] Skip logic fix, improve formatting --- Jenkinsfile | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 214c950..a59b911 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -15,6 +15,7 @@ final codedeploy_target_skip = -1 // See generally safe key names from https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingMetadata.html //final s3_safe_branch_name = env.BRANCH_NAME.replaceAll(/[^0-9a-zA-Z\!\-_\.\*\'\(\)], "_") final s3_safe_branch_name = env.BRANCH_NAME.replaceAll(/[^0-9a-zA-Z\!\-_\.\*\'\(\)]/ , "_") +def codedeploy_target = codedeploy_target_skip /** Set up CAPTCHA*/ def get_captcha(Long hash_const) { @@ -102,7 +103,7 @@ properties([ defaultValue: false, description: """Rotate server instances in Auto Scaling Group? You should do this if you changed ASG size or baked a new AMI. - """ + """ ), booleanParam( name: 'Run_JMeter', @@ -157,23 +158,23 @@ stage('Preflight') { } def build_number = env.BUILD_NUMBER as Long - Long codedeploy_target switch (params.Deploy_CodeDeploy.toLowerCase()) { case "": echo "CodeDeploy deployment target is blank, skipping codedeploy step" - codedeploy_target = codedeploy_target_skip break case "latest": // when codedeploy_target > build number, count backwards codedeploy_target = build_number + 1 echo """CodeDeploy: targeting latest build -CodeDeploy: Will look for build <= ${build_number} -CodeDeploy: Will use prefix ${s3_safe_branch_name}""" + CodeDeploy: Will look for build <= ${build_number} + CodeDeploy: Will use prefix ${s3_safe_branch_name} + """ break case 1..build_number: echo """CodeDeploy: targeting build ${build_number} for ${env.BRANCH_NAME} -CodeDeploy: Will use name ${s3_safe_build_number}-${build_number}""" + CodeDeploy: Will use name ${s3_safe_build_number}-${build_number} + """ codedeploy_target = build_number break default: From 23c10854ebfef7ff53fd79efbcc74941a8e99f69 Mon Sep 17 00:00:00 2001 From: Richard Bullington-McGuire Date: Sat, 9 Nov 2019 02:47:14 -0500 Subject: [PATCH 17/55] Fix regex --- bin/deploy-codedeploy.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/deploy-codedeploy.sh b/bin/deploy-codedeploy.sh index 3360d4f..4e36f31 100755 --- a/bin/deploy-codedeploy.sh +++ b/bin/deploy-codedeploy.sh @@ -26,7 +26,7 @@ latest) ARCHIVE="s3://$BUCKET/$(aws s3 ls "$BUCKET/codedeploy-$BRANCH_PREFIX-" | sort | tail -1 | cut -f 6)" S3_URL="s3://$BUCKET/$ARCHIVE" ;; -[0-9][0-9]+) +[0-9]*) ARCHIVE="$(aws s3 ls "$BUCKET/codedeploy-$BRANCH_PREFIX-" | sort | tail -1)" S3_URL="s3://$BUCKET/$ARCHIVE" ;; From 97b0f65d51140da22bae29fa69b906925438bfed Mon Sep 17 00:00:00 2001 From: Richard Bullington-McGuire Date: Sat, 9 Nov 2019 03:06:29 -0500 Subject: [PATCH 18/55] Fix up deploy, add scan to validate --- bin/codedeploy/ValidateService.sh | 4 ++++ bin/deploy-codedeploy.sh | 6 +++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/bin/codedeploy/ValidateService.sh b/bin/codedeploy/ValidateService.sh index 61a8c63..1da7788 100755 --- a/bin/codedeploy/ValidateService.sh +++ b/bin/codedeploy/ValidateService.sh @@ -25,4 +25,8 @@ check_every() { done } +echo "Checking web server availability" check_every 2 + +echo "Scanning with openscap and gauntlt" +bash /app/bin/ansible.sh scan-openscap.yml scan-gauntlt.yml diff --git a/bin/deploy-codedeploy.sh b/bin/deploy-codedeploy.sh index 4e36f31..db556a3 100755 --- a/bin/deploy-codedeploy.sh +++ b/bin/deploy-codedeploy.sh @@ -33,6 +33,7 @@ latest) s3[:]//[a-z0-9]*) S3_URL="$PARAM" ARCHIVE=$(cut -d/ -f 3- <<<"$S3_URL") + BUCKET==$(cut -d/ -f 2- <<<"$S3_URL") ;; *) echo "ERROR: Unknown format for $PARAM, exiting" @@ -41,10 +42,13 @@ s3[:]//[a-z0-9]*) esac +S3_SHORTHAND="bundleType=string,bucket=$BUCKET,key=$ARCHIVE" + echo "BRANCH_PREFIX=$BRANCH_PREFIX" echo "BUILD_NUMBER=$BUILD_NUMBER" echo "ARCHIVE=$ARCHIVE" echo "S3_URL=$S3_URL" +echo "S3_SHORTHAND=$S3_SHORTHAND" DEPLOYMENT=$(aws deploy create-deployment \ @@ -53,6 +57,6 @@ DEPLOYMENT=$(aws deploy create-deployment \ --deployment-group-name "$DEPLOYMENT_GROUP_NAME" \ --description "deployment initiated by deploy-codedeploy.sh" \ --no-ignore-application-stop-failures \ - --s3-location "$S3_URL") + --s3-location "$S3_SHORTHAND") echo "CodeDeploy: deployment started $DEPLOYMENT" echo "CodeDeploy: see https://console.aws.amazon.com/codesuite/codedeploy/deployments/$DEPLOYMENT" From 85129eb028ac0dd3de3a884ba525c3ec8ff86fb3 Mon Sep 17 00:00:00 2001 From: Richard Bullington-McGuire Date: Sat, 9 Nov 2019 03:08:06 -0500 Subject: [PATCH 19/55] fix syntax --- bin/deploy-codedeploy.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/deploy-codedeploy.sh b/bin/deploy-codedeploy.sh index db556a3..8e4537e 100755 --- a/bin/deploy-codedeploy.sh +++ b/bin/deploy-codedeploy.sh @@ -33,7 +33,7 @@ latest) s3[:]//[a-z0-9]*) S3_URL="$PARAM" ARCHIVE=$(cut -d/ -f 3- <<<"$S3_URL") - BUCKET==$(cut -d/ -f 2- <<<"$S3_URL") + BUCKET=$(cut -d/ -f 2- <<<"$S3_URL") ;; *) echo "ERROR: Unknown format for $PARAM, exiting" From 75f80656a861f631f9580283fb91487faa46ed40 Mon Sep 17 00:00:00 2001 From: Richard Bullington-McGuire Date: Sat, 9 Nov 2019 03:11:36 -0500 Subject: [PATCH 20/55] Fix default region --- bin/deploy-codedeploy.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/bin/deploy-codedeploy.sh b/bin/deploy-codedeploy.sh index 8e4537e..6693a66 100755 --- a/bin/deploy-codedeploy.sh +++ b/bin/deploy-codedeploy.sh @@ -52,6 +52,7 @@ echo "S3_SHORTHAND=$S3_SHORTHAND" DEPLOYMENT=$(aws deploy create-deployment \ + --region "$AWS_DEFAULT_REGION" \ --output table \ --application-name "$APP_NAME" \ --deployment-group-name "$DEPLOYMENT_GROUP_NAME" \ From 3731d9c3a956bf55caefe3262e0f6dabd21d20a0 Mon Sep 17 00:00:00 2001 From: Richard Bullington-McGuire Date: Sat, 9 Nov 2019 04:04:11 -0500 Subject: [PATCH 21/55] Add env.sh --- bin/deploy-codedeploy.sh | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/bin/deploy-codedeploy.sh b/bin/deploy-codedeploy.sh index 6693a66..dd4d854 100755 --- a/bin/deploy-codedeploy.sh +++ b/bin/deploy-codedeploy.sh @@ -9,6 +9,15 @@ ${DEBUG:-false} && set -vx # 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/.." + +# shellcheck disable=SC1090 +. "$DIR/common.sh" +#shellcheck disable=SC1090 +. "$BASE_DIR/env.sh" + BUILD_NUMBER=${BUILD_NUMBER:-0} PARAM=${1:-} BRANCH_PREFIX=${2:-master} From 1b01479cc0951fc2897e84c12571994a1f54d6eb Mon Sep 17 00:00:00 2001 From: Richard Bullington-McGuire Date: Sat, 9 Nov 2019 04:35:06 -0500 Subject: [PATCH 22/55] Fix up bundle type --- bin/deploy-codedeploy.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/deploy-codedeploy.sh b/bin/deploy-codedeploy.sh index dd4d854..ba77263 100755 --- a/bin/deploy-codedeploy.sh +++ b/bin/deploy-codedeploy.sh @@ -51,7 +51,7 @@ s3[:]//[a-z0-9]*) esac -S3_SHORTHAND="bundleType=string,bucket=$BUCKET,key=$ARCHIVE" +S3_SHORTHAND="bundleType=zip,bucket=$BUCKET,key=$ARCHIVE" echo "BRANCH_PREFIX=$BRANCH_PREFIX" echo "BUILD_NUMBER=$BUILD_NUMBER" From 7b1135a3144f5c8fed7d6a742772574e9afef75c Mon Sep 17 00:00:00 2001 From: Richard Bullington-McGuire Date: Sat, 9 Nov 2019 04:42:39 -0500 Subject: [PATCH 23/55] Fix up deployment target --- bin/deploy-codedeploy.sh | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/bin/deploy-codedeploy.sh b/bin/deploy-codedeploy.sh index ba77263..03a8f8b 100755 --- a/bin/deploy-codedeploy.sh +++ b/bin/deploy-codedeploy.sh @@ -32,7 +32,7 @@ BUCKET="codedeploy-$AWS_ACCOUNT_ID" case $PARAM in latest) echo "CodeDeploy: finding latest build for $BRANCH_PREFIX" - ARCHIVE="s3://$BUCKET/$(aws s3 ls "$BUCKET/codedeploy-$BRANCH_PREFIX-" | sort | tail -1 | cut -f 6)" + ARCHIVE="s3://$BUCKET/$(aws s3 ls "$BUCKET/codedeploy-$BRANCH_PREFIX-" | sort | tail -1 | cut -d\ -f 6)" S3_URL="s3://$BUCKET/$ARCHIVE" ;; [0-9]*) @@ -60,13 +60,14 @@ echo "S3_URL=$S3_URL" echo "S3_SHORTHAND=$S3_SHORTHAND" -DEPLOYMENT=$(aws deploy create-deployment \ +DEPLOYMENT_ID=$(aws deploy create-deployment \ --region "$AWS_DEFAULT_REGION" \ - --output table \ + --output text \ + --query '[deploymentId]' \ --application-name "$APP_NAME" \ --deployment-group-name "$DEPLOYMENT_GROUP_NAME" \ --description "deployment initiated by deploy-codedeploy.sh" \ --no-ignore-application-stop-failures \ --s3-location "$S3_SHORTHAND") -echo "CodeDeploy: deployment started $DEPLOYMENT" -echo "CodeDeploy: see https://console.aws.amazon.com/codesuite/codedeploy/deployments/$DEPLOYMENT" +echo "CodeDeploy: deployment started $DEPLOYMENT_ID" +echo "CodeDeploy: see https://console.aws.amazon.com/codesuite/codedeploy/deployments/$DEPLOYMENT_ID" From d9bd805d64328ece77d0aa85e67f8d0d9fc359aa Mon Sep 17 00:00:00 2001 From: Richard Bullington-McGuire Date: Sat, 9 Nov 2019 04:50:42 -0500 Subject: [PATCH 24/55] Fix up archive name --- bin/deploy-codedeploy.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/bin/deploy-codedeploy.sh b/bin/deploy-codedeploy.sh index 03a8f8b..8f79eba 100755 --- a/bin/deploy-codedeploy.sh +++ b/bin/deploy-codedeploy.sh @@ -32,7 +32,11 @@ BUCKET="codedeploy-$AWS_ACCOUNT_ID" case $PARAM in latest) echo "CodeDeploy: finding latest build for $BRANCH_PREFIX" - ARCHIVE="s3://$BUCKET/$(aws s3 ls "$BUCKET/codedeploy-$BRANCH_PREFIX-" | sort | tail -1 | cut -d\ -f 6)" + ARCHIVE="s3://$BUCKET/$(aws s3 ls + "$BUCKET/codedeploy-$BRANCH_PREFIX-" | \ + sort | \ + tail -1 | \ + cut -d\ -f6)" S3_URL="s3://$BUCKET/$ARCHIVE" ;; [0-9]*) From 1d3e80f36c124f01806b46013387d3018683452f Mon Sep 17 00:00:00 2001 From: Richard Bullington-McGuire Date: Sat, 9 Nov 2019 04:57:56 -0500 Subject: [PATCH 25/55] Fix up aws s3 ls processing --- bin/deploy-codedeploy.sh | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/bin/deploy-codedeploy.sh b/bin/deploy-codedeploy.sh index 8f79eba..68f279c 100755 --- a/bin/deploy-codedeploy.sh +++ b/bin/deploy-codedeploy.sh @@ -36,11 +36,16 @@ latest) "$BUCKET/codedeploy-$BRANCH_PREFIX-" | \ sort | \ tail -1 | \ - cut -d\ -f6)" + sed 's/ */\t/g' | \ + cut -f 4)" S3_URL="s3://$BUCKET/$ARCHIVE" ;; [0-9]*) - ARCHIVE="$(aws s3 ls "$BUCKET/codedeploy-$BRANCH_PREFIX-" | sort | tail -1)" + ARCHIVE="$(aws s3 ls "$BUCKET/codedeploy-$BRANCH_PREFIX-$PARAM-" | \ + sort | \ + tail -1 | \ + sed 's/ */\t/g' | \ + cut -f 4)" S3_URL="s3://$BUCKET/$ARCHIVE" ;; s3[:]//[a-z0-9]*) From ea848b56447b0d3e53677f4f9ea6fb0bd6c4a61e Mon Sep 17 00:00:00 2001 From: Richard Bullington-McGuire Date: Sat, 9 Nov 2019 05:08:40 -0500 Subject: [PATCH 26/55] Fixed up latest processing --- bin/deploy-codedeploy.sh | 61 +++++++++++++++++++++------------------- 1 file changed, 32 insertions(+), 29 deletions(-) diff --git a/bin/deploy-codedeploy.sh b/bin/deploy-codedeploy.sh index 68f279c..193307b 100755 --- a/bin/deploy-codedeploy.sh +++ b/bin/deploy-codedeploy.sh @@ -28,36 +28,39 @@ DEPLOYMENT_GROUP_NAME=${4:-dev} AWS_ACCOUNT_ID=$(aws sts get-caller-identity --output text --query 'Account') BUCKET="codedeploy-$AWS_ACCOUNT_ID" - -case $PARAM in -latest) +if [[ "$PARAM" -gt "$BUILD_NUMBER" ]]; then echo "CodeDeploy: finding latest build for $BRANCH_PREFIX" - ARCHIVE="s3://$BUCKET/$(aws s3 ls - "$BUCKET/codedeploy-$BRANCH_PREFIX-" | \ - sort | \ - tail -1 | \ - sed 's/ */\t/g' | \ - cut -f 4)" - S3_URL="s3://$BUCKET/$ARCHIVE" - ;; -[0-9]*) - ARCHIVE="$(aws s3 ls "$BUCKET/codedeploy-$BRANCH_PREFIX-$PARAM-" | \ - sort | \ - tail -1 | \ - sed 's/ */\t/g' | \ - cut -f 4)" - S3_URL="s3://$BUCKET/$ARCHIVE" - ;; -s3[:]//[a-z0-9]*) - S3_URL="$PARAM" - ARCHIVE=$(cut -d/ -f 3- <<<"$S3_URL") - BUCKET=$(cut -d/ -f 2- <<<"$S3_URL") - ;; -*) - echo "ERROR: Unknown format for $PARAM, exiting" - exit 1 - ;; -esac + for x in $(seq $PARAM 1); do + ARCHIVE="s3://$BUCKET/$(aws s3 ls + "$BUCKET/codedeploy-$BRANCH_PREFIX-" | \ + sort | \ + tail -1 | \ + sed 's/ */\t/g' | \ + cut -f 4)" + S3_URL="s3://$BUCKET/$ARCHIVE" + PARAM=$(( PARAM - 1 )) + done +else + case $PARAM in + [0-9]*) + ARCHIVE="$(aws s3 ls "$BUCKET/codedeploy-$BRANCH_PREFIX-$PARAM-" | \ + sort | \ + tail -1 | \ + sed 's/ */\t/g' | \ + cut -f 4)" + S3_URL="s3://$BUCKET/$ARCHIVE" + ;; + s3[:]//[a-z0-9]*) + S3_URL="$PARAM" + ARCHIVE=$(cut -d/ -f 3- <<<"$S3_URL") + BUCKET=$(cut -d/ -f 2- <<<"$S3_URL") + ;; + *) + echo "ERROR: Unknown format for $PARAM, exiting" + exit 1 + ;; + esac +fi S3_SHORTHAND="bundleType=zip,bucket=$BUCKET,key=$ARCHIVE" From 0c3c4e0b856bacd342e45ae8849db445ddba1eaf Mon Sep 17 00:00:00 2001 From: Richard Bullington-McGuire Date: Sat, 9 Nov 2019 06:51:48 -0500 Subject: [PATCH 27/55] Attempt to simplify CodeDeploy deployments --- Jenkinsfile | 22 +++++++++------------- bin/deploy-codedeploy.sh | 34 ++++++++++------------------------ 2 files changed, 19 insertions(+), 37 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index a59b911..d5f9f4f 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -70,9 +70,9 @@ properties([ defaultValue: '', description: '''Deploy a CodeDeploy archive. Specify one of the following: - 1. "latest" - deploy the latest build from this branch - 2. a build number - deploy that build number from this branch - 3. a full S3 URL''' + 1. "current" - deploy the CodeDeploy archive from this build + 2. a full S3 URL of a zip file to deploy''' + 3. an empty string (to skip deployment)''' ), booleanParam( name: 'Apply_Terraform', @@ -159,23 +159,19 @@ stage('Preflight') { def build_number = env.BUILD_NUMBER as Long - switch (params.Deploy_CodeDeploy.toLowerCase()) { + switch (params.Deploy_CodeDeploy) { case "": echo "CodeDeploy deployment target is blank, skipping codedeploy step" break - case "latest": - // when codedeploy_target > build number, count backwards - codedeploy_target = build_number + 1 + case "current": echo """CodeDeploy: targeting latest build - CodeDeploy: Will look for build <= ${build_number} CodeDeploy: Will use prefix ${s3_safe_branch_name} """ + codedeploy_target = "current" break - case 1..build_number: - echo """CodeDeploy: targeting build ${build_number} for ${env.BRANCH_NAME} - CodeDeploy: Will use name ${s3_safe_build_number}-${build_number} - """ - codedeploy_target = build_number + case /^s3:.*/: + echo """CodeDeploy: targeting S3 URL build ${params.Deploy_CodeDeploy)""" + codedeploy_target = params.Deploy_CodeDeploy break default: currentBuild.result = 'ABORTED' diff --git a/bin/deploy-codedeploy.sh b/bin/deploy-codedeploy.sh index 193307b..31c7eee 100755 --- a/bin/deploy-codedeploy.sh +++ b/bin/deploy-codedeploy.sh @@ -24,43 +24,29 @@ BRANCH_PREFIX=${2:-master} APP_NAME=${3:-tf-infra-demo-app} DEPLOYMENT_GROUP_NAME=${4:-dev} +GIT_REV="$(git rev-parse --short HEAD)" +ARCHIVE="codedeploy-$BRANCH_PREFIX-$BUILD_NUMBER-$GIT_REV.zip" +# Thanks https://stackoverflow.com/questions/33791069/quick-way-to-get-aws-account-number-from-the-cli-tools +S3_URL="s3://$BUCKET/$ARCHIVE" + # Thanks https://stackoverflow.com/questions/33791069/quick-way-to-get-aws-account-number-from-the-cli-tools AWS_ACCOUNT_ID=$(aws sts get-caller-identity --output text --query 'Account') BUCKET="codedeploy-$AWS_ACCOUNT_ID" -if [[ "$PARAM" -gt "$BUILD_NUMBER" ]]; then - echo "CodeDeploy: finding latest build for $BRANCH_PREFIX" - for x in $(seq $PARAM 1); do - ARCHIVE="s3://$BUCKET/$(aws s3 ls - "$BUCKET/codedeploy-$BRANCH_PREFIX-" | \ - sort | \ - tail -1 | \ - sed 's/ */\t/g' | \ - cut -f 4)" - S3_URL="s3://$BUCKET/$ARCHIVE" - PARAM=$(( PARAM - 1 )) - done -else - case $PARAM in - [0-9]*) - ARCHIVE="$(aws s3 ls "$BUCKET/codedeploy-$BRANCH_PREFIX-$PARAM-" | \ - sort | \ - tail -1 | \ - sed 's/ */\t/g' | \ - cut -f 4)" - S3_URL="s3://$BUCKET/$ARCHIVE" - ;; +case $PARAM in s3[:]//[a-z0-9]*) S3_URL="$PARAM" ARCHIVE=$(cut -d/ -f 3- <<<"$S3_URL") BUCKET=$(cut -d/ -f 2- <<<"$S3_URL") ;; + current) + echo "Using current CodeDeploy build: $S3_URL" + ;; *) echo "ERROR: Unknown format for $PARAM, exiting" exit 1 ;; - esac -fi +esac S3_SHORTHAND="bundleType=zip,bucket=$BUCKET,key=$ARCHIVE" From 8012df6e74d68a1b78e65fc1867f266b2123ddcd Mon Sep 17 00:00:00 2001 From: Richard Bullington-McGuire Date: Sat, 9 Nov 2019 06:54:23 -0500 Subject: [PATCH 28/55] Fix quoting --- Jenkinsfile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index d5f9f4f..260afde 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -13,7 +13,6 @@ import java.util.Random final default_timeout_minutes = 20 final codedeploy_target_skip = -1 // See generally safe key names from https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingMetadata.html -//final s3_safe_branch_name = env.BRANCH_NAME.replaceAll(/[^0-9a-zA-Z\!\-_\.\*\'\(\)], "_") final s3_safe_branch_name = env.BRANCH_NAME.replaceAll(/[^0-9a-zA-Z\!\-_\.\*\'\(\)]/ , "_") def codedeploy_target = codedeploy_target_skip @@ -71,7 +70,7 @@ properties([ description: '''Deploy a CodeDeploy archive. Specify one of the following: 1. "current" - deploy the CodeDeploy archive from this build - 2. a full S3 URL of a zip file to deploy''' + 2. a full S3 URL of a zip file to deploy 3. an empty string (to skip deployment)''' ), booleanParam( From d180732ff5f241a882c866bab0f37eab4e537d9e Mon Sep 17 00:00:00 2001 From: Richard Bullington-McGuire Date: Sat, 9 Nov 2019 06:56:27 -0500 Subject: [PATCH 29/55] Fix syntax --- Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jenkinsfile b/Jenkinsfile index 260afde..f46f779 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -168,7 +168,7 @@ stage('Preflight') { """ codedeploy_target = "current" break - case /^s3:.*/: + case ~/^s3:.*/: echo """CodeDeploy: targeting S3 URL build ${params.Deploy_CodeDeploy)""" codedeploy_target = params.Deploy_CodeDeploy break From e4f6df2940657f99c2ed043af47962ace128f281 Mon Sep 17 00:00:00 2001 From: Richard Bullington-McGuire Date: Sat, 9 Nov 2019 06:58:04 -0500 Subject: [PATCH 30/55] Fix syntax --- Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jenkinsfile b/Jenkinsfile index f46f779..d507907 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -169,7 +169,7 @@ stage('Preflight') { codedeploy_target = "current" break case ~/^s3:.*/: - echo """CodeDeploy: targeting S3 URL build ${params.Deploy_CodeDeploy)""" + echo """CodeDeploy: targeting S3 URL build ${params.Deploy_CodeDeploy}""" codedeploy_target = params.Deploy_CodeDeploy break default: From 555c83b7e1c80cd27cd3f87c9d7262cc1599f507 Mon Sep 17 00:00:00 2001 From: Richard Bullington-McGuire Date: Sat, 9 Nov 2019 07:10:41 -0500 Subject: [PATCH 31/55] Fix up common functions --- bin/build-codedeploy.sh | 12 +++++++++++- bin/deploy-codedeploy.sh | 1 + 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/bin/build-codedeploy.sh b/bin/build-codedeploy.sh index 3612b3e..8988825 100755 --- a/bin/build-codedeploy.sh +++ b/bin/build-codedeploy.sh @@ -17,13 +17,23 @@ ANSIBLE_DIR="$BASE_DIR/ansible" APPLICTION_DIR="$BASE_DIR/application" SRC_DIR="$BASE_DIR/src" +# Credit to http://stackoverflow.com/a/246128/424301 +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +BASE_DIR="$DIR/.." + +# shellcheck disable=SC1090 +. "$DIR/common.sh" +#shellcheck disable=SC1090 +. "$BASE_DIR/env.sh" + + GIT_REV="$(git rev-parse --short HEAD)" BUILD_NUMBER=${BUILD_NUMBER:-0} BRANCH_PREFIX=${1:-master} ARCHIVE="codedeploy-$BRANCH_PREFIX-$BUILD_NUMBER-$GIT_REV.zip" CONTAINERNAME=infra-demo # Thanks https://stackoverflow.com/questions/33791069/quick-way-to-get-aws-account-number-from-the-cli-tools -AWS_ACCOUNT_ID=$(aws sts get-caller-identity --output text --query 'Account') +AWS_ACCOUNT_ID=$(get_aws_account_id) BUCKET="codedeploy-$AWS_ACCOUNT_ID" S3_URL="s3://$BUCKET/$ARCHIVE" diff --git a/bin/deploy-codedeploy.sh b/bin/deploy-codedeploy.sh index 31c7eee..b5dd015 100755 --- a/bin/deploy-codedeploy.sh +++ b/bin/deploy-codedeploy.sh @@ -19,6 +19,7 @@ BASE_DIR="$DIR/.." . "$BASE_DIR/env.sh" BUILD_NUMBER=${BUILD_NUMBER:-0} +BUCKET="codedeploy-$(get_aws_account_id)" PARAM=${1:-} BRANCH_PREFIX=${2:-master} APP_NAME=${3:-tf-infra-demo-app} From ade31a49960e6d12dfcb9937dd6c612867d2b455 Mon Sep 17 00:00:00 2001 From: Richard Bullington-McGuire Date: Sat, 9 Nov 2019 07:20:27 -0500 Subject: [PATCH 32/55] Get HOME defined for CodeDeploy --- bin/activate-rvm.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/bin/activate-rvm.sh b/bin/activate-rvm.sh index dc8a93e..b724db6 100755 --- a/bin/activate-rvm.sh +++ b/bin/activate-rvm.sh @@ -2,6 +2,8 @@ # Activate rvm # Source this to activate RVM +# CodeDeploy has no HOME variable defined! +HOME=${HOME:-/root} RVM_SH=${RVM_SH:-$HOME/.rvm/scripts/rvm} RUBY_VERSION=${RUBY_VERSION:-2.6.3} From a6620e4aceb1ed255d675a42fba7109bca420abc Mon Sep 17 00:00:00 2001 From: Richard Bullington-McGuire Date: Sat, 9 Nov 2019 07:35:45 -0500 Subject: [PATCH 33/55] Add Skip Terraform feature --- Jenkinsfile | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index d507907..b79ed6a 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -73,6 +73,11 @@ properties([ 2. a full S3 URL of a zip file to deploy 3. an empty string (to skip deployment)''' ), + booleanParam( + name: 'Skip_Terraform', + defaultValue: false, + description: 'Skip all Terraform steps, including validation and planning? (shortens cycle times when testing other aspects)' + ), booleanParam( name: 'Apply_Terraform', defaultValue: false, @@ -245,24 +250,26 @@ if (params.Package_CodeDeploy) { def terraform_prompt = 'Should we apply the Terraform plan?' -stage('Plan Terraform') { - node { - wrap.call({ - unstash 'src' - def verb = "plan" - if (params.Destroy_Terraform) { - verb += '-destroy'; - terraform_prompt += ' WARNING: will DESTROY resources'; - } - sh (""" - ./bin/terraform.sh ${verb} - """) - }) - stash includes: "**", excludes: ".git/", name: 'plan' +if (! param.Skip_Terraform) { + stage('Plan Terraform') { + node { + wrap.call({ + unstash 'src' + def verb = "plan" + if (params.Destroy_Terraform) { + verb += '-destroy'; + terraform_prompt += ' WARNING: will DESTROY resources'; + } + sh (""" + ./bin/terraform.sh ${verb} + """) + }) + stash includes: "**", excludes: ".git/", name: 'plan' + } } } -if (params.Apply_Terraform || params.Destroy_Terraform) { +if (! params.Skip_Terraform && params.Apply_Terraform || params.Destroy_Terraform) { // See https://support.cloudbees.com/hc/en-us/articles/226554067-Pipeline-How-to-add-an-input-step-with-timeout-that-continues-if-timeout-is-reached-using-a-default-value def userInput = false try { From 13f2e7edd7d151717821ba3715f936ef16a2f202 Mon Sep 17 00:00:00 2001 From: Richard Bullington-McGuire Date: Sat, 9 Nov 2019 07:37:53 -0500 Subject: [PATCH 34/55] params not param for Jenkins parameters --- Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jenkinsfile b/Jenkinsfile index b79ed6a..2581d3c 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -250,7 +250,7 @@ if (params.Package_CodeDeploy) { def terraform_prompt = 'Should we apply the Terraform plan?' -if (! param.Skip_Terraform) { +if (! params.Skip_Terraform) { stage('Plan Terraform') { node { wrap.call({ From 3382409711e87c3f01f6d6e4fd1371c7d907dc12 Mon Sep 17 00:00:00 2001 From: Richard Bullington-McGuire Date: Sat, 9 Nov 2019 07:45:37 -0500 Subject: [PATCH 35/55] Use new wait syntax to wait until deploy is complete --- bin/deploy-codedeploy.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/bin/deploy-codedeploy.sh b/bin/deploy-codedeploy.sh index b5dd015..fa2c17d 100755 --- a/bin/deploy-codedeploy.sh +++ b/bin/deploy-codedeploy.sh @@ -70,3 +70,5 @@ DEPLOYMENT_ID=$(aws deploy create-deployment \ --s3-location "$S3_SHORTHAND") echo "CodeDeploy: deployment started $DEPLOYMENT_ID" echo "CodeDeploy: see https://console.aws.amazon.com/codesuite/codedeploy/deployments/$DEPLOYMENT_ID" +echo "CodeDeploy: waiting for deployment $DEPLOYMENT_ID to complete..." +aws deploy wait deployment-successful --deployment-id "$DEPLOYMENT_ID" From 817b93434967f84f0bf6d40c1c39c718fddea592 Mon Sep 17 00:00:00 2001 From: Richard Bullington-McGuire Date: Sat, 9 Nov 2019 08:14:01 -0500 Subject: [PATCH 36/55] Try harder --- bin/activate-rvm.sh | 5 ++++- bin/codedeploy/ValidateService.sh | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/bin/activate-rvm.sh b/bin/activate-rvm.sh index b724db6..467ae11 100755 --- a/bin/activate-rvm.sh +++ b/bin/activate-rvm.sh @@ -3,12 +3,15 @@ # Source this to activate RVM # CodeDeploy has no HOME variable defined! -HOME=${HOME:-/root} +HOME=${HOME:-/centos} RVM_SH=${RVM_SH:-$HOME/.rvm/scripts/rvm} RUBY_VERSION=${RUBY_VERSION:-2.6.3} # rvm hates the bash options -eu +echo -n "Activating RVM. HOME=$HOME id:" +id -a + if [[ ! -f "$RVM_SH" ]]; then echo "Error: $0: RVM_SH $RVM_SH not found" exit 1 diff --git a/bin/codedeploy/ValidateService.sh b/bin/codedeploy/ValidateService.sh index 1da7788..fa9b410 100755 --- a/bin/codedeploy/ValidateService.sh +++ b/bin/codedeploy/ValidateService.sh @@ -29,4 +29,4 @@ echo "Checking web server availability" check_every 2 echo "Scanning with openscap and gauntlt" -bash /app/bin/ansible.sh scan-openscap.yml scan-gauntlt.yml +sudo -u centos HOME=/home/centos /app/bin/ansible.sh scan-openscap.yml scan-gauntlt.yml From 848a6f6f69efe1838383faee878aed8864a5b31a Mon Sep 17 00:00:00 2001 From: Richard Bullington-McGuire Date: Sat, 9 Nov 2019 08:23:40 -0500 Subject: [PATCH 37/55] Skip Terraform validation too --- Jenkinsfile | 4 ++-- bin/validate.sh | 30 ++++++++++++++++-------------- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 2581d3c..76a4413 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -198,8 +198,8 @@ stage('Validate') { node { wrap.call({ unstash 'src' - // Validate packer templates, check branch - sh ("./bin/validate.sh") + // Validate packer templates, check branch, lint shell scripts, lint terraform + sh ("SKIP_TERRAFORM=${params.Skip_Terraform} ./bin/validate.sh") }) } } diff --git a/bin/validate.sh b/bin/validate.sh index 3ce3976..b6c830d 100755 --- a/bin/validate.sh +++ b/bin/validate.sh @@ -27,20 +27,22 @@ echo "Linting packer files" $DOCKER_PACKER validate app/packer/machines/web-server.json # Ensure that `terraform fmt` comes up clean -echo "Linting terraform files for correctness" -DOCKER_TERRAFORM=$(get_docker_terraform) -init_terraform -$DOCKER_TERRAFORM validate \ - -var 'newrelic_license_key=ZZZZ' \ - -var 'newrelic_api_key=ZZZZ' \ - -var 'newrelic_alert_email=ferd.berferd@example.com' \ -echo "Linting terraform files for formatting" -fmt=$($DOCKER_TERRAFORM fmt) -if [[ -n "$fmt" ]]; then - echo 'ERROR: these files are not formatted correctly. Run "terraform fmt"' - echo "$fmt" - git diff - exit 1 +if [[ "$SKIP_TERRAFORM" == "false" ]]; then + echo "Linting terraform files for correctness" + DOCKER_TERRAFORM=$(get_docker_terraform) + init_terraform + $DOCKER_TERRAFORM validate \ + -var 'newrelic_license_key=ZZZZ' \ + -var 'newrelic_api_key=ZZZZ' \ + -var 'newrelic_alert_email=ferd.berferd@example.com' \ + echo "Linting terraform files for formatting" + fmt=$($DOCKER_TERRAFORM fmt) + if [[ -n "$fmt" ]]; then + echo 'ERROR: these files are not formatted correctly. Run "terraform fmt"' + echo "$fmt" + git diff + exit 1 + fi fi echo "Linting shell scripts" From 2e64aa30c84b4ae52451c1636f81bf56cc450eed Mon Sep 17 00:00:00 2001 From: Richard Bullington-McGuire Date: Sat, 9 Nov 2019 08:25:36 -0500 Subject: [PATCH 38/55] Increase CodeDeploy timeout for validate --- codedeploy/appspec.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/codedeploy/appspec.yml b/codedeploy/appspec.yml index 6c7275f..880803a 100644 --- a/codedeploy/appspec.yml +++ b/codedeploy/appspec.yml @@ -25,4 +25,4 @@ hooks: timeout: 120 ValidateService: - location: bin/codedeploy/ValidateService.sh - timeout: 60 + timeout: 300 From 48620ecd4530b6337f1bd49b75c71382c5b5d140 Mon Sep 17 00:00:00 2001 From: Richard Bullington-McGuire Date: Sat, 9 Nov 2019 09:08:18 -0500 Subject: [PATCH 39/55] Add CodeDeploy log to CloudWatch --- ansible/roles/cloudwatch-agent/files/config.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ansible/roles/cloudwatch-agent/files/config.json b/ansible/roles/cloudwatch-agent/files/config.json index 219e151..38e2d6f 100755 --- a/ansible/roles/cloudwatch-agent/files/config.json +++ b/ansible/roles/cloudwatch-agent/files/config.json @@ -61,6 +61,11 @@ "file_path": "/var/log/nginx/error.log", "log_group_name": "nginx-error", "log_stream_name": "{instance_id}" + }, + { + "file_path": "/opt/codedeploy-agent/deployment-root/deployment-logs/codedeploy-agent-deployments.log", + "log_group_name": "codedeploy", + "log_stream_name": "{instance_id}" } ] } From 94b5be0a2cffca69796146d341e948524b58b1ac Mon Sep 17 00:00:00 2001 From: Richard Bullington-McGuire Date: Sat, 9 Nov 2019 09:12:45 -0500 Subject: [PATCH 40/55] Be concise --- Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jenkinsfile b/Jenkinsfile index 76a4413..ce89585 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -302,7 +302,7 @@ if (params.Rotate_Servers) { } if (params.Deploy_CodeDeploy) { - stage('DeployCodeDeploy Archive') { + stage('Deploy') { node { wrap.call({ unstash 'src' From 3e9037e4684d7bd1bacea69df237bf3161602955 Mon Sep 17 00:00:00 2001 From: Richard Bullington-McGuire Date: Sat, 9 Nov 2019 09:19:03 -0500 Subject: [PATCH 41/55] Ensure that gauntlt attack files are in CodeDeploy archive --- codedeploy/appspec.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/codedeploy/appspec.yml b/codedeploy/appspec.yml index 880803a..21be634 100644 --- a/codedeploy/appspec.yml +++ b/codedeploy/appspec.yml @@ -6,6 +6,8 @@ files: destination: /app/application - source: src destination: /app/src + - source: gauntlt + destination: /app/gauntlt - source: bin destination: /app/bin - source: ansible From be5d1a6d0cab748e0a754747048fdbcaf38768f2 Mon Sep 17 00:00:00 2001 From: Richard Bullington-McGuire Date: Sat, 9 Nov 2019 09:24:48 -0500 Subject: [PATCH 42/55] Avoid downloading resources - pack is failing --- ansible/roles/scan-openscap/tasks/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ansible/roles/scan-openscap/tasks/main.yml b/ansible/roles/scan-openscap/tasks/main.yml index f8bf305..a7778fb 100644 --- a/ansible/roles/scan-openscap/tasks/main.yml +++ b/ansible/roles/scan-openscap/tasks/main.yml @@ -18,7 +18,7 @@ cd {{ build_dir }} # This will have a non-zero exit if any of the scans fail, so do not fail immediately on that set +e - oscap xccdf eval --fetch-remote-resources --profile {{ profile }} --results {{ output_file_xml }} {{ xccdf_file }} + oscap xccdf eval --profile {{ profile }} --results {{ output_file_xml }} {{ xccdf_file }} set -e oscap xccdf generate report {{ output_file_xml }} > {{ output_file_html }} args: From a99a4459be993ae85070ad3eb28d8185fd9c7a9a Mon Sep 17 00:00:00 2001 From: Richard Bullington-McGuire Date: Sat, 9 Nov 2019 10:16:55 -0500 Subject: [PATCH 43/55] Add Gauntlt files to CodeDeploy package --- bin/build-codedeploy.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/bin/build-codedeploy.sh b/bin/build-codedeploy.sh index 8988825..efb8136 100755 --- a/bin/build-codedeploy.sh +++ b/bin/build-codedeploy.sh @@ -16,6 +16,7 @@ BUILD_DIR="$BASE_DIR/build" ANSIBLE_DIR="$BASE_DIR/ansible" APPLICTION_DIR="$BASE_DIR/application" SRC_DIR="$BASE_DIR/src" +GAUNTLT_DIR="$BASE_DIR/gauntlt" # Credit to http://stackoverflow.com/a/246128/424301 DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" @@ -65,6 +66,7 @@ SOURCES="$BASE_DIR/bin $ANSIBLE_DIR $APPLICTION_DIR $SRC_DIR +$GAUNTLT_DIR $BASE_DIR/codedeploy/appspec.yml" for src in $SOURCES; do cp -a "$src" "$BUILD_DIR" From 3f749a055ab7c6604fcc2d534506e1b4090d97b9 Mon Sep 17 00:00:00 2001 From: Richard Bullington-McGuire Date: Sat, 9 Nov 2019 10:21:57 -0500 Subject: [PATCH 44/55] Add gauntlt files properly to archive --- bin/build-codedeploy.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/bin/build-codedeploy.sh b/bin/build-codedeploy.sh index efb8136..b4b8b82 100755 --- a/bin/build-codedeploy.sh +++ b/bin/build-codedeploy.sh @@ -79,6 +79,7 @@ done bin \ ansible \ application \ + gauntlt \ src \ venv \ socket From 6bed5ecac525341311ea3847a1ab9bb391639cc0 Mon Sep 17 00:00:00 2001 From: Richard Bullington-McGuire Date: Sat, 9 Nov 2019 10:40:29 -0500 Subject: [PATCH 45/55] Remove C2S profile. Not happy! --- ansible/roles/scan-openscap/defaults/main.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ansible/roles/scan-openscap/defaults/main.yml b/ansible/roles/scan-openscap/defaults/main.yml index ed0b37a..ac588b1 100644 --- a/ansible/roles/scan-openscap/defaults/main.yml +++ b/ansible/roles/scan-openscap/defaults/main.yml @@ -3,5 +3,6 @@ build_dir: /app/build output_file_html: /app/build/scan-xccdf-results.html output_file_xml: /app/build/scan-xccdf-results.xml -profile: C2S +# Oh no! The old C2S profile is no longer available! +profile: standard xccdf_file: /usr/share/xml/scap/ssg/content/ssg-centos7-xccdf.xml From 95ebfaac84df2f69a5559b6c28053d55191b0232 Mon Sep 17 00:00:00 2001 From: Richard Bullington-McGuire Date: Sat, 9 Nov 2019 10:57:32 -0500 Subject: [PATCH 46/55] Work around permissions issues --- bin/codedeploy/ValidateService.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/bin/codedeploy/ValidateService.sh b/bin/codedeploy/ValidateService.sh index fa9b410..994dc54 100755 --- a/bin/codedeploy/ValidateService.sh +++ b/bin/codedeploy/ValidateService.sh @@ -14,6 +14,8 @@ ${DEBUG:-false} && set -vx # and http://wiki.bash-hackers.org/scripting/debuggingtips export PS4='+(${BASH_SOURCE}:${LINENO}): ${FUNCNAME[0]:+${FUNCNAME[0]}(): }' +GAUNTLT_RESULTS=/app/build/gauntlt-results.html + check_every() { local delay=${1:-} local host="http://localhost/" @@ -29,4 +31,7 @@ echo "Checking web server availability" check_every 2 echo "Scanning with openscap and gauntlt" +mkdir -p /app/build +cat < /dev/null > "$GAUNTLT_RESULTS" +chown centos:centos "$GAUNTLT_RESULTS" sudo -u centos HOME=/home/centos /app/bin/ansible.sh scan-openscap.yml scan-gauntlt.yml From 7c71fc30ecdd430d56a0d81022ee327905ca33a9 Mon Sep 17 00:00:00 2001 From: Richard Bullington-McGuire Date: Sat, 9 Nov 2019 11:07:06 -0500 Subject: [PATCH 47/55] Fix copy and add debug --- bin/build-codedeploy.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/bin/build-codedeploy.sh b/bin/build-codedeploy.sh index b4b8b82..a528e72 100755 --- a/bin/build-codedeploy.sh +++ b/bin/build-codedeploy.sh @@ -68,7 +68,9 @@ $APPLICTION_DIR $SRC_DIR $GAUNTLT_DIR $BASE_DIR/codedeploy/appspec.yml" +echo "Copying sources into place for src in $SOURCES; do + echo cp -a "$src" "$BUILD_DIR" cp -a "$src" "$BUILD_DIR" done From 93e3985efa69f942778f4062a32ff1e6b2853324 Mon Sep 17 00:00:00 2001 From: Richard Bullington-McGuire Date: Sat, 9 Nov 2019 11:08:22 -0500 Subject: [PATCH 48/55] Fix quoting --- bin/build-codedeploy.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/build-codedeploy.sh b/bin/build-codedeploy.sh index a528e72..8bcbfca 100755 --- a/bin/build-codedeploy.sh +++ b/bin/build-codedeploy.sh @@ -68,7 +68,7 @@ $APPLICTION_DIR $SRC_DIR $GAUNTLT_DIR $BASE_DIR/codedeploy/appspec.yml" -echo "Copying sources into place +echo "Copying sources into place" for src in $SOURCES; do echo cp -a "$src" "$BUILD_DIR" cp -a "$src" "$BUILD_DIR" From e182069690ddd51d5b6ff99f58176f9628bde5b3 Mon Sep 17 00:00:00 2001 From: Richard Bullington-McGuire Date: Sat, 9 Nov 2019 11:23:15 -0500 Subject: [PATCH 49/55] Add debug of install --- bin/codedeploy/AfterInstall.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/bin/codedeploy/AfterInstall.sh b/bin/codedeploy/AfterInstall.sh index 2fcbca4..3b5c57e 100755 --- a/bin/codedeploy/AfterInstall.sh +++ b/bin/codedeploy/AfterInstall.sh @@ -41,3 +41,6 @@ source ${VENV_DIR}/bin/activate set -u newrelic-admin generate-config "${NEWRELIC_LICENSE_KEY}" "${NEWRELIC_CONFIG_DIR}/newrelic.ini.orig" sed 's/^app_name =.*$/app_name = Spin/' "${NEWRELIC_CONFIG_DIR}/newrelic.ini.orig" > "${NEWRELIC_CONFIG_DIR}/newrelic.ini" + +echo /app directory: +ls -laZ /app From cc83d7f04717da35ecc79b7436252a4da3ca43a5 Mon Sep 17 00:00:00 2001 From: Richard Bullington-McGuire Date: Sat, 9 Nov 2019 11:48:08 -0500 Subject: [PATCH 50/55] Hackity hack --- bin/codedeploy/ValidateService.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/bin/codedeploy/ValidateService.sh b/bin/codedeploy/ValidateService.sh index 994dc54..6891c91 100755 --- a/bin/codedeploy/ValidateService.sh +++ b/bin/codedeploy/ValidateService.sh @@ -15,6 +15,8 @@ ${DEBUG:-false} && set -vx export PS4='+(${BASH_SOURCE}:${LINENO}): ${FUNCNAME[0]:+${FUNCNAME[0]}(): }' GAUNTLT_RESULTS=/app/build/gauntlt-results.html +# TODO: save this to S3 instead +GAUNTLT_RESULTS_SAVE="/home/centos/$DEPLOYMENT_ID-gauntlt-results.html" check_every() { local delay=${1:-} @@ -34,4 +36,9 @@ echo "Scanning with openscap and gauntlt" mkdir -p /app/build cat < /dev/null > "$GAUNTLT_RESULTS" chown centos:centos "$GAUNTLT_RESULTS" +set +e sudo -u centos HOME=/home/centos /app/bin/ansible.sh scan-openscap.yml scan-gauntlt.yml +RETCODE=$? +cp "$GAUNTLT_RESULTS" "$GAUNTLT_RESULTS_SAVE" +set -e +exit "$RETCODE" From 81399efc491e25ebded0aa7928f30c3f4e579120 Mon Sep 17 00:00:00 2001 From: Richard Bullington-McGuire Date: Sat, 9 Nov 2019 12:28:28 -0500 Subject: [PATCH 51/55] Fix permissions --- bin/codedeploy/ValidateService.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/bin/codedeploy/ValidateService.sh b/bin/codedeploy/ValidateService.sh index 6891c91..43fc282 100755 --- a/bin/codedeploy/ValidateService.sh +++ b/bin/codedeploy/ValidateService.sh @@ -35,10 +35,12 @@ check_every 2 echo "Scanning with openscap and gauntlt" mkdir -p /app/build cat < /dev/null > "$GAUNTLT_RESULTS" -chown centos:centos "$GAUNTLT_RESULTS" +chown -R centos:centos "$GAUNTLT_RESULTS" /app/build /app/ansible/tmp + set +e sudo -u centos HOME=/home/centos /app/bin/ansible.sh scan-openscap.yml scan-gauntlt.yml RETCODE=$? cp "$GAUNTLT_RESULTS" "$GAUNTLT_RESULTS_SAVE" set -e exit "$RETCODE" +rm -rf /app/ansible/tmp From ced916b66a558b8552ccfb1a3dd14a3eaf6c95db Mon Sep 17 00:00:00 2001 From: Richard Bullington-McGuire Date: Sat, 9 Nov 2019 12:41:58 -0500 Subject: [PATCH 52/55] Hail mary commit --- bin/codedeploy/ValidateService.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/bin/codedeploy/ValidateService.sh b/bin/codedeploy/ValidateService.sh index 43fc282..6e69712 100755 --- a/bin/codedeploy/ValidateService.sh +++ b/bin/codedeploy/ValidateService.sh @@ -33,14 +33,15 @@ echo "Checking web server availability" check_every 2 echo "Scanning with openscap and gauntlt" -mkdir -p /app/build +mkdir -p /app/build /app/ansible/tmp cat < /dev/null > "$GAUNTLT_RESULTS" chown -R centos:centos "$GAUNTLT_RESULTS" /app/build /app/ansible/tmp +chmod 755 "$GAUNTLT_RESULTS" /app/build /app/ansible/tmp set +e sudo -u centos HOME=/home/centos /app/bin/ansible.sh scan-openscap.yml scan-gauntlt.yml RETCODE=$? -cp "$GAUNTLT_RESULTS" "$GAUNTLT_RESULTS_SAVE" set -e +cp "$GAUNTLT_RESULTS" "$GAUNTLT_RESULTS_SAVE" +rm -rf /app/ansible/tmp /app/build exit "$RETCODE" -rm -rf /app/ansible/tmp From 8dced1f6a92f942ba5ec11cff6ab1aade7001fec Mon Sep 17 00:00:00 2001 From: Richard Bullington-McGuire Date: Sat, 9 Nov 2019 12:55:58 -0500 Subject: [PATCH 53/55] Hard code path for demo --- gauntlt/nmap.attack | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gauntlt/nmap.attack b/gauntlt/nmap.attack index 6467c14..35b9827 100644 --- a/gauntlt/nmap.attack +++ b/gauntlt/nmap.attack @@ -36,12 +36,12 @@ Feature: nmap attacks for localhost and to use this for your tests, change the v Scenario: Output to XML When I launch an "nmap" attack with: """ - nmap -p 22,80,443 -oX foo.xml + nmap -p 22,80,443 -oX /app/build/nmap-results.xml """ - And the file "foo.xml" should contain XML: + And the file "/app/build/nmap-results.xml" should contain XML: | css | | ports port[protocol="tcp"][portid="22"] state[state="open"] | - And the file "foo.xml" should not contain XML: + And the file "/app/build/nmap-results.xml" should not contain XML: | css | | ports port[protocol="tcp"][portid="80"] state[state="open"] | | ports port[protocol="tcp"][portid="443"] state[state="open"] | From ccee2b3d8562180b2d9dd33a2addbaed8e527c44 Mon Sep 17 00:00:00 2001 From: Richard Bullington-McGuire Date: Sat, 9 Nov 2019 13:42:12 -0500 Subject: [PATCH 54/55] get it done --- gauntlt/nmap.attack | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/gauntlt/nmap.attack b/gauntlt/nmap.attack index 35b9827..3d3f200 100644 --- a/gauntlt/nmap.attack +++ b/gauntlt/nmap.attack @@ -32,17 +32,3 @@ Feature: nmap attacks for localhost and to use this for your tests, change the v """ 443/tcp """ - - Scenario: Output to XML - When I launch an "nmap" attack with: - """ - nmap -p 22,80,443 -oX /app/build/nmap-results.xml - """ - And the file "/app/build/nmap-results.xml" should contain XML: - | css | - | ports port[protocol="tcp"][portid="22"] state[state="open"] | - And the file "/app/build/nmap-results.xml" should not contain XML: - | css | - | ports port[protocol="tcp"][portid="80"] state[state="open"] | - | ports port[protocol="tcp"][portid="443"] state[state="open"] | - From 85d1b56ad68052aa7b4fbb8109dce126436e3096 Mon Sep 17 00:00:00 2001 From: Richard Bullington-McGuire Date: Sun, 10 Nov 2019 15:24:39 -0500 Subject: [PATCH 55/55] Revert "get it done" This reverts commit ccee2b3d8562180b2d9dd33a2addbaed8e527c44. --- gauntlt/nmap.attack | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/gauntlt/nmap.attack b/gauntlt/nmap.attack index 3d3f200..35b9827 100644 --- a/gauntlt/nmap.attack +++ b/gauntlt/nmap.attack @@ -32,3 +32,17 @@ Feature: nmap attacks for localhost and to use this for your tests, change the v """ 443/tcp """ + + Scenario: Output to XML + When I launch an "nmap" attack with: + """ + nmap -p 22,80,443 -oX /app/build/nmap-results.xml + """ + And the file "/app/build/nmap-results.xml" should contain XML: + | css | + | ports port[protocol="tcp"][portid="22"] state[state="open"] | + And the file "/app/build/nmap-results.xml" should not contain XML: + | css | + | ports port[protocol="tcp"][portid="80"] state[state="open"] | + | ports port[protocol="tcp"][portid="443"] state[state="open"] | +