Skip to content

Commit 2b5a130

Browse files
authored
Integration Test Workflow (#246)
* Adding integration testing workflow and terraform files * Added workflow to execute on pull request only * modified tfvars file name * Added resource_prefix var, os name * Applied constant var directly * Added -var parameter to fetch github run_id env variable * remove resource_prefix logic and solve secret repo access issue * test checking out from secret repo * test pulling secret repo * fixing destroying resources * added debug logic to fix plugins permissions issue * debug logic to check plugins dir location * removed download artifact step * debug logic * debug permission issue * debug permission issue - 2 * debug permission issue * debug permission issue * debug destroy resources * fix: destroy resources * remove unnecessary steps * fix: end to end workflow * Added resource_prefix var * Added env variable to set resource_prefix * removed constant vars from tfvars and used env variable to populate values * modified names * fix: eb url * minor changes * minor changes * Added sse encryption to s3 and eb updated config * Added public access setting to bucket, sse encrpytion and fix eb issue * eb issue: try * Added integ test runner repo * Added repo for sample app, test runner * minor change * execute workflow on push too * Added secret PAT to test workflow * Added validator module * Added gradle execution command * minor change * minor change: added branch * Added aws creds * fixed issue * minor cleanups * modified testing module and webapp module * Added logic to create unique names in case of re running same workflow * added sample-apps dir * fixed syntax issue * added path in upload and download actions * Added license file * workflow executes on push
1 parent 0081cdf commit 2b5a130

File tree

8 files changed

+371
-0
lines changed

8 files changed

+371
-0
lines changed
Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
name: Integration Testing
2+
on: push
3+
4+
jobs:
5+
build_SDK:
6+
name: Build X-Ray Python SDK
7+
runs-on: ubuntu-latest
8+
9+
steps:
10+
- name: Pull in source code from aws-xray-sdk-python Github repository
11+
uses: actions/checkout@v2
12+
13+
- name: Setup python
14+
uses: actions/setup-python@v2
15+
with:
16+
python-version: '3.8'
17+
18+
- name: Build X-Ray Python SDK
19+
run: python setup.py sdist
20+
21+
- name: Upload SDK build artifact
22+
uses: actions/upload-artifact@v2
23+
with:
24+
name: sdk-build-artifact
25+
path: .
26+
27+
build_WebApp:
28+
name: Build Web Application
29+
needs: build_SDK
30+
runs-on: ubuntu-latest
31+
32+
steps:
33+
- uses: actions/checkout@v2
34+
35+
- name: Setup python
36+
uses: actions/setup-python@v2
37+
with:
38+
python-version: '3.8'
39+
40+
- name: Download X-Ray SDK build artifact
41+
uses: actions/download-artifact@v2
42+
with:
43+
name: sdk-build-artifact
44+
path: ./sample-apps/flask
45+
46+
- name: Build WebApp with X-Ray Python SDK
47+
run: pip3 install . -t .
48+
working-directory: ./sample-apps/flask
49+
50+
- name: Zip up the deployment package
51+
run: zip -r deploy.zip . -x '*.git*'
52+
working-directory: ./sample-apps/flask
53+
54+
- name: Upload WebApp with X-Ray SDK build artifact
55+
uses: actions/upload-artifact@v2
56+
with:
57+
name: sdk-flask-build-artifact
58+
path: ./sample-apps/flask/deploy.zip
59+
60+
deploy_WebApp:
61+
name: Deploy Web Application
62+
needs: build_WebApp
63+
runs-on: ubuntu-latest
64+
65+
steps:
66+
- name: Checkout X-Ray SDK to get terraform source
67+
uses: actions/checkout@v2
68+
69+
- name: Download WebApp with X-Ray SDK build artifact
70+
uses: actions/download-artifact@v2
71+
with:
72+
name: sdk-flask-build-artifact
73+
74+
- name: Copy deployment package to terraform directory
75+
run: cp deploy.zip ./terraform
76+
77+
- name: Configure AWS Credentials
78+
uses: aws-actions/configure-aws-credentials@v1
79+
with:
80+
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
81+
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
82+
aws-region: us-west-2
83+
84+
- name: Setup Terraform
85+
uses: hashicorp/setup-terraform@v1
86+
87+
- name: Terraform Init
88+
run: terraform init
89+
working-directory: ./terraform
90+
91+
- name: Terraform Validate
92+
run: terraform validate -no-color
93+
working-directory: ./terraform
94+
95+
- name: Terraform Plan
96+
run: terraform plan -var-file="fixtures.us-west-2.tfvars" -no-color
97+
env:
98+
TF_VAR_resource_prefix: '${{ github.run_id }}-${{ github.run_number }}'
99+
continue-on-error: true
100+
working-directory: ./terraform
101+
102+
- name: Terraform Apply
103+
run: terraform apply -var-file="fixtures.us-west-2.tfvars" -auto-approve
104+
env:
105+
TF_VAR_resource_prefix: '${{ github.run_id }}-${{ github.run_number }}'
106+
working-directory: ./terraform
107+
108+
- name: Upload terraform state files for destorying resources
109+
uses: actions/upload-artifact@v2
110+
with:
111+
name: terraform-state-artifact
112+
path: ./terraform
113+
114+
test_WebApp:
115+
name: Test WebApp
116+
needs: deploy_WebApp
117+
runs-on: ubuntu-latest
118+
119+
steps:
120+
- uses: actions/setup-java@v1
121+
with:
122+
java-version: 14
123+
124+
- name: Configure AWS Credentials
125+
uses: aws-actions/configure-aws-credentials@v1
126+
with:
127+
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
128+
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
129+
aws-region: us-west-2
130+
131+
- name: Checkout test framework
132+
uses: actions/checkout@v2
133+
with:
134+
repository: aws-observability/aws-otel-test-framework
135+
ref: terraform
136+
137+
- name: Run testing suite
138+
run: ./gradlew :validator:run --args='-c default-xray-trace-validation.yml --endpoint http://${{ github.run_id }}-${{ github.run_number }}-eb-app-env.us-west-2.elasticbeanstalk.com'
139+
140+
cleanup:
141+
name: Resource tear down
142+
needs: test_WebApp
143+
if: true
144+
runs-on: ubuntu-latest
145+
146+
steps:
147+
- name: Download terraform state artifact
148+
uses: actions/download-artifact@v2
149+
with:
150+
name: terraform-state-artifact
151+
152+
- name: Configure AWS Credentials
153+
uses: aws-actions/configure-aws-credentials@v1
154+
with:
155+
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
156+
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
157+
aws-region: us-west-2
158+
159+
- name: Setup Terraform
160+
uses: hashicorp/setup-terraform@v1
161+
162+
- name: Terraform Init
163+
run: terraform init
164+
165+
- name: set permissions to terraform plugins
166+
run: chmod -R a+x .terraform/plugins/registry.terraform.io/hashicorp/aws/3.5.0/linux_amd64/*
167+
168+
- name: Destroy resources
169+
run: terraform destroy -state="terraform.tfstate" -var-file="fixtures.us-west-2.tfvars" -auto-approve
170+
env:
171+
TF_VAR_resource_prefix: '${{ github.run_id }}-${{ github.run_number }}'

sample-apps/LICENSE

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
3+
Permission is hereby granted, free of charge, to any person obtaining a copy of this
4+
software and associated documentation files (the "Software"), to deal in the Software
5+
without restriction, including without limitation the rights to use, copy, modify,
6+
merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
7+
permit persons to whom the Software is furnished to do so.
8+
9+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
10+
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
11+
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
12+
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
13+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
14+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

sample-apps/flask/Dockerfile

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
FROM python:3.6
2+
3+
WORKDIR /app
4+
5+
COPY . ./
6+
7+
RUN pip install -r requirements.txt
8+
9+
CMD ["python", "application.py"]

sample-apps/flask/application.py

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
import boto3
2+
from flask import Flask
3+
from aws_xray_sdk.core import xray_recorder, patch_all
4+
from aws_xray_sdk.ext.flask.middleware import XRayMiddleware
5+
from aws_xray_sdk.ext.flask_sqlalchemy.query import XRayFlaskSqlAlchemy
6+
import requests
7+
import os
8+
9+
application = app = Flask(__name__)
10+
application.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
11+
application.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///db.sqlite3"
12+
13+
xray_recorder.configure(service='My Flask Web Application')
14+
XRayMiddleware(app, xray_recorder)
15+
patch_all()
16+
17+
db = XRayFlaskSqlAlchemy(app=application)
18+
19+
20+
class User(db.Model):
21+
__tablename__ = 'users'
22+
23+
id = db.Column(db.Integer, primary_key=True)
24+
name = db.Column(db.String(255), nullable=False, unique=True)
25+
26+
27+
# test http instrumentation
28+
@app.route('/outgoing-http-call')
29+
def callHTTP():
30+
requests.get("https://aws.amazon.com")
31+
return "Ok! tracing outgoing http call"
32+
33+
34+
# test aws sdk instrumentation
35+
@app.route('/aws-sdk-call')
36+
def callAWSSDK():
37+
client = boto3.client('s3')
38+
client.list_buckets()
39+
40+
return 'Ok! tracing aws sdk call'
41+
42+
43+
# test flask-sql alchemy instrumentation
44+
@app.route('/flask-sql-alchemy-call')
45+
def callSQL():
46+
name = 'sql-alchemy-model'
47+
user = User(name=name)
48+
db.create_all()
49+
db.session.add(user)
50+
51+
return 'Ok! tracing sql call'
52+
53+
54+
@app.route('/')
55+
def default():
56+
return "healthcheck"
57+
58+
59+
if __name__ == "__main__":
60+
address = os.environ.get('LISTEN_ADDRESS')
61+
62+
if address is None:
63+
host = '127.0.0.1'
64+
port = '5000'
65+
else:
66+
host, port = address.split(":")
67+
app.run(host=host, port=int(port), debug=True)

sample-apps/flask/requirements.txt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
boto3
2+
certifi==2020.4.5.1
3+
chardet==3.0.4
4+
click==7.1.2
5+
Flask==1.1.2
6+
idna==2.9
7+
itsdangerous==1.1.0
8+
Jinja2==2.11.2
9+
MarkupSafe==1.1.1
10+
requests==2.23.0
11+
urllib3==1.25.9
12+
Werkzeug==1.0.1
13+
flask-sqlalchemy==2.4.3
14+
aws_xray_sdk==2.6.0

terraform/eb.tf

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
terraform {
2+
required_providers {
3+
aws = {
4+
source = "hashicorp/aws"
5+
version = "3.5.0"
6+
}
7+
}
8+
}
9+
10+
provider "aws" {
11+
profile = "default"
12+
region = var.region
13+
}
14+
15+
resource "aws_s3_bucket_public_access_block" "bucket_access" {
16+
bucket = aws_s3_bucket.eb_app_bucket.id
17+
18+
restrict_public_buckets = true
19+
}
20+
21+
resource "aws_s3_bucket" "eb_app_bucket" {
22+
bucket = "${var.resource_prefix}.eb.app.applicationversion"
23+
24+
versioning {
25+
enabled = true
26+
}
27+
28+
server_side_encryption_configuration {
29+
rule {
30+
apply_server_side_encryption_by_default {
31+
sse_algorithm = "AES256"
32+
}
33+
}
34+
}
35+
}
36+
37+
resource "aws_s3_bucket_object" "eb_app_package" {
38+
bucket = aws_s3_bucket.eb_app_bucket.id
39+
key = var.bucket_key
40+
source = var.source_path
41+
}
42+
43+
resource "aws_elastic_beanstalk_application" "eb_app" {
44+
name = "${var.resource_prefix}-EB-App"
45+
description = "Deployment of EB App for integration testing"
46+
}
47+
48+
resource "aws_elastic_beanstalk_application_version" "eb_app_version" {
49+
name = "${var.resource_prefix}-EB-App-1"
50+
application = aws_elastic_beanstalk_application.eb_app.name
51+
bucket = aws_s3_bucket.eb_app_bucket.id
52+
key = aws_s3_bucket_object.eb_app_package.id
53+
}
54+
55+
resource "aws_elastic_beanstalk_environment" "eb_env" {
56+
name = "${var.resource_prefix}-EB-App-Env"
57+
application = aws_elastic_beanstalk_application.eb_app.name
58+
solution_stack_name = "64bit Amazon Linux 2 v3.1.1 running Python 3.7"
59+
tier = "WebServer"
60+
version_label = aws_elastic_beanstalk_application_version.eb_app_version.name
61+
cname_prefix = "${var.resource_prefix}-Eb-app-env"
62+
63+
setting {
64+
namespace = "aws:autoscaling:launchconfiguration"
65+
name = "IamInstanceProfile"
66+
value = "aws-elasticbeanstalk-ec2-role"
67+
}
68+
69+
setting {
70+
namespace = "aws:elasticbeanstalk:xray"
71+
name = "XRayEnabled"
72+
value = "true"
73+
}
74+
}

terraform/fixtures.us-west-2.tfvars

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
region = "us-west-2"
2+
3+
bucket_key = "beanstalk/deploy.zip"
4+
5+
source_path = "deploy.zip"

terraform/variables.tf

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
variable "region" {
2+
type = string
3+
description = "AWS region for deployment of resources"
4+
}
5+
6+
variable "bucket_key" {
7+
type = string
8+
description = "AWS s3 object key"
9+
}
10+
11+
variable "source_path" {
12+
type = string
13+
description = "local source zip path to upload on AWS s3 bucket"
14+
}
15+
16+
variable "resource_prefix" {}
17+

0 commit comments

Comments
 (0)