awslabs.cloudwatch-applicationsignals-mcp-server 0.1.21__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- awslabs/__init__.py +17 -0
- awslabs/cloudwatch_applicationsignals_mcp_server/__init__.py +17 -0
- awslabs/cloudwatch_applicationsignals_mcp_server/audit_presentation_utils.py +288 -0
- awslabs/cloudwatch_applicationsignals_mcp_server/audit_utils.py +912 -0
- awslabs/cloudwatch_applicationsignals_mcp_server/aws_clients.py +120 -0
- awslabs/cloudwatch_applicationsignals_mcp_server/canary_utils.py +910 -0
- awslabs/cloudwatch_applicationsignals_mcp_server/enablement_guides/templates/ec2/ec2-dotnet-enablement.md +435 -0
- awslabs/cloudwatch_applicationsignals_mcp_server/enablement_guides/templates/ec2/ec2-java-enablement.md +321 -0
- awslabs/cloudwatch_applicationsignals_mcp_server/enablement_guides/templates/ec2/ec2-nodejs-enablement.md +420 -0
- awslabs/cloudwatch_applicationsignals_mcp_server/enablement_guides/templates/ec2/ec2-python-enablement.md +598 -0
- awslabs/cloudwatch_applicationsignals_mcp_server/enablement_guides/templates/ecs/ecs-dotnet-enablement.md +264 -0
- awslabs/cloudwatch_applicationsignals_mcp_server/enablement_guides/templates/ecs/ecs-java-enablement.md +193 -0
- awslabs/cloudwatch_applicationsignals_mcp_server/enablement_guides/templates/ecs/ecs-nodejs-enablement.md +198 -0
- awslabs/cloudwatch_applicationsignals_mcp_server/enablement_guides/templates/ecs/ecs-python-enablement.md +236 -0
- awslabs/cloudwatch_applicationsignals_mcp_server/enablement_guides/templates/eks/eks-dotnet-enablement.md +166 -0
- awslabs/cloudwatch_applicationsignals_mcp_server/enablement_guides/templates/eks/eks-java-enablement.md +166 -0
- awslabs/cloudwatch_applicationsignals_mcp_server/enablement_guides/templates/eks/eks-nodejs-enablement.md +166 -0
- awslabs/cloudwatch_applicationsignals_mcp_server/enablement_guides/templates/eks/eks-python-enablement.md +169 -0
- awslabs/cloudwatch_applicationsignals_mcp_server/enablement_guides/templates/lambda/lambda-dotnet-enablement.md +336 -0
- awslabs/cloudwatch_applicationsignals_mcp_server/enablement_guides/templates/lambda/lambda-java-enablement.md +336 -0
- awslabs/cloudwatch_applicationsignals_mcp_server/enablement_guides/templates/lambda/lambda-nodejs-enablement.md +336 -0
- awslabs/cloudwatch_applicationsignals_mcp_server/enablement_guides/templates/lambda/lambda-python-enablement.md +336 -0
- awslabs/cloudwatch_applicationsignals_mcp_server/enablement_tools.py +147 -0
- awslabs/cloudwatch_applicationsignals_mcp_server/server.py +1505 -0
- awslabs/cloudwatch_applicationsignals_mcp_server/service_audit_utils.py +231 -0
- awslabs/cloudwatch_applicationsignals_mcp_server/service_tools.py +659 -0
- awslabs/cloudwatch_applicationsignals_mcp_server/sli_report_client.py +333 -0
- awslabs/cloudwatch_applicationsignals_mcp_server/slo_tools.py +386 -0
- awslabs/cloudwatch_applicationsignals_mcp_server/trace_tools.py +784 -0
- awslabs/cloudwatch_applicationsignals_mcp_server/utils.py +172 -0
- awslabs_cloudwatch_applicationsignals_mcp_server-0.1.21.dist-info/METADATA +808 -0
- awslabs_cloudwatch_applicationsignals_mcp_server-0.1.21.dist-info/RECORD +36 -0
- awslabs_cloudwatch_applicationsignals_mcp_server-0.1.21.dist-info/WHEEL +4 -0
- awslabs_cloudwatch_applicationsignals_mcp_server-0.1.21.dist-info/entry_points.txt +2 -0
- awslabs_cloudwatch_applicationsignals_mcp_server-0.1.21.dist-info/licenses/LICENSE +174 -0
- awslabs_cloudwatch_applicationsignals_mcp_server-0.1.21.dist-info/licenses/NOTICE +2 -0
|
@@ -0,0 +1,336 @@
|
|
|
1
|
+
# Task: Enable AWS Application Signals for Java on AWS Lambda
|
|
2
|
+
|
|
3
|
+
Your task is to modify Infrastructure as Code (IaC) files to enable AWS Application Signals for Java Lambda functions. You will:
|
|
4
|
+
|
|
5
|
+
1. Add IAM permissions for Application Signals
|
|
6
|
+
2. Configure X-Ray tracing
|
|
7
|
+
3. Add the ADOT Lambda layer
|
|
8
|
+
4. Set the required environment variables.
|
|
9
|
+
|
|
10
|
+
If you cannot determine a value (such as AWS Region): Ask the user for clarification before proceeding. Do not guess or make up values.
|
|
11
|
+
|
|
12
|
+
## Region-Specific Layer ARNs
|
|
13
|
+
|
|
14
|
+
Select the correct ARN for your region:
|
|
15
|
+
|
|
16
|
+
```json
|
|
17
|
+
{
|
|
18
|
+
"af-south-1": "arn:aws:lambda:af-south-1:904233096616:layer:AWSOpenTelemetryDistroJava:8",
|
|
19
|
+
"ap-east-1": "arn:aws:lambda:ap-east-1:888577020596:layer:AWSOpenTelemetryDistroJava:8",
|
|
20
|
+
"ap-northeast-1": "arn:aws:lambda:ap-northeast-1:615299751070:layer:AWSOpenTelemetryDistroJava:8",
|
|
21
|
+
"ap-northeast-2": "arn:aws:lambda:ap-northeast-2:615299751070:layer:AWSOpenTelemetryDistroJava:8",
|
|
22
|
+
"ap-northeast-3": "arn:aws:lambda:ap-northeast-3:615299751070:layer:AWSOpenTelemetryDistroJava:8",
|
|
23
|
+
"ap-south-1": "arn:aws:lambda:ap-south-1:615299751070:layer:AWSOpenTelemetryDistroJava:8",
|
|
24
|
+
"ap-south-2": "arn:aws:lambda:ap-south-2:796973505492:layer:AWSOpenTelemetryDistroJava:8",
|
|
25
|
+
"ap-southeast-1": "arn:aws:lambda:ap-southeast-1:615299751070:layer:AWSOpenTelemetryDistroJava:8",
|
|
26
|
+
"ap-southeast-2": "arn:aws:lambda:ap-southeast-2:615299751070:layer:AWSOpenTelemetryDistroJava:8",
|
|
27
|
+
"ap-southeast-3": "arn:aws:lambda:ap-southeast-3:039612877180:layer:AWSOpenTelemetryDistroJava:8",
|
|
28
|
+
"ap-southeast-4": "arn:aws:lambda:ap-southeast-4:713881805771:layer:AWSOpenTelemetryDistroJava:8",
|
|
29
|
+
"ap-southeast-5": "arn:aws:lambda:ap-southeast-5:152034782359:layer:AWSOpenTelemetryDistroJava:5",
|
|
30
|
+
"ap-southeast-7": "arn:aws:lambda:ap-southeast-7:980416031188:layer:AWSOpenTelemetryDistroJava:5",
|
|
31
|
+
"ca-central-1": "arn:aws:lambda:ca-central-1:615299751070:layer:AWSOpenTelemetryDistroJava:8",
|
|
32
|
+
"ca-west-1": "arn:aws:lambda:ca-west-1:595944127152:layer:AWSOpenTelemetryDistroJava:5",
|
|
33
|
+
"cn-north-1": "arn:aws-cn:lambda:cn-north-1:440179912924:layer:AWSOpenTelemetryDistroJava:5",
|
|
34
|
+
"cn-northwest-1": "arn:aws-cn:lambda:cn-northwest-1:440180067931:layer:AWSOpenTelemetryDistroJava:5",
|
|
35
|
+
"eu-central-1": "arn:aws:lambda:eu-central-1:615299751070:layer:AWSOpenTelemetryDistroJava:8",
|
|
36
|
+
"eu-central-2": "arn:aws:lambda:eu-central-2:156041407956:layer:AWSOpenTelemetryDistroJava:8",
|
|
37
|
+
"eu-north-1": "arn:aws:lambda:eu-north-1:615299751070:layer:AWSOpenTelemetryDistroJava:8",
|
|
38
|
+
"eu-south-1": "arn:aws:lambda:eu-south-1:257394471194:layer:AWSOpenTelemetryDistroJava:8",
|
|
39
|
+
"eu-south-2": "arn:aws:lambda:eu-south-2:490004653786:layer:AWSOpenTelemetryDistroJava:8",
|
|
40
|
+
"eu-west-1": "arn:aws:lambda:eu-west-1:615299751070:layer:AWSOpenTelemetryDistroJava:8",
|
|
41
|
+
"eu-west-2": "arn:aws:lambda:eu-west-2:615299751070:layer:AWSOpenTelemetryDistroJava:8",
|
|
42
|
+
"eu-west-3": "arn:aws:lambda:eu-west-3:615299751070:layer:AWSOpenTelemetryDistroJava:8",
|
|
43
|
+
"il-central-1": "arn:aws:lambda:il-central-1:746669239226:layer:AWSOpenTelemetryDistroJava:8",
|
|
44
|
+
"me-central-1": "arn:aws:lambda:me-central-1:739275441131:layer:AWSOpenTelemetryDistroJava:8",
|
|
45
|
+
"me-south-1": "arn:aws:lambda:me-south-1:980921751758:layer:AWSOpenTelemetryDistroJava:8",
|
|
46
|
+
"mx-central-1": "arn:aws:lambda:mx-central-1:610118373846:layer:AWSOpenTelemetryDistroJava:5",
|
|
47
|
+
"sa-east-1": "arn:aws:lambda:sa-east-1:615299751070:layer:AWSOpenTelemetryDistroJava:8",
|
|
48
|
+
"us-east-1": "arn:aws:lambda:us-east-1:615299751070:layer:AWSOpenTelemetryDistroJava:8",
|
|
49
|
+
"us-east-2": "arn:aws:lambda:us-east-2:615299751070:layer:AWSOpenTelemetryDistroJava:8",
|
|
50
|
+
"us-west-1": "arn:aws:lambda:us-west-1:615299751070:layer:AWSOpenTelemetryDistroJava:8",
|
|
51
|
+
"us-west-2": "arn:aws:lambda:us-west-2:615299751070:layer:AWSOpenTelemetryDistroJava:8",
|
|
52
|
+
"us-gov-east-1": "arn:aws-us-gov:lambda:us-gov-east-1:399711857375:layer:AWSOpenTelemetryDistroJava:1",
|
|
53
|
+
"us-gov-west-1": "arn:aws-us-gov:lambda:us-gov-west-1:399727141365:layer:AWSOpenTelemetryDistroJava:1"
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Instructions
|
|
58
|
+
|
|
59
|
+
### Step 1: Add IAM Permissions
|
|
60
|
+
|
|
61
|
+
Add the AWS managed policy `CloudWatchLambdaApplicationSignalsExecutionRolePolicy` to the Lambda function's execution role.
|
|
62
|
+
|
|
63
|
+
**CDK:**
|
|
64
|
+
```typescript
|
|
65
|
+
const role = new iam.Role(this, 'LambdaRole', {
|
|
66
|
+
assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'),
|
|
67
|
+
managedPolicies: [
|
|
68
|
+
iam.ManagedPolicy.fromAwsManagedPolicyName('service-role/AWSLambdaBasicExecutionRole'),
|
|
69
|
+
iam.ManagedPolicy.fromAwsManagedPolicyName('CloudWatchLambdaApplicationSignalsExecutionRolePolicy'),
|
|
70
|
+
// ... keep existing policies
|
|
71
|
+
],
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
const myFunction = new lambda.Function(this, 'MyFunction', {
|
|
75
|
+
// ... existing configuration
|
|
76
|
+
role: role,
|
|
77
|
+
});
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
**Terraform:**
|
|
81
|
+
```hcl
|
|
82
|
+
resource "aws_iam_role" "lambda_role" {
|
|
83
|
+
name = "lambda-role"
|
|
84
|
+
assume_role_policy = jsonencode({
|
|
85
|
+
Version = "2012-10-17"
|
|
86
|
+
Statement = [
|
|
87
|
+
{
|
|
88
|
+
Action = "sts:AssumeRole"
|
|
89
|
+
Effect = "Allow"
|
|
90
|
+
Principal = {
|
|
91
|
+
Service = "lambda.amazonaws.com"
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
]
|
|
95
|
+
})
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
resource "aws_iam_role_policy_attachment" "lambda_basic" {
|
|
99
|
+
role = aws_iam_role.lambda_role.name
|
|
100
|
+
policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
resource "aws_iam_role_policy_attachment" "application_signals" {
|
|
104
|
+
role = aws_iam_role.lambda_role.name
|
|
105
|
+
policy_arn = "arn:aws:iam::aws:policy/CloudWatchLambdaApplicationSignalsExecutionRolePolicy"
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
resource "aws_lambda_function" "my_function" {
|
|
109
|
+
# ... existing configuration
|
|
110
|
+
role = aws_iam_role.lambda_role.arn
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
**CloudFormation:**
|
|
115
|
+
```yaml
|
|
116
|
+
LambdaRole:
|
|
117
|
+
Type: AWS::IAM::Role
|
|
118
|
+
Properties:
|
|
119
|
+
AssumeRolePolicyDocument:
|
|
120
|
+
Version: '2012-10-17'
|
|
121
|
+
Statement:
|
|
122
|
+
- Effect: Allow
|
|
123
|
+
Principal:
|
|
124
|
+
Service: lambda.amazonaws.com
|
|
125
|
+
Action: sts:AssumeRole
|
|
126
|
+
ManagedPolicyArns:
|
|
127
|
+
- arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
|
|
128
|
+
- arn:aws:iam::aws:policy/CloudWatchLambdaApplicationSignalsExecutionRolePolicy
|
|
129
|
+
# ... keep existing policies
|
|
130
|
+
|
|
131
|
+
MyFunction:
|
|
132
|
+
Type: AWS::Lambda::Function
|
|
133
|
+
Properties:
|
|
134
|
+
# ... existing configuration
|
|
135
|
+
Role: !GetAtt LambdaRole.Arn
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### Step 2: Enable X-Ray Active Tracing
|
|
139
|
+
|
|
140
|
+
**CDK:**
|
|
141
|
+
```typescript
|
|
142
|
+
const myFunction = new lambda.Function(this, 'MyFunction', {
|
|
143
|
+
// ... existing configuration
|
|
144
|
+
tracing: lambda.Tracing.ACTIVE,
|
|
145
|
+
});
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
**Terraform:**
|
|
149
|
+
```hcl
|
|
150
|
+
resource "aws_lambda_function" "my_function" {
|
|
151
|
+
# ... existing configuration
|
|
152
|
+
tracing_config {
|
|
153
|
+
mode = "Active"
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
**CloudFormation:**
|
|
159
|
+
```yaml
|
|
160
|
+
MyFunction:
|
|
161
|
+
Type: AWS::Lambda::Function
|
|
162
|
+
Properties:
|
|
163
|
+
# ... existing configuration
|
|
164
|
+
TracingConfig:
|
|
165
|
+
Mode: Active
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### Step 3: Add ADOT Java Lambda Layer
|
|
169
|
+
|
|
170
|
+
Use the layer name `AWSOpenTelemetryDistroJava` with automatic region detection. The code below includes a complete mapping that will automatically select the correct layer ARN based on your deployment region.
|
|
171
|
+
|
|
172
|
+
**CDK:**
|
|
173
|
+
```typescript
|
|
174
|
+
const layerArns: { [region: string]: string } = {
|
|
175
|
+
'af-south-1': 'arn:aws:lambda:af-south-1:904233096616:layer:AWSOpenTelemetryDistroJava:8',
|
|
176
|
+
'ap-east-1': 'arn:aws:lambda:ap-east-1:888577020596:layer:AWSOpenTelemetryDistroJava:8',
|
|
177
|
+
// ... (see Region-Specific Layer ARNs section above for complete mapping)
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
const myFunction = new lambda.Function(this, 'MyFunction', {
|
|
181
|
+
// ... existing configuration
|
|
182
|
+
layers: [
|
|
183
|
+
// ... keep existing layers
|
|
184
|
+
lambda.LayerVersion.fromLayerVersionArn(
|
|
185
|
+
this,
|
|
186
|
+
'AdotLayer',
|
|
187
|
+
layerArns[this.region]
|
|
188
|
+
),
|
|
189
|
+
],
|
|
190
|
+
});
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
**Terraform:**
|
|
194
|
+
```hcl
|
|
195
|
+
locals {
|
|
196
|
+
layer_arns = {
|
|
197
|
+
"af-south-1" = "arn:aws:lambda:af-south-1:904233096616:layer:AWSOpenTelemetryDistroJava:8"
|
|
198
|
+
"ap-east-1" = "arn:aws:lambda:ap-east-1:888577020596:layer:AWSOpenTelemetryDistroJava:8"
|
|
199
|
+
# ... (see Region-Specific Layer ARNs section above for complete mapping)
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
data "aws_region" "current" {}
|
|
204
|
+
|
|
205
|
+
resource "aws_lambda_function" "my_function" {
|
|
206
|
+
# ... existing configuration
|
|
207
|
+
layers = [
|
|
208
|
+
# ... keep existing layers
|
|
209
|
+
local.layer_arns[data.aws_region.current.name]
|
|
210
|
+
]
|
|
211
|
+
}
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
**CloudFormation:**
|
|
215
|
+
```yaml
|
|
216
|
+
Mappings:
|
|
217
|
+
LayerArns:
|
|
218
|
+
af-south-1:
|
|
219
|
+
arn: arn:aws:lambda:af-south-1:904233096616:layer:AWSOpenTelemetryDistroJava:8
|
|
220
|
+
ap-east-1:
|
|
221
|
+
arn: arn:aws:lambda:ap-east-1:888577020596:layer:AWSOpenTelemetryDistroJava:8
|
|
222
|
+
# ... (see Region-Specific Layer ARNs section above for complete mapping)
|
|
223
|
+
|
|
224
|
+
Resources:
|
|
225
|
+
MyFunction:
|
|
226
|
+
Type: AWS::Lambda::Function
|
|
227
|
+
Properties:
|
|
228
|
+
# ... existing configuration
|
|
229
|
+
Layers:
|
|
230
|
+
# ... keep existing layers
|
|
231
|
+
- !FindInMap [LayerArns, !Ref 'AWS::Region', arn]
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
### Step 4: Set Environment Variable
|
|
235
|
+
|
|
236
|
+
Add the `AWS_LAMBDA_EXEC_WRAPPER` environment variable with value `/opt/otel-instrument`.
|
|
237
|
+
|
|
238
|
+
**CDK:**
|
|
239
|
+
```typescript
|
|
240
|
+
const myFunction = new lambda.Function(this, 'MyFunction', {
|
|
241
|
+
// ... existing configuration
|
|
242
|
+
environment: {
|
|
243
|
+
// ... keep existing environment variables
|
|
244
|
+
AWS_LAMBDA_EXEC_WRAPPER: '/opt/otel-instrument',
|
|
245
|
+
},
|
|
246
|
+
});
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
**Terraform:**
|
|
250
|
+
```hcl
|
|
251
|
+
resource "aws_lambda_function" "my_function" {
|
|
252
|
+
# ... existing configuration
|
|
253
|
+
environment {
|
|
254
|
+
variables = {
|
|
255
|
+
# ... keep existing environment variables
|
|
256
|
+
AWS_LAMBDA_EXEC_WRAPPER = "/opt/otel-instrument"
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
**CloudFormation:**
|
|
263
|
+
```yaml
|
|
264
|
+
MyFunction:
|
|
265
|
+
Type: AWS::Lambda::Function
|
|
266
|
+
Properties:
|
|
267
|
+
# ... existing configuration
|
|
268
|
+
Environment:
|
|
269
|
+
Variables:
|
|
270
|
+
# ... keep existing environment variables
|
|
271
|
+
AWS_LAMBDA_EXEC_WRAPPER: /opt/otel-instrument
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
## Complete Example
|
|
275
|
+
|
|
276
|
+
**CDK:**
|
|
277
|
+
```typescript
|
|
278
|
+
const layerArns: { [region: string]: string } = {
|
|
279
|
+
'af-south-1': 'arn:aws:lambda:af-south-1:904233096616:layer:AWSOpenTelemetryDistroJava:8',
|
|
280
|
+
'ap-east-1': 'arn:aws:lambda:ap-east-1:888577020596:layer:AWSOpenTelemetryDistroJava:8',
|
|
281
|
+
// ... (see Region-Specific Layer ARNs section above for complete mapping)
|
|
282
|
+
};
|
|
283
|
+
|
|
284
|
+
const javaFunction = new lambda.Function(this, 'JavaFunction', {
|
|
285
|
+
runtime: lambda.Runtime.JAVA_17,
|
|
286
|
+
handler: 'com.example.Handler::handleRequest',
|
|
287
|
+
code: lambda.Code.fromAsset('target/my-app.jar'),
|
|
288
|
+
tracing: lambda.Tracing.ACTIVE,
|
|
289
|
+
layers: [
|
|
290
|
+
lambda.LayerVersion.fromLayerVersionArn(
|
|
291
|
+
this,
|
|
292
|
+
'AdotLayer',
|
|
293
|
+
layerArns[this.region]
|
|
294
|
+
),
|
|
295
|
+
],
|
|
296
|
+
environment: {
|
|
297
|
+
AWS_LAMBDA_EXEC_WRAPPER: '/opt/otel-instrument',
|
|
298
|
+
},
|
|
299
|
+
});
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
## Completion
|
|
303
|
+
|
|
304
|
+
**Tell the user:**
|
|
305
|
+
|
|
306
|
+
"I've completed the Application Signals enablement for your Java Lambda function. Here's what I modified:
|
|
307
|
+
|
|
308
|
+
**Configuration Changes:**
|
|
309
|
+
- IAM Permissions: Added CloudWatchLambdaApplicationSignalsExecutionRolePolicy
|
|
310
|
+
- X-Ray Tracing: Enabled active tracing
|
|
311
|
+
- ADOT Layer: Added AWSOpenTelemetryDistroJava layer
|
|
312
|
+
- Environment Variable: Set AWS_LAMBDA_EXEC_WRAPPER=/opt/otel-instrument
|
|
313
|
+
|
|
314
|
+
**Next Steps:**
|
|
315
|
+
1. Ensure that [Application Signals is enabled in AWS account](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch-Application-Signals-Enable.html).
|
|
316
|
+
2. Review the changes I made using `git diff`
|
|
317
|
+
3. Deploy your infrastructure:
|
|
318
|
+
- For CDK: `cdk deploy`
|
|
319
|
+
- For Terraform: `terraform apply`
|
|
320
|
+
- For CloudFormation: Deploy your stack
|
|
321
|
+
4. After deployment, invoke your Lambda function to generate telemetry data
|
|
322
|
+
|
|
323
|
+
**Verification:**
|
|
324
|
+
Once deployed, you can verify Application Signals is working by:
|
|
325
|
+
- Opening the AWS CloudWatch Console
|
|
326
|
+
- Navigating to Application Signals → Services
|
|
327
|
+
- Looking for your Lambda function service
|
|
328
|
+
- Checking that traces and metrics are being collected
|
|
329
|
+
|
|
330
|
+
**Monitor Application Health:**
|
|
331
|
+
After enablement, you can monitor your Lambda function's operational health using Application Signals dashboards. For more information, see [Monitor the operational health of your applications with Application Signals](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Services.html).
|
|
332
|
+
|
|
333
|
+
**Troubleshooting**
|
|
334
|
+
If you encounter any other issues, refer to the [CloudWatch APM troubleshooting guide](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch-Application-Signals-Enable-Troubleshoot.html).
|
|
335
|
+
|
|
336
|
+
Let me know if you'd like me to make any adjustments before you deploy!"
|
|
@@ -0,0 +1,336 @@
|
|
|
1
|
+
# Task: Enable AWS Application Signals for Node.js on AWS Lambda
|
|
2
|
+
|
|
3
|
+
Your task is to modify Infrastructure as Code (IaC) files to enable AWS Application Signals for Node.js Lambda functions. You will:
|
|
4
|
+
|
|
5
|
+
1. Add IAM permissions for Application Signals
|
|
6
|
+
2. Configure X-Ray tracing
|
|
7
|
+
3. Add the ADOT Lambda layer
|
|
8
|
+
4. Set the required environment variables.
|
|
9
|
+
|
|
10
|
+
If you cannot determine a value (such as AWS Region): Ask the user for clarification before proceeding. Do not guess or make up values.
|
|
11
|
+
|
|
12
|
+
## Region-Specific Layer ARNs
|
|
13
|
+
|
|
14
|
+
Select the correct ARN for your region:
|
|
15
|
+
|
|
16
|
+
```json
|
|
17
|
+
{
|
|
18
|
+
"af-south-1": "arn:aws:lambda:af-south-1:904233096616:layer:AWSOpenTelemetryDistroJs:10",
|
|
19
|
+
"ap-east-1": "arn:aws:lambda:ap-east-1:888577020596:layer:AWSOpenTelemetryDistroJs:10",
|
|
20
|
+
"ap-northeast-1": "arn:aws:lambda:ap-northeast-1:615299751070:layer:AWSOpenTelemetryDistroJs:10",
|
|
21
|
+
"ap-northeast-2": "arn:aws:lambda:ap-northeast-2:615299751070:layer:AWSOpenTelemetryDistroJs:10",
|
|
22
|
+
"ap-northeast-3": "arn:aws:lambda:ap-northeast-3:615299751070:layer:AWSOpenTelemetryDistroJs:10",
|
|
23
|
+
"ap-south-1": "arn:aws:lambda:ap-south-1:615299751070:layer:AWSOpenTelemetryDistroJs:10",
|
|
24
|
+
"ap-south-2": "arn:aws:lambda:ap-south-2:796973505492:layer:AWSOpenTelemetryDistroJs:10",
|
|
25
|
+
"ap-southeast-1": "arn:aws:lambda:ap-southeast-1:615299751070:layer:AWSOpenTelemetryDistroJs:10",
|
|
26
|
+
"ap-southeast-2": "arn:aws:lambda:ap-southeast-2:615299751070:layer:AWSOpenTelemetryDistroJs:10",
|
|
27
|
+
"ap-southeast-3": "arn:aws:lambda:ap-southeast-3:039612877180:layer:AWSOpenTelemetryDistroJs:10",
|
|
28
|
+
"ap-southeast-4": "arn:aws:lambda:ap-southeast-4:713881805771:layer:AWSOpenTelemetryDistroJs:10",
|
|
29
|
+
"ap-southeast-5": "arn:aws:lambda:ap-southeast-5:152034782359:layer:AWSOpenTelemetryDistroJs:3",
|
|
30
|
+
"ap-southeast-7": "arn:aws:lambda:ap-southeast-7:980416031188:layer:AWSOpenTelemetryDistroJs:3",
|
|
31
|
+
"ca-central-1": "arn:aws:lambda:ca-central-1:615299751070:layer:AWSOpenTelemetryDistroJs:10",
|
|
32
|
+
"ca-west-1": "arn:aws:lambda:ca-west-1:595944127152:layer:AWSOpenTelemetryDistroJs:3",
|
|
33
|
+
"cn-north-1": "arn:aws-cn:lambda:cn-north-1:440179912924:layer:AWSOpenTelemetryDistroJs:3",
|
|
34
|
+
"cn-northwest-1": "arn:aws-cn:lambda:cn-northwest-1:440180067931:layer:AWSOpenTelemetryDistroJs:3",
|
|
35
|
+
"eu-central-1": "arn:aws:lambda:eu-central-1:615299751070:layer:AWSOpenTelemetryDistroJs:10",
|
|
36
|
+
"eu-central-2": "arn:aws:lambda:eu-central-2:156041407956:layer:AWSOpenTelemetryDistroJs:10",
|
|
37
|
+
"eu-north-1": "arn:aws:lambda:eu-north-1:615299751070:layer:AWSOpenTelemetryDistroJs:10",
|
|
38
|
+
"eu-south-1": "arn:aws:lambda:eu-south-1:257394471194:layer:AWSOpenTelemetryDistroJs:10",
|
|
39
|
+
"eu-south-2": "arn:aws:lambda:eu-south-2:490004653786:layer:AWSOpenTelemetryDistroJs:10",
|
|
40
|
+
"eu-west-1": "arn:aws:lambda:eu-west-1:615299751070:layer:AWSOpenTelemetryDistroJs:10",
|
|
41
|
+
"eu-west-2": "arn:aws:lambda:eu-west-2:615299751070:layer:AWSOpenTelemetryDistroJs:10",
|
|
42
|
+
"eu-west-3": "arn:aws:lambda:eu-west-3:615299751070:layer:AWSOpenTelemetryDistroJs:10",
|
|
43
|
+
"il-central-1": "arn:aws:lambda:il-central-1:746669239226:layer:AWSOpenTelemetryDistroJs:10",
|
|
44
|
+
"me-central-1": "arn:aws:lambda:me-central-1:739275441131:layer:AWSOpenTelemetryDistroJs:10",
|
|
45
|
+
"me-south-1": "arn:aws:lambda:me-south-1:980921751758:layer:AWSOpenTelemetryDistroJs:10",
|
|
46
|
+
"mx-central-1": "arn:aws:lambda:mx-central-1:610118373846:layer:AWSOpenTelemetryDistroJs:3",
|
|
47
|
+
"sa-east-1": "arn:aws:lambda:sa-east-1:615299751070:layer:AWSOpenTelemetryDistroJs:10",
|
|
48
|
+
"us-east-1": "arn:aws:lambda:us-east-1:615299751070:layer:AWSOpenTelemetryDistroJs:10",
|
|
49
|
+
"us-east-2": "arn:aws:lambda:us-east-2:615299751070:layer:AWSOpenTelemetryDistroJs:10",
|
|
50
|
+
"us-west-1": "arn:aws:lambda:us-west-1:615299751070:layer:AWSOpenTelemetryDistroJs:10",
|
|
51
|
+
"us-west-2": "arn:aws:lambda:us-west-2:615299751070:layer:AWSOpenTelemetryDistroJs:10",
|
|
52
|
+
"us-gov-east-1": "arn:aws-us-gov:lambda:us-gov-east-1:399711857375:layer:AWSOpenTelemetryDistroJs:1",
|
|
53
|
+
"us-gov-west-1": "arn:aws-us-gov:lambda:us-gov-west-1:399727141365:layer:AWSOpenTelemetryDistroJs:1"
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Instructions
|
|
58
|
+
|
|
59
|
+
### Step 1: Add IAM Permissions
|
|
60
|
+
|
|
61
|
+
Add the AWS managed policy `CloudWatchLambdaApplicationSignalsExecutionRolePolicy` to the Lambda function's execution role.
|
|
62
|
+
|
|
63
|
+
**CDK:**
|
|
64
|
+
```typescript
|
|
65
|
+
const role = new iam.Role(this, 'LambdaRole', {
|
|
66
|
+
assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'),
|
|
67
|
+
managedPolicies: [
|
|
68
|
+
iam.ManagedPolicy.fromAwsManagedPolicyName('service-role/AWSLambdaBasicExecutionRole'),
|
|
69
|
+
iam.ManagedPolicy.fromAwsManagedPolicyName('CloudWatchLambdaApplicationSignalsExecutionRolePolicy'),
|
|
70
|
+
// ... keep existing policies
|
|
71
|
+
],
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
const myFunction = new lambda.Function(this, 'MyFunction', {
|
|
75
|
+
// ... existing configuration
|
|
76
|
+
role: role,
|
|
77
|
+
});
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
**Terraform:**
|
|
81
|
+
```hcl
|
|
82
|
+
resource "aws_iam_role" "lambda_role" {
|
|
83
|
+
name = "lambda-role"
|
|
84
|
+
assume_role_policy = jsonencode({
|
|
85
|
+
Version = "2012-10-17"
|
|
86
|
+
Statement = [
|
|
87
|
+
{
|
|
88
|
+
Action = "sts:AssumeRole"
|
|
89
|
+
Effect = "Allow"
|
|
90
|
+
Principal = {
|
|
91
|
+
Service = "lambda.amazonaws.com"
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
]
|
|
95
|
+
})
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
resource "aws_iam_role_policy_attachment" "lambda_basic" {
|
|
99
|
+
role = aws_iam_role.lambda_role.name
|
|
100
|
+
policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
resource "aws_iam_role_policy_attachment" "application_signals" {
|
|
104
|
+
role = aws_iam_role.lambda_role.name
|
|
105
|
+
policy_arn = "arn:aws:iam::aws:policy/CloudWatchLambdaApplicationSignalsExecutionRolePolicy"
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
resource "aws_lambda_function" "my_function" {
|
|
109
|
+
# ... existing configuration
|
|
110
|
+
role = aws_iam_role.lambda_role.arn
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
**CloudFormation:**
|
|
115
|
+
```yaml
|
|
116
|
+
LambdaRole:
|
|
117
|
+
Type: AWS::IAM::Role
|
|
118
|
+
Properties:
|
|
119
|
+
AssumeRolePolicyDocument:
|
|
120
|
+
Version: '2012-10-17'
|
|
121
|
+
Statement:
|
|
122
|
+
- Effect: Allow
|
|
123
|
+
Principal:
|
|
124
|
+
Service: lambda.amazonaws.com
|
|
125
|
+
Action: sts:AssumeRole
|
|
126
|
+
ManagedPolicyArns:
|
|
127
|
+
- arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
|
|
128
|
+
- arn:aws:iam::aws:policy/CloudWatchLambdaApplicationSignalsExecutionRolePolicy
|
|
129
|
+
# ... keep existing policies
|
|
130
|
+
|
|
131
|
+
MyFunction:
|
|
132
|
+
Type: AWS::Lambda::Function
|
|
133
|
+
Properties:
|
|
134
|
+
# ... existing configuration
|
|
135
|
+
Role: !GetAtt LambdaRole.Arn
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### Step 2: Enable X-Ray Active Tracing
|
|
139
|
+
|
|
140
|
+
**CDK:**
|
|
141
|
+
```typescript
|
|
142
|
+
const myFunction = new lambda.Function(this, 'MyFunction', {
|
|
143
|
+
// ... existing configuration
|
|
144
|
+
tracing: lambda.Tracing.ACTIVE,
|
|
145
|
+
});
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
**Terraform:**
|
|
149
|
+
```hcl
|
|
150
|
+
resource "aws_lambda_function" "my_function" {
|
|
151
|
+
# ... existing configuration
|
|
152
|
+
tracing_config {
|
|
153
|
+
mode = "Active"
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
**CloudFormation:**
|
|
159
|
+
```yaml
|
|
160
|
+
MyFunction:
|
|
161
|
+
Type: AWS::Lambda::Function
|
|
162
|
+
Properties:
|
|
163
|
+
# ... existing configuration
|
|
164
|
+
TracingConfig:
|
|
165
|
+
Mode: Active
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### Step 3: Add ADOT Node.js Lambda Layer
|
|
169
|
+
|
|
170
|
+
Use the layer name `AWSOpenTelemetryDistroJs` with automatic region detection. The code below includes a complete mapping that will automatically select the correct layer ARN based on your deployment region.
|
|
171
|
+
|
|
172
|
+
**CDK:**
|
|
173
|
+
```typescript
|
|
174
|
+
const layerArns: { [region: string]: string } = {
|
|
175
|
+
'af-south-1': 'arn:aws:lambda:af-south-1:904233096616:layer:AWSOpenTelemetryDistroJs:10',
|
|
176
|
+
'ap-east-1': 'arn:aws:lambda:ap-east-1:888577020596:layer:AWSOpenTelemetryDistroJs:10',
|
|
177
|
+
// ... (see Region-Specific Layer ARNs section above for complete mapping)
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
const myFunction = new lambda.Function(this, 'MyFunction', {
|
|
181
|
+
// ... existing configuration
|
|
182
|
+
layers: [
|
|
183
|
+
// ... keep existing layers
|
|
184
|
+
lambda.LayerVersion.fromLayerVersionArn(
|
|
185
|
+
this,
|
|
186
|
+
'AdotLayer',
|
|
187
|
+
layerArns[this.region]
|
|
188
|
+
),
|
|
189
|
+
],
|
|
190
|
+
});
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
**Terraform:**
|
|
194
|
+
```hcl
|
|
195
|
+
locals {
|
|
196
|
+
layer_arns = {
|
|
197
|
+
"af-south-1" = "arn:aws:lambda:af-south-1:904233096616:layer:AWSOpenTelemetryDistroJs:10"
|
|
198
|
+
"ap-east-1" = "arn:aws:lambda:ap-east-1:888577020596:layer:AWSOpenTelemetryDistroJs:10"
|
|
199
|
+
# ... (see Region-Specific Layer ARNs section above for complete mapping)
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
data "aws_region" "current" {}
|
|
204
|
+
|
|
205
|
+
resource "aws_lambda_function" "my_function" {
|
|
206
|
+
# ... existing configuration
|
|
207
|
+
layers = [
|
|
208
|
+
# ... keep existing layers
|
|
209
|
+
local.layer_arns[data.aws_region.current.name]
|
|
210
|
+
]
|
|
211
|
+
}
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
**CloudFormation:**
|
|
215
|
+
```yaml
|
|
216
|
+
Mappings:
|
|
217
|
+
LayerArns:
|
|
218
|
+
af-south-1:
|
|
219
|
+
arn: arn:aws:lambda:af-south-1:904233096616:layer:AWSOpenTelemetryDistroJs:10
|
|
220
|
+
ap-east-1:
|
|
221
|
+
arn: arn:aws:lambda:ap-east-1:888577020596:layer:AWSOpenTelemetryDistroJs:10
|
|
222
|
+
# ... (see Region-Specific Layer ARNs section above for complete mapping)
|
|
223
|
+
|
|
224
|
+
Resources:
|
|
225
|
+
MyFunction:
|
|
226
|
+
Type: AWS::Lambda::Function
|
|
227
|
+
Properties:
|
|
228
|
+
# ... existing configuration
|
|
229
|
+
Layers:
|
|
230
|
+
# ... keep existing layers
|
|
231
|
+
- !FindInMap [LayerArns, !Ref 'AWS::Region', arn]
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
### Step 4: Set Environment Variable
|
|
235
|
+
|
|
236
|
+
Add the `AWS_LAMBDA_EXEC_WRAPPER` environment variable with value `/opt/otel-instrument`.
|
|
237
|
+
|
|
238
|
+
**CDK:**
|
|
239
|
+
```typescript
|
|
240
|
+
const myFunction = new lambda.Function(this, 'MyFunction', {
|
|
241
|
+
// ... existing configuration
|
|
242
|
+
environment: {
|
|
243
|
+
// ... keep existing environment variables
|
|
244
|
+
AWS_LAMBDA_EXEC_WRAPPER: '/opt/otel-instrument',
|
|
245
|
+
},
|
|
246
|
+
});
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
**Terraform:**
|
|
250
|
+
```hcl
|
|
251
|
+
resource "aws_lambda_function" "my_function" {
|
|
252
|
+
# ... existing configuration
|
|
253
|
+
environment {
|
|
254
|
+
variables = {
|
|
255
|
+
# ... keep existing environment variables
|
|
256
|
+
AWS_LAMBDA_EXEC_WRAPPER = "/opt/otel-instrument"
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
**CloudFormation:**
|
|
263
|
+
```yaml
|
|
264
|
+
MyFunction:
|
|
265
|
+
Type: AWS::Lambda::Function
|
|
266
|
+
Properties:
|
|
267
|
+
# ... existing configuration
|
|
268
|
+
Environment:
|
|
269
|
+
Variables:
|
|
270
|
+
# ... keep existing environment variables
|
|
271
|
+
AWS_LAMBDA_EXEC_WRAPPER: /opt/otel-instrument
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
## Complete Example
|
|
275
|
+
|
|
276
|
+
**CDK:**
|
|
277
|
+
```typescript
|
|
278
|
+
const layerArns: { [region: string]: string } = {
|
|
279
|
+
'af-south-1': 'arn:aws:lambda:af-south-1:904233096616:layer:AWSOpenTelemetryDistroJs:10',
|
|
280
|
+
'ap-east-1': 'arn:aws:lambda:ap-east-1:888577020596:layer:AWSOpenTelemetryDistroJs:10',
|
|
281
|
+
// ... (see Region-Specific Layer ARNs section above for complete mapping)
|
|
282
|
+
};
|
|
283
|
+
|
|
284
|
+
const nodeFunction = new lambda.Function(this, 'NodeFunction', {
|
|
285
|
+
runtime: lambda.Runtime.NODEJS_18_X,
|
|
286
|
+
handler: 'index.handler',
|
|
287
|
+
code: lambda.Code.fromAsset('src'),
|
|
288
|
+
tracing: lambda.Tracing.ACTIVE,
|
|
289
|
+
layers: [
|
|
290
|
+
lambda.LayerVersion.fromLayerVersionArn(
|
|
291
|
+
this,
|
|
292
|
+
'AdotLayer',
|
|
293
|
+
layerArns[this.region]
|
|
294
|
+
),
|
|
295
|
+
],
|
|
296
|
+
environment: {
|
|
297
|
+
AWS_LAMBDA_EXEC_WRAPPER: '/opt/otel-instrument',
|
|
298
|
+
},
|
|
299
|
+
});
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
## Completion
|
|
303
|
+
|
|
304
|
+
**Tell the user:**
|
|
305
|
+
|
|
306
|
+
"I've completed the Application Signals enablement for your Node.js Lambda function. Here's what I modified:
|
|
307
|
+
|
|
308
|
+
**Configuration Changes:**
|
|
309
|
+
- IAM Permissions: Added CloudWatchLambdaApplicationSignalsExecutionRolePolicy
|
|
310
|
+
- X-Ray Tracing: Enabled active tracing
|
|
311
|
+
- ADOT Layer: Added AWSOpenTelemetryDistroJs layer
|
|
312
|
+
- Environment Variable: Set AWS_LAMBDA_EXEC_WRAPPER=/opt/otel-instrument
|
|
313
|
+
|
|
314
|
+
**Next Steps:**
|
|
315
|
+
1. Ensure that [Application Signals is enabled in AWS account](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch-Application-Signals-Enable.html).
|
|
316
|
+
2. Review the changes I made using `git diff`
|
|
317
|
+
3. Deploy your infrastructure:
|
|
318
|
+
- For CDK: `cdk deploy`
|
|
319
|
+
- For Terraform: `terraform apply`
|
|
320
|
+
- For CloudFormation: Deploy your stack
|
|
321
|
+
4. After deployment, invoke your Lambda function to generate telemetry data
|
|
322
|
+
|
|
323
|
+
**Verification:**
|
|
324
|
+
Once deployed, you can verify Application Signals is working by:
|
|
325
|
+
- Opening the AWS CloudWatch Console
|
|
326
|
+
- Navigating to Application Signals → Services
|
|
327
|
+
- Looking for your Lambda function service
|
|
328
|
+
- Checking that traces and metrics are being collected
|
|
329
|
+
|
|
330
|
+
**Monitor Application Health:**
|
|
331
|
+
After enablement, you can monitor your Lambda function's operational health using Application Signals dashboards. For more information, see [Monitor the operational health of your applications with Application Signals](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Services.html).
|
|
332
|
+
|
|
333
|
+
**Troubleshooting**
|
|
334
|
+
If you encounter any other issues, refer to the [CloudWatch APM troubleshooting guide](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch-Application-Signals-Enable-Troubleshoot.html).
|
|
335
|
+
|
|
336
|
+
Let me know if you'd like me to make any adjustments before you deploy!"
|