Skip to content

Commit 7003880

Browse files
Merge pull request #27 from ModusCreateOrg/demo-20190130
Demo 20190130
2 parents 5af043b + 1bec304 commit 7003880

29 files changed

+426
-64
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,6 @@
1212
__pycache__
1313
build/
1414
jmeter.log
15+
scan-xccdf-results.html
16+
scan-xccdf-results.xml
1517
venv/

Jenkinsfile

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -26,17 +26,22 @@ def get_captcha(Long hash_const) {
2626
}
2727

2828
def wrap = { fn->
29-
ansiColor('xterm') {
30-
withCredentials([file(credentialsId: 'terraform-demo.json',
31-
variable: 'GOOGLE_APPLICATION_CREDENTIALS_OVERRIDE')]) {
32-
sh ("""
33-
cp env.sh.sample env.sh
34-
rm -rf build
35-
mkdir build
36-
""")
29+
ansiColor('xterm') {
30+
withCredentials(
31+
[
32+
file(credentialsId: 'terraform-demo.json',
33+
variable: 'GOOGLE_APPLICATION_CREDENTIALS_OVERRIDE'),
34+
string(credentialsId: 'newrelic.license.key',
35+
variable: 'NEWRELIC_LICENSE_KEY_OVERRIDE'),
36+
string(credentialsId: 'newrelic.api.key',
37+
variable: 'NEWRELIC_API_KEY_OVERRIDE'),
38+
string(credentialsId: 'newrelic.alert.email',
39+
variable: 'NEWRELIC_ALERT_EMAIL_OVERRIDE'),
40+
]) {
41+
sh ("bin/clean-workspace.sh")
3742
fn()
3843
}
39-
}
44+
}
4045
}
4146

4247
final Long XOR_CONST = 3735928559 // 0xdeadbeef
@@ -87,15 +92,12 @@ properties([
8792
description: "Execute a JMeter load test against the stack"
8893
),
8994
string(
90-
name: 'JMETER_threads',
95+
name: 'JMETER_num_threads',
9196
defaultValue: '2',
92-
description: """number of jmeter threads. Resulting ASG stable sizes for t2.large instances are:
93-
- 2 threads, 3 instances;
94-
- 4 threads, 7 instances;
95-
"""
97+
description: "number of jmeter threads."
9698
),
9799
string(
98-
name: 'JMETER_ramp_duration',
100+
name: 'JMETER_ramp_time',
99101
defaultValue: '900',
100102
description: 'period in seconds of ramp-up time.'
101103
),
@@ -182,7 +184,7 @@ stage('Build CodeDeploy Archive') {
182184
node {
183185
unstash 'src'
184186
wrap.call({
185-
sh ("./codedeploy/bin/build.sh")
187+
sh ("./bin/build-codedeploy.sh")
186188
})
187189
}
188190
}
@@ -246,7 +248,7 @@ if (params.Run_JMeter) {
246248
wrap.call({
247249
sh ("""
248250
HOST=\$(./bin/terraform.sh output route53-dns)
249-
./bin/jmeter.sh -Jthreads=${params.JMETER_threads} -Jramp_duration=${params.JMETER_ramp_duration} -Jduration=${params.JMETER_duration} -Jhost=\$HOST
251+
./bin/jmeter.sh -Jnum_threads=${params.JMETER_num_threads} -Jramp_time=${params.JMETER_ramp_time} -Jduration=${params.JMETER_duration} -Jhost=\$HOST
250252
ls -l build
251253
""")
252254
archiveArtifacts artifacts: 'build/*.jtl, build/*.xml, build/*.csv, build/*.html', fingerprint: true

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ Instructions
2323
* [Docker](https://docker.com/) (tested with 18.05.0-ce)
2424
* [Packer](https://www.packer.io/) (tested with 1.0.3)
2525
* [Terraform](https://www.terraform.io/) (tested with v0.11.7)
26+
* [JQ](https://stedolan.github.io/jq/) (tested with 1.3 and 1.5)
2627

2728
Optionally, you can use Vagrant to test ansible playbooks locally and Jenkins to orchestrate creation of AMIs in conjunction with GitHub branches and pull requests.
2829

@@ -116,6 +117,8 @@ A JMeter test harness that will allow testing of a the application
116117

117118
A `Jenkinsfile` is provided that will allow Jenkins to execute Packer and Terraform, package a CodeDeploy application, and even run JMeter performance tests. In order for Jenkins to do this, it needs to have AWS credentials set up, preferably through an IAM role, granting full control of EC2 and VPC resources in that account, and write access to the S3 bucket used for storing CodeDeploy applications. Packer needs this in order to create AMIs, key pairs, etc, Terraform needs this to create a VPC and EC2 resources, and CodeDeploy needs this to store the artifact it creates. This could be pared down further through some careful logging and role work.
118119

120+
The Jenkins executor running this job needs to have both a recent Docker and the jq utility (version 1.3 or higher) installed.
121+
119122
The scripts here assume that Jenkins is running on EC2 and uses instance data from the Jenkins executor to infer what VPC and subnet to launch the new EC2 instance into. The AWS profile IAM user associated with your Jenkins instance or the Jenkins user's AWS credentials should have full control of EC2 in the account you are using.
120123

121124
This script relies on Jenkins having a secret file containing the Google application credentials in JSON with the id "terraform-demo.json". You will need to add that to your Jenkins server's credentials.

ansible/bakery.yml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,20 @@
33

44
# Thanks https://www.tricksofthetrades.net/2017/10/02/ansible-local-playbooks/ for
55
# the trick on installing locally using "hosts: 127.0.0.1" and "connection:local"
6+
- name: Install New Relic Infrastructure
7+
hosts: 127.0.0.1
8+
connection: local
9+
become: yes
10+
roles:
11+
- newrelic.newrelic-infra
12+
vars:
13+
nrinfragent_os_name: CentOS
14+
nrinfragent_os_version: 7
15+
nrinfragent_config:
16+
license_key: ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ
17+
log_file: /var/log/newrelic-infra/nr-infra.log
18+
log_to_stdout: false
19+
620
- name: Install Web Application
721
hosts: 127.0.0.1
822
connection: local
@@ -12,6 +26,7 @@
1226
- prepare-web-content
1327
- prepare-codedeploy
1428

29+
1530
- name: Harden Server
1631
hosts: 127.0.0.1
1732
connection: local
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
---
2+
# Use ansible to install the newrelic infra agent.
3+
4+
# Thanks https://www.tricksofthetrades.net/2017/10/02/ansible-local-playbooks/ for
5+
# the trick on installing locally using "hosts: 127.0.0.1" and "connection:local"
6+
7+
- name: Set the newrelic license key
8+
hosts: 127.0.0.1
9+
connection: local
10+
become: yes
11+
tasks:
12+
- command: bash /app/bin/set-newrelic-license-key.sh
13+
14+
- name: Restart newrelic-infra
15+
hosts: 127.0.0.1
16+
connection: local
17+
become: yes
18+
service:
19+
name: newerelic-infra
20+
state: restarted
21+

ansible/requirements.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,6 @@
1515
# And the ModusCreateOrg fork has been fixed to avoid running stuff from /tmp
1616
- src: https://github.com/ModusCreateOrg/ansible-aws-codedeploy-agent
1717

18+
# New Relic Infrastructure
19+
- src: newrelic.newrelic-infra
20+

ansible/roles/app-AfterInstall/templates/infra-demo.ini.j2

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,14 @@ venv = /app/venv
33
wsgi-file = /app/src/wsgi.py
44
chdir = /app/src
55
master = 1
6-
workers = 2
7-
threads = 8
6+
workers = 64
7+
threads = 1
88
lazy-apps = 1
99
wsgi-env-behaviour = holy
10-
enable-threads = 1
10+
enable-threads = 0
1111
http-auto-chunked = 1
1212
http-keepalive = 1
1313
uwsgi-socket = 127.0.0.1:8008
14-
14+
harakiri = 120
15+
harakiri-verbose
16+
max-requests = 2048

codedeploy/bin/build.sh renamed to bin/build-codedeploy.sh

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,9 @@ export PS4='+(${BASH_SOURCE}:${LINENO}): ${FUNCNAME[0]:+${FUNCNAME[0]}(): }'
1313
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
1414
BASE_DIR="$DIR/.."
1515
BUILD_DIR="$BASE_DIR/build"
16-
ANSIBLE_DIR="$BASE_DIR/../ansible"
17-
APPLICTION_DIR="$BASE_DIR/../application"
18-
SRC_DIR="$BASE_DIR/../src"
19-
VENV_DIR="$BASE_DIR/../venv"
20-
DOCKER_DIR="$BASE_DIR/.."
16+
ANSIBLE_DIR="$BASE_DIR/ansible"
17+
APPLICTION_DIR="$BASE_DIR/application"
18+
SRC_DIR="$BASE_DIR/src"
2119

2220
GIT_REV="$(git rev-parse --short HEAD)"
2321
BUILD_NUMBER=${BUILD_NUMBER:-0}
@@ -39,20 +37,22 @@ fi
3937
mkdir -p "$BUILD_DIR/socket"
4038

4139
echo Build docker container $CONTAINERNAME
42-
docker build -f=Dockerfile -t "$CONTAINERNAME" "$DOCKER_DIR"
40+
docker build -f=Dockerfile -t "$CONTAINERNAME" "$BASE_DIR"
4341

4442
echo Create python virtual environment
45-
docker run --rm -v "$DOCKER_DIR:/src" "$CONTAINERNAME" /bin/bash -c \
46-
"mkdir -p /src/venv ; \
47-
cp -fa /app/venv/* /src/venv"
43+
docker run \
44+
--rm \
45+
-v "$BASE_DIR:/src" \
46+
"$CONTAINERNAME" \
47+
/bin/bash -c \
48+
"mkdir -p /src/build/venv ; \
49+
cp -fa /app/venv/* /src/build/venv"
4850

4951
SOURCES="$BASE_DIR/bin
5052
$ANSIBLE_DIR
5153
$APPLICTION_DIR
5254
$SRC_DIR
53-
$BASE_DIR/appspec.yml
54-
$BASE_DIR/bin
55-
$VENV_DIR"
55+
$BASE_DIR/codedeploy/appspec.yml"
5656
for src in $SOURCES; do
5757
cp -a "$src" "$BUILD_DIR"
5858
done
@@ -70,7 +70,7 @@ done
7070
)
7171

7272
echo Remove docker generated files
73-
docker run --rm -v "$DOCKER_DIR:/src" "$CONTAINERNAME" /bin/bash -c \
73+
docker run --rm -v "$BASE_DIR:/src" "$CONTAINERNAME" /bin/bash -c \
7474
"rm -rf /src/venv"
7575

7676
cd "$BUILD_DIR"
Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,8 @@
11
#!/usr/bin/env bash
2+
# clean workspace
23
#
3-
# AfterInstall.sh
4-
#
5-
# AWS CodeDeploy After Install hook script
6-
74
# Set bash unofficial strict mode http://redsymbol.net/articles/unofficial-bash-strict-mode/
85
set -euo pipefail
9-
IFS=$'\n\t'
106

117
# Set DEBUG to true for enhanced debugging: run prefixed with "DEBUG=true"
128
${DEBUG:-false} && set -vx
@@ -17,7 +13,13 @@ export PS4='+(${BASH_SOURCE}:${LINENO}): ${FUNCNAME[0]:+${FUNCNAME[0]}(): }'
1713
# Credit to http://stackoverflow.com/a/246128/424301
1814
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
1915
BASE_DIR="$DIR/.."
20-
ANSIBLE_DIR="$BASE_DIR/ansible"
16+
BUILD_DIR="$BASE_DIR/build"
17+
export BASE_DIR
18+
19+
# shellcheck disable=SC1090
20+
. "$DIR/common.sh"
2121

22-
# Invoke Ansible for final set up
23-
ansible-playbook -l localhost "$ANSIBLE_DIR/app-AfterInstall.yml"
22+
cp "$BASE_DIR/env.sh.sample" "$BASE_DIR/env.sh"
23+
clean_root_owned_docker_files
24+
rm -rf "$BUILD_DIR"
25+
mkdir "$BUILD_DIR"

bin/codedeploy/AfterInstall.sh

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
#!/usr/bin/env bash
2+
#
3+
# AfterInstall.sh
4+
#
5+
# AWS CodeDeploy After Install hook script
6+
7+
# Set bash unofficial strict mode http://redsymbol.net/articles/unofficial-bash-strict-mode/
8+
set -euo pipefail
9+
IFS=$'\n\t'
10+
11+
# Set DEBUG to true for enhanced debugging: run prefixed with "DEBUG=true"
12+
${DEBUG:-false} && set -vx
13+
# Credit to https://stackoverflow.com/a/17805088
14+
# and http://wiki.bash-hackers.org/scripting/debuggingtips
15+
export PS4='+(${BASH_SOURCE}:${LINENO}): ${FUNCNAME[0]:+${FUNCNAME[0]}(): }'
16+
17+
# Credit to http://stackoverflow.com/a/246128/424301
18+
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
19+
BASE_DIR="$DIR/../.."
20+
ANSIBLE_DIR="$BASE_DIR/ansible"
21+
22+
# Invoke Ansible for final set up
23+
ansible-playbook -l localhost "$ANSIBLE_DIR/app-AfterInstall.yml"
24+
25+
# Configure New Relic
26+
# TODO: move into Ansible playbook app-AfterInstall.yml
27+
NEWRELIC_CONFIG_DIR=/app
28+
VENV_DIR=/app/venv
29+
# Thanks Stack Overflow https://stackoverflow.com/a/9735663/424301
30+
EC2_AVAIL_ZONE=$(curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone)
31+
EC2_REGION="$(sed 's/[a-z]$//' <<<"$EC2_AVAIL_ZONE")"
32+
33+
NEWRELIC_LICENSE_KEY=$(aws secretsmanager get-secret-value \
34+
--region="$EC2_REGION" \
35+
--secret-id newrelic_license \
36+
--output text \
37+
--query '[SecretString]')
38+
set +u
39+
#shellcheck disable=SC1090
40+
source ${VENV_DIR}/bin/activate
41+
set -u
42+
newrelic-admin generate-config "${NEWRELIC_LICENSE_KEY}" "${NEWRELIC_CONFIG_DIR}/newrelic.ini.orig"
43+
sed 's/^app_name =.*$/app_name = Spin/' "${NEWRELIC_CONFIG_DIR}/newrelic.ini.orig" > "${NEWRELIC_CONFIG_DIR}/newrelic.ini"

0 commit comments

Comments
 (0)