Skip to content

Commit 8d012ea

Browse files
authored
Add python EC2 E2E tests. (#11)
Add python EC2 E2E tests.
1 parent 9a60335 commit 8d012ea

20 files changed

+1840
-3
lines changed
Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
Django~=4.2.9
22
requests~=2.31.0
33
boto3~=1.34.3
4-
requests~=2.31.0
54
schedule~=1.2.1
6-
python-dotenv~=1.0.0
5+
python-dotenv~=1.0.1
76
opentelemetry-api~=1.22.0

terraform/python/ec2/main.tf

Lines changed: 231 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,231 @@
1+
# ------------------------------------------------------------------------
2+
# Copyright 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License").
5+
# You may not use this file except in compliance with the License.
6+
# A copy of the License is located at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# or in the "license" file accompanying this file. This file is distributed
11+
# on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12+
# express or implied. See the License for the specific language governing
13+
# permissions and limitations under the License.
14+
# -------------------------------------------------------------------------
15+
16+
terraform {
17+
required_providers {
18+
aws = {
19+
source = "hashicorp/aws"
20+
}
21+
}
22+
}
23+
24+
# Define the provider for AWS
25+
provider "aws" {}
26+
27+
resource "aws_default_vpc" "default" {}
28+
29+
resource "tls_private_key" "ssh_key" {
30+
algorithm = "RSA"
31+
rsa_bits = 4096
32+
}
33+
34+
resource "aws_key_pair" "aws_ssh_key" {
35+
key_name = "instance_key-${var.test_id}"
36+
public_key = tls_private_key.ssh_key.public_key_openssh
37+
}
38+
39+
locals {
40+
ssh_key_name = aws_key_pair.aws_ssh_key.key_name
41+
private_key_content = tls_private_key.ssh_key.private_key_pem
42+
}
43+
44+
data "aws_ami" "ami" {
45+
owners = ["amazon"]
46+
most_recent = true
47+
filter {
48+
name = "name"
49+
values = ["al2023-ami-2023.3.20240117.0-kernel-6.1-x86_64"]
50+
}
51+
filter {
52+
name = "state"
53+
values = ["available"]
54+
}
55+
filter {
56+
name = "architecture"
57+
values = ["x86_64"]
58+
}
59+
filter {
60+
name = "image-type"
61+
values = ["machine"]
62+
}
63+
64+
filter {
65+
name = "root-device-name"
66+
values = ["/dev/xvda"]
67+
}
68+
69+
filter {
70+
name = "root-device-type"
71+
values = ["ebs"]
72+
}
73+
74+
filter {
75+
name = "virtualization-type"
76+
values = ["hvm"]
77+
}
78+
}
79+
80+
resource "aws_instance" "main_service_instance" {
81+
ami = data.aws_ami.ami.id # Amazon Linux 2 (free tier)
82+
instance_type = "t3.small"
83+
key_name = local.ssh_key_name
84+
iam_instance_profile = "APP_SIGNALS_EC2_TEST_ROLE"
85+
vpc_security_group_ids = [aws_default_vpc.default.default_security_group_id]
86+
associate_public_ip_address = true
87+
instance_initiated_shutdown_behavior = "terminate"
88+
metadata_options {
89+
http_tokens = "required"
90+
}
91+
92+
tags = {
93+
Name = "main-service-${var.test_id}"
94+
}
95+
}
96+
97+
resource "null_resource" "main_service_setup" {
98+
connection {
99+
type = "ssh"
100+
user = var.user
101+
private_key = local.private_key_content
102+
host = aws_instance.main_service_instance.public_ip
103+
}
104+
105+
provisioner "remote-exec" {
106+
inline = [
107+
# Install Python and wget
108+
"sudo yum install wget -y",
109+
"sudo yum install unzip -y",
110+
"sudo dnf install -y python3.9",
111+
"sudo dnf install -y python3.9-pip",
112+
113+
# Copy in CW Agent configuration
114+
"agent_config='${replace(replace(file("../../ec2/amazon-cloudwatch-agent.json"), "/\\s+/", ""), "$REGION", var.aws_region)}'",
115+
"echo $agent_config > amazon-cloudwatch-agent.json",
116+
117+
# Get and run CW agent rpm
118+
"wget -O cw-agent.rpm https://amazoncloudwatch-agent-us-east-1.s3.us-east-1.amazonaws.com/amazon_linux/amd64/1.300031.0b313/amazon-cloudwatch-agent.rpm",
119+
"sudo rpm -U ./cw-agent.rpm",
120+
"sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -s -c file:./amazon-cloudwatch-agent.json",
121+
122+
# Get ADOT Wheel and install it
123+
"${var.get_adot_wheel_command}",
124+
125+
# Get and run the sample application with configuration
126+
"aws s3 cp ${var.sample_app_zip} ./python-sample-app.zip",
127+
"unzip -o python-sample-app.zip",
128+
129+
# Export environment variables for instrumentation
130+
"cd ./django_frontend_service",
131+
"python3.9 -m pip install -r requirements.txt",
132+
"export DJANGO_SETTINGS_MODULE=\"django_frontend_service.settings\"",
133+
"export OTEL_PYTHON_DISTRO=\"aws_distro\"",
134+
"export OTEL_PYTHON_CONFIGURATOR=\"aws_configurator\"",
135+
"export OTEL_METRICS_EXPORTER=none",
136+
"export OTEL_TRACES_EXPORTER=otlp",
137+
"export OTEL_AWS_APP_SIGNALS_ENABLED=true",
138+
"export OTEL_AWS_APP_SIGNALS_EXPORTER_ENDPOINT=http://localhost:4315",
139+
"export OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=http://localhost:4315",
140+
"export OTEL_EXPORTER_OTLP_TRACES_PROTOCOL=grpc",
141+
"export OTEL_EXPORTER_OTLP_METRICS_PROTOCOL=grpc",
142+
"export OTEL_SERVICE_NAME=python-sample-application-${var.test_id}",
143+
"export OTEL_RESOURCE_ATTRIBUTES=aws.hostedin.environment=EC2",
144+
"export OTEL_TRACES_SAMPLER=always_on",
145+
"python3.9 manage.py migrate",
146+
"nohup opentelemetry-instrument python3.9 manage.py runserver 0.0.0.0:8000 --noreload &",
147+
148+
# The application needs time to come up and reach a steady state, this should not take longer than 30 seconds
149+
"sleep 30"
150+
]
151+
}
152+
153+
depends_on = [aws_instance.main_service_instance]
154+
}
155+
156+
resource "aws_instance" "remote_service_instance" {
157+
ami = data.aws_ami.ami.id # Amazon Linux 2 (free tier)
158+
instance_type = "t3.small"
159+
key_name = local.ssh_key_name
160+
iam_instance_profile = "APP_SIGNALS_EC2_TEST_ROLE"
161+
vpc_security_group_ids = [aws_default_vpc.default.default_security_group_id]
162+
associate_public_ip_address = true
163+
instance_initiated_shutdown_behavior = "terminate"
164+
metadata_options {
165+
http_tokens = "required"
166+
}
167+
168+
tags = {
169+
Name = "remote-service-${var.test_id}"
170+
}
171+
}
172+
173+
resource "null_resource" "remote_service_setup" {
174+
connection {
175+
type = "ssh"
176+
user = var.user
177+
private_key = local.private_key_content
178+
host = aws_instance.remote_service_instance.public_ip
179+
}
180+
181+
provisioner "remote-exec" {
182+
inline = [
183+
# Install Python and wget
184+
"sudo yum install wget -y",
185+
"sudo yum install unzip -y",
186+
"sudo dnf install -y python3.9",
187+
"sudo dnf install -y python3.9-pip",
188+
189+
# Copy in CW Agent configuration
190+
"agent_config='${replace(replace(file("../../ec2/amazon-cloudwatch-agent.json"), "/\\s+/", ""), "$REGION", var.aws_region)}'",
191+
"echo $agent_config > amazon-cloudwatch-agent.json",
192+
193+
# Get and run CW agent rpm
194+
"wget -O cw-agent.rpm https://amazoncloudwatch-agent-us-east-1.s3.us-east-1.amazonaws.com/amazon_linux/amd64/1.300031.0b313/amazon-cloudwatch-agent.rpm",
195+
"sudo rpm -U ./cw-agent.rpm",
196+
"sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -s -c file:./amazon-cloudwatch-agent.json",
197+
198+
# Get ADOT Wheel and install it
199+
"${var.get_adot_wheel_command}",
200+
201+
# Get and run the sample application with configuration
202+
"aws s3 cp ${var.sample_app_zip} ./python-sample-app.zip",
203+
"unzip -o python-sample-app.zip",
204+
205+
# Export environment variables for instrumentation
206+
"cd ./django_remote_service",
207+
"export DJANGO_SETTINGS_MODULE=\"django_remote_service.settings\"",
208+
"python3.9 -m pip install -r requirements.txt --force-reinstall",
209+
"export OTEL_PYTHON_DISTRO=\"aws_distro\"",
210+
"export OTEL_PYTHON_CONFIGURATOR=\"aws_configurator\"",
211+
"export OTEL_METRICS_EXPORTER=none",
212+
"export OTEL_TRACES_EXPORTER=otlp",
213+
"export OTEL_AWS_APP_SIGNALS_ENABLED=true",
214+
"export OTEL_AWS_APP_SIGNALS_EXPORTER_ENDPOINT=http://localhost:4315",
215+
"export OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=http://localhost:4315",
216+
"export OTEL_EXPORTER_OTLP_TRACES_PROTOCOL=grpc",
217+
"export OTEL_EXPORTER_OTLP_METRICS_PROTOCOL=grpc",
218+
"export OTEL_SERVICE_NAME=python-sample-remote-application-${var.test_id}",
219+
"export OTEL_RESOURCE_ATTRIBUTES=aws.hostedin.environment=EC2",
220+
"export OTEL_TRACES_SAMPLER=always_on",
221+
"python3.9 manage.py migrate",
222+
"nohup opentelemetry-instrument python3.9 manage.py runserver 0.0.0.0:8001 --noreload &",
223+
224+
225+
# The application needs time to come up and reach a steady state, this should not take longer than 30 seconds
226+
"sleep 30"
227+
]
228+
}
229+
230+
depends_on = [aws_instance.remote_service_instance]
231+
}

terraform/python/ec2/output.tf

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# ------------------------------------------------------------------------
2+
# Copyright 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License").
5+
# You may not use this file except in compliance with the License.
6+
# A copy of the License is located at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# or in the "license" file accompanying this file. This file is distributed
11+
# on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12+
# express or implied. See the License for the specific language governing
13+
# permissions and limitations under the License.
14+
# -------------------------------------------------------------------------
15+
16+
output "sample_app_main_service_public_dns" {
17+
value = aws_instance.main_service_instance.public_dns
18+
}
19+
20+
output "sample_app_remote_service_public_ip" {
21+
value = aws_instance.remote_service_instance.public_ip
22+
}
23+
24+
output "ec2_instance_ami" {
25+
value = data.aws_ami.ami.id
26+
}

terraform/python/ec2/variables.tf

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# ------------------------------------------------------------------------
2+
# Copyright 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License").
5+
# You may not use this file except in compliance with the License.
6+
# A copy of the License is located at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# or in the "license" file accompanying this file. This file is distributed
11+
# on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12+
# express or implied. See the License for the specific language governing
13+
# permissions and limitations under the License.
14+
# -------------------------------------------------------------------------
15+
16+
variable "test_id" {
17+
default = "dummy-123"
18+
}
19+
20+
variable "aws_region" {
21+
default = "<aws-region>"
22+
}
23+
24+
variable "user" {
25+
default = "ec2-user"
26+
}
27+
28+
variable "sample_app_zip" {
29+
default = "s3://<bucket-name>/<zip>"
30+
}
31+
32+
variable "get_adot_wheel_command" {
33+
default = "aws s3 cp s3://<bucket-name>/<whl> ./<whl> && pip install <whl>"
34+
}
35+
36+
variable "get_cw_agent_rpm_command" {
37+
default = "<command> s3://<bucket-name>/<jar>"
38+
}

validator/src/main/java/com/amazon/aoc/fileconfigs/PredefinedExpectedTemplate.java

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ public enum PredefinedExpectedTemplate implements FileConfig {
3939
EKS_CLIENT_CALL_METRIC("/expected-data-template/eks/client-call-metric.mustache"),
4040
EKS_CLIENT_CALL_TRACE("/expected-data-template/eks/client-call-trace.mustache"),
4141

42-
/** EC2 Test Case Validations */
42+
/** Java EC2 Test Case Validations */
4343
EC2_OUTGOING_HTTP_CALL_LOG("/expected-data-template/ec2/outgoing-http-call-log.mustache"),
4444
EC2_OUTGOING_HTTP_CALL_METRIC("/expected-data-template/ec2/outgoing-http-call-metric.mustache"),
4545
EC2_OUTGOING_HTTP_CALL_TRACE("/expected-data-template/ec2/outgoing-http-call-trace.mustache"),
@@ -55,6 +55,23 @@ public enum PredefinedExpectedTemplate implements FileConfig {
5555
EC2_CLIENT_CALL_LOG("/expected-data-template/ec2/client-call-log.mustache"),
5656
EC2_CLIENT_CALL_METRIC("/expected-data-template/ec2/client-call-metric.mustache"),
5757
EC2_CLIENT_CALL_TRACE("/expected-data-template/ec2/client-call-trace.mustache"),
58+
59+
/** Python EC2 Test Case Validations */
60+
PYTHON_EC2_OUTGOING_HTTP_CALL_LOG("/expected-data-template/python/ec2/outgoing-http-call-log.mustache"),
61+
PYTHON_EC2_OUTGOING_HTTP_CALL_METRIC("/expected-data-template/python/ec2/outgoing-http-call-metric.mustache"),
62+
PYTHON_EC2_OUTGOING_HTTP_CALL_TRACE("/expected-data-template/python/ec2/outgoing-http-call-trace.mustache"),
63+
64+
PYTHON_EC2_AWS_SDK_CALL_LOG("/expected-data-template/python/ec2/aws-sdk-call-log.mustache"),
65+
PYTHON_EC2_AWS_SDK_CALL_METRIC("/expected-data-template/python/ec2/aws-sdk-call-metric.mustache"),
66+
PYTHON_EC2_AWS_SDK_CALL_TRACE("/expected-data-template/python/ec2/aws-sdk-call-trace.mustache"),
67+
68+
PYTHON_EC2_REMOTE_SERVICE_LOG("/expected-data-template/python/ec2/remote-service-log.mustache"),
69+
PYTHON_EC2_REMOTE_SERVICE_METRIC("/expected-data-template/python/ec2/remote-service-metric.mustache"),
70+
PYTHON_EC2_REMOTE_SERVICE_TRACE("/expected-data-template/python/ec2/remote-service-trace.mustache"),
71+
72+
PYTHON_EC2_CLIENT_CALL_LOG("/expected-data-template/python/ec2/client-call-log.mustache"),
73+
PYTHON_EC2_CLIENT_CALL_METRIC("/expected-data-template/python/ec2/client-call-metric.mustache"),
74+
PYTHON_EC2_CLIENT_CALL_TRACE("/expected-data-template/python/ec2/client-call-trace.mustache"),
5875
;
5976

6077
private String path;
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
[{
2+
"HostedIn.Environment": "^EC2$",
3+
"Operation": "GET aws-sdk-call",
4+
"OTelLib": "^AwsSpanMetricsProcessor$",
5+
"Version": "^1$",
6+
"aws.span.kind": "^LOCAL_ROOT$"
7+
},
8+
{
9+
"HostedIn.Environment": "^EC2$",
10+
"Operation": "GET aws-sdk-call",
11+
"OTelLib": "^AwsSpanMetricsProcessor$",
12+
"Version": "^1$",
13+
"RemoteService": "AWS.SDK.S3",
14+
"RemoteOperation": "GetBucketLocation",
15+
"RemoteTarget": "::s3:::e2e-test-bucket-name",
16+
"aws.span.kind": "^CLIENT$"
17+
}]

0 commit comments

Comments
 (0)