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.
Files changed (36) hide show
  1. awslabs/__init__.py +17 -0
  2. awslabs/cloudwatch_applicationsignals_mcp_server/__init__.py +17 -0
  3. awslabs/cloudwatch_applicationsignals_mcp_server/audit_presentation_utils.py +288 -0
  4. awslabs/cloudwatch_applicationsignals_mcp_server/audit_utils.py +912 -0
  5. awslabs/cloudwatch_applicationsignals_mcp_server/aws_clients.py +120 -0
  6. awslabs/cloudwatch_applicationsignals_mcp_server/canary_utils.py +910 -0
  7. awslabs/cloudwatch_applicationsignals_mcp_server/enablement_guides/templates/ec2/ec2-dotnet-enablement.md +435 -0
  8. awslabs/cloudwatch_applicationsignals_mcp_server/enablement_guides/templates/ec2/ec2-java-enablement.md +321 -0
  9. awslabs/cloudwatch_applicationsignals_mcp_server/enablement_guides/templates/ec2/ec2-nodejs-enablement.md +420 -0
  10. awslabs/cloudwatch_applicationsignals_mcp_server/enablement_guides/templates/ec2/ec2-python-enablement.md +598 -0
  11. awslabs/cloudwatch_applicationsignals_mcp_server/enablement_guides/templates/ecs/ecs-dotnet-enablement.md +264 -0
  12. awslabs/cloudwatch_applicationsignals_mcp_server/enablement_guides/templates/ecs/ecs-java-enablement.md +193 -0
  13. awslabs/cloudwatch_applicationsignals_mcp_server/enablement_guides/templates/ecs/ecs-nodejs-enablement.md +198 -0
  14. awslabs/cloudwatch_applicationsignals_mcp_server/enablement_guides/templates/ecs/ecs-python-enablement.md +236 -0
  15. awslabs/cloudwatch_applicationsignals_mcp_server/enablement_guides/templates/eks/eks-dotnet-enablement.md +166 -0
  16. awslabs/cloudwatch_applicationsignals_mcp_server/enablement_guides/templates/eks/eks-java-enablement.md +166 -0
  17. awslabs/cloudwatch_applicationsignals_mcp_server/enablement_guides/templates/eks/eks-nodejs-enablement.md +166 -0
  18. awslabs/cloudwatch_applicationsignals_mcp_server/enablement_guides/templates/eks/eks-python-enablement.md +169 -0
  19. awslabs/cloudwatch_applicationsignals_mcp_server/enablement_guides/templates/lambda/lambda-dotnet-enablement.md +336 -0
  20. awslabs/cloudwatch_applicationsignals_mcp_server/enablement_guides/templates/lambda/lambda-java-enablement.md +336 -0
  21. awslabs/cloudwatch_applicationsignals_mcp_server/enablement_guides/templates/lambda/lambda-nodejs-enablement.md +336 -0
  22. awslabs/cloudwatch_applicationsignals_mcp_server/enablement_guides/templates/lambda/lambda-python-enablement.md +336 -0
  23. awslabs/cloudwatch_applicationsignals_mcp_server/enablement_tools.py +147 -0
  24. awslabs/cloudwatch_applicationsignals_mcp_server/server.py +1505 -0
  25. awslabs/cloudwatch_applicationsignals_mcp_server/service_audit_utils.py +231 -0
  26. awslabs/cloudwatch_applicationsignals_mcp_server/service_tools.py +659 -0
  27. awslabs/cloudwatch_applicationsignals_mcp_server/sli_report_client.py +333 -0
  28. awslabs/cloudwatch_applicationsignals_mcp_server/slo_tools.py +386 -0
  29. awslabs/cloudwatch_applicationsignals_mcp_server/trace_tools.py +784 -0
  30. awslabs/cloudwatch_applicationsignals_mcp_server/utils.py +172 -0
  31. awslabs_cloudwatch_applicationsignals_mcp_server-0.1.21.dist-info/METADATA +808 -0
  32. awslabs_cloudwatch_applicationsignals_mcp_server-0.1.21.dist-info/RECORD +36 -0
  33. awslabs_cloudwatch_applicationsignals_mcp_server-0.1.21.dist-info/WHEEL +4 -0
  34. awslabs_cloudwatch_applicationsignals_mcp_server-0.1.21.dist-info/entry_points.txt +2 -0
  35. awslabs_cloudwatch_applicationsignals_mcp_server-0.1.21.dist-info/licenses/LICENSE +174 -0
  36. awslabs_cloudwatch_applicationsignals_mcp_server-0.1.21.dist-info/licenses/NOTICE +2 -0
@@ -0,0 +1,264 @@
1
+ # Task: Enable AWS Application Signals for .NET on ECS
2
+
3
+ ## Overview
4
+ This guide provides complete steps to enable AWS Application Signals for ECS Fargate services, distributed tracing, performance monitoring, and service mapping.
5
+
6
+ ## Prerequisites
7
+ - Services running on ECS both the ec2 and Fargate launch types.
8
+ - Applications using .NET language
9
+
10
+ ## Implementation Steps
11
+
12
+ **Constraints:**
13
+ You must strictly follow the steps in the order below, do not skip or combine steps.
14
+
15
+ ### Step 1: Setup CloudWatch Agent Task
16
+ When running in ECS, the CloudWatch Agent is deployed as a sidecar container next to the application container.
17
+ Proper permissions, a CWAgentConfig configuration file, and the target log group must be set up to enable logging and metrics collection.
18
+
19
+ #### 1.1 Add CloudWatch Agent Permissions to ECS Task Role
20
+
21
+ Update ECS task role to add CloudWatchAgentServerPolicy:
22
+
23
+ ```typescript
24
+ // Update existing taskRole or create new one
25
+ const taskRole = new iam.Role(this, 'EcsTaskRole', {
26
+ assumedBy: new iam.ServicePrincipal('ecs-tasks.amazonaws.com'),
27
+ managedPolicies: [
28
+ iam.ManagedPolicy.fromAwsManagedPolicyName('AWSXRayDaemonWriteAccess'),
29
+ iam.ManagedPolicy.fromAwsManagedPolicyName('CloudWatchAgentServerPolicy'),
30
+ ],
31
+ inlinePolicies: {
32
+ // Your existing inline policies...
33
+ },
34
+ });
35
+ ```
36
+
37
+ #### 1.2 Create CloudWatch Agent Log Group
38
+ ```typescript
39
+ const cwAgentLogGroup = new logs.LogGroup(this, 'CwAgentLogGroup', {
40
+ logGroupName: '/ecs/ecs-cwagent',
41
+ removalPolicy: cdk.RemovalPolicy.DESTROY,
42
+ retention: logs.RetentionDays.ONE_WEEK,
43
+ });
44
+ ```
45
+
46
+ #### 1.3 Add CloudWatch Agent Container to Each Task Definition
47
+ ```typescript
48
+ // Add CloudWatch Agent sidecar to each task definition
49
+ const cwAgentContainer = taskDefinition.addContainer('ecs-cwagent-{SERVICE_NAME}', {
50
+ image: ecs.ContainerImage.fromRegistry('public.ecr.aws/cloudwatch-agent/cloudwatch-agent:latest'),
51
+ essential: false,
52
+ memoryReservationMiB: 128,
53
+ cpu: 64,
54
+ environment: {
55
+ CW_CONFIG_CONTENT: JSON.stringify({
56
+ "traces": {
57
+ "traces_collected": {
58
+ "application_signals": {}
59
+ }
60
+ },
61
+ "logs": {
62
+ "metrics_collected": {
63
+ "application_signals": {}
64
+ }
65
+ }
66
+ }),
67
+ },
68
+ logging: ecs.LogDrivers.awsLogs({
69
+ streamPrefix: 'ecs',
70
+ logGroup: cwAgentLogGroup,
71
+ }),
72
+ });
73
+ ```
74
+
75
+ ### Step 2: Add AWS Distro for OpenTelemetry Zero-Code Instrumentation to Main Service
76
+
77
+ #### 2.1 Add Bind Mount Volumes to Task Definition
78
+ ```typescript
79
+ const taskDefinition = new ecs.FargateTaskDefinition(this, '{SERVICE_NAME}TaskDefinition', {
80
+ // Existing configuration...
81
+ volumes: [
82
+ {
83
+ name: "opentelemetry-auto-instrumentation-dotnet"
84
+ }
85
+ ],
86
+ });
87
+ ```
88
+
89
+ #### 2.2 Add ADOT Auto-instrumentation Init Container
90
+
91
+ ##### For Linux Containers:
92
+ ```typescript
93
+ const initContainer = taskDefinition.addContainer('init', {
94
+ image: ecs.ContainerImage.fromRegistry('public.ecr.aws/aws-observability/adot-autoinstrumentation-dotnet:v1.9.2'),
95
+ essential: false,
96
+ memoryReservationMiB: 64,
97
+ cpu: 32,
98
+ command: ['cp', '-a', '/autoinstrumentation/.', '/otel-auto-instrumentation-dotnet'],
99
+ logging: ecs.LogDrivers.awsLogs({
100
+ streamPrefix: 'init-{SERVICE_NAME}',
101
+ logGroup: serviceLogGroup,
102
+ }),
103
+ });
104
+
105
+ // Add mount point to init container
106
+ initContainer.addMountPoints({
107
+ sourceVolume: 'opentelemetry-auto-instrumentation-dotnet',
108
+ containerPath: '/otel-auto-instrumentation-dotnet',
109
+ readOnly: false,
110
+ });
111
+ ```
112
+
113
+ ##### For Windows Server Containers:
114
+ ```typescript
115
+ const initContainer = taskDefinition.addContainer('init', {
116
+ image: ecs.ContainerImage.fromRegistry('public.ecr.aws/aws-observability/adot-autoinstrumentation-dotnet:v1.9.2'),
117
+ essential: false,
118
+ memoryReservationMiB: 64,
119
+ cpu: 32,
120
+ command: ['CMD', '/c', 'xcopy', '/e', 'C:\\autoinstrumentation\\*', 'C:\\otel-auto-instrumentation', '&&', 'icacls', 'C:\\otel-auto-instrumentation', '/grant', '*S-1-1-0:R', '/T'],
121
+ logging: ecs.LogDrivers.awsLogs({
122
+ streamPrefix: 'init-{SERVICE_NAME}',
123
+ logGroup: serviceLogGroup,
124
+ }),
125
+ });
126
+
127
+ // Add mount point to init container
128
+ initContainer.addMountPoints({
129
+ sourceVolume: 'opentelemetry-auto-instrumentation-dotnet',
130
+ containerPath: 'C:\\otel-auto-instrumentation',
131
+ readOnly: false,
132
+ });
133
+ ```
134
+
135
+ #### 2.3 Configure Main Application Container OpenTelemetry Environment Variables
136
+
137
+ ##### For Linux Containers:
138
+ ```typescript
139
+ const mainContainer = taskDefinition.addContainer('{SERVICE_NAME}-container', {
140
+ // Existing configuration...
141
+ environment: {
142
+ // Existing environment variables...
143
+
144
+ // ADOT Configuration for Application Signals - .NET Linux
145
+ OTEL_RESOURCE_ATTRIBUTES: 'service.name={SERVICE_NAME}', // SERVICE_NAME is defined by user. Check for service.serviceName for example
146
+ OTEL_METRICS_EXPORTER: 'none',
147
+ OTEL_LOGS_EXPORTER: 'none',
148
+ DOTNET_STARTUP_HOOKS: '/otel-auto-instrumentation-dotnet/net/OpenTelemetry.AutoInstrumentation.StartupHook.dll',
149
+ DOTNET_ADDITIONAL_DEPS: '/otel-auto-instrumentation-dotnet/AdditionalDeps',
150
+ DOTNET_SHARED_STORE: '/otel-auto-instrumentation-dotnet/store',
151
+ OTEL_DOTNET_AUTO_HOME: '/otel-auto-instrumentation-dotnet',
152
+ OTEL_TRACES_EXPORTER: 'otlp',
153
+ OTEL_EXPORTER_OTLP_PROTOCOL: 'http/protobuf',
154
+ OTEL_EXPORTER_OTLP_TRACES_ENDPOINT: 'http://localhost:4316/v1/traces',
155
+ OTEL_AWS_APPLICATION_SIGNALS_EXPORTER_ENDPOINT: 'http://localhost:4316/v1/metrics',
156
+ OTEL_AWS_APPLICATION_SIGNALS_ENABLED: 'true',
157
+ CORECLR_ENABLE_PROFILING: '1',
158
+ CORECLR_PROFILER: '{918728DD-259F-4A6A-AC2B-B85E1B658318}',
159
+ CORECLR_PROFILER_PATH: '/otel-auto-instrumentation-dotnet/linux-x64/OpenTelemetry.AutoInstrumentation.Native.so',
160
+ OTEL_DOTNET_AUTO_PLUGINS: 'AWS.Distro.OpenTelemetry.AutoInstrumentation.Plugin, AWS.Distro.OpenTelemetry.AutoInstrumentation',
161
+ },
162
+ });
163
+ ```
164
+
165
+ ##### For Windows Server Containers:
166
+ ```typescript
167
+ const mainContainer = taskDefinition.addContainer('{SERVICE_NAME}-container', {
168
+ // Existing configuration...
169
+ environment: {
170
+ // Existing environment variables...
171
+
172
+ // ADOT Configuration for Application Signals - .NET Windows
173
+ OTEL_RESOURCE_ATTRIBUTES: 'service.name={SERVICE_NAME}', // SERVICE_NAME is defined by user. Check for service.serviceName for example
174
+ OTEL_METRICS_EXPORTER: 'none',
175
+ OTEL_LOGS_EXPORTER: 'none',
176
+ DOTNET_STARTUP_HOOKS: 'C:\\otel-auto-instrumentation\\net\\OpenTelemetry.AutoInstrumentation.StartupHook.dll',
177
+ DOTNET_ADDITIONAL_DEPS: 'C:\\otel-auto-instrumentation\\AdditionalDeps',
178
+ DOTNET_SHARED_STORE: 'C:\\otel-auto-instrumentation\\store',
179
+ OTEL_DOTNET_AUTO_HOME: 'C:\\otel-auto-instrumentation',
180
+ OTEL_TRACES_EXPORTER: 'otlp',
181
+ OTEL_EXPORTER_OTLP_PROTOCOL: 'http/protobuf',
182
+ OTEL_EXPORTER_OTLP_TRACES_ENDPOINT: 'http://localhost:4316/v1/traces',
183
+ OTEL_AWS_APPLICATION_SIGNALS_EXPORTER_ENDPOINT: 'http://localhost:4316/v1/metrics',
184
+ OTEL_AWS_APPLICATION_SIGNALS_ENABLED: 'true',
185
+ CORECLR_ENABLE_PROFILING: '1',
186
+ CORECLR_PROFILER: '{918728DD-259F-4A6A-AC2B-B85E1B658318}',
187
+ CORECLR_PROFILER_PATH: 'C:\\otel-auto-instrumentation\\win-x64\\OpenTelemetry.AutoInstrumentation.Native.dll',
188
+ OTEL_DOTNET_AUTO_PLUGINS: 'AWS.Distro.OpenTelemetry.AutoInstrumentation.Plugin, AWS.Distro.OpenTelemetry.AutoInstrumentation',
189
+ },
190
+ });
191
+ ```
192
+
193
+ #### 2.4 Add Mount Point to Main Container
194
+
195
+ ##### For Linux Containers:
196
+ ```typescript
197
+ // Add mount point to main application container
198
+ mainContainer.addMountPoints({
199
+ sourceVolume: 'opentelemetry-auto-instrumentation-dotnet',
200
+ containerPath: '/otel-auto-instrumentation-dotnet',
201
+ readOnly: false,
202
+ });
203
+ ```
204
+
205
+ ##### For Windows Server Containers:
206
+ ```typescript
207
+ // Add mount point to main application container
208
+ mainContainer.addMountPoints({
209
+ sourceVolume: 'opentelemetry-auto-instrumentation-dotnet',
210
+ containerPath: 'C:\\otel-auto-instrumentation',
211
+ readOnly: false,
212
+ });
213
+ ```
214
+
215
+ #### 2.5 Configure Container Dependencies
216
+ ```typescript
217
+ // Ensure containers start in correct order
218
+ mainContainer.addContainerDependencies({
219
+ container: initContainer,
220
+ condition: ecs.ContainerDependencyCondition.SUCCESS,
221
+ });
222
+
223
+ mainContainer.addContainerDependencies({
224
+ container: cwAgentContainer,
225
+ condition: ecs.ContainerDependencyCondition.START,
226
+ });
227
+ ```
228
+
229
+ ## Completion
230
+
231
+ **Tell the user:**
232
+
233
+ "I've completed the Application Signals enablement for your .NET application. Here's what I modified:
234
+
235
+ **Files Changed:**
236
+ - IAM role: Added CloudWatchAgentServerPolicy
237
+ - ECS container: Installed and configured CloudWatch Agent as sidecar
238
+ - ADOT SDK container: Mounted ADOT SDK dependencies into Application container
239
+ - Application container: Enabled zero-code instrumentation for .NET Application
240
+
241
+ **Next Steps:**
242
+ 1. Ensure that [Application Signals is enabled in AWS account](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch-Application-Signals-Enable.html).
243
+ This is a one-time setup; if already enabled, you can skip this step.
244
+ 2. Review the changes I made using `git diff`
245
+ 3. Deploy your infrastructure:
246
+ - For CDK: `cdk deploy`
247
+ - For Terraform: `terraform apply`
248
+ - For CloudFormation: Deploy your stack
249
+ 4. After deployment, wait 5-10 minutes for telemetry data to start flowing
250
+
251
+ **Verification:**
252
+ Once deployed, you can verify Application Signals is working by:
253
+ - Opening the AWS CloudWatch Console
254
+ - Navigating to Application Signals → Services
255
+ - Looking for your service (named: {{SERVICE_NAME}})
256
+ - Checking that traces and metrics are being collected
257
+
258
+ **Monitor Application Health:**
259
+ After enablement, you can monitor your application'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).
260
+
261
+ **Troubleshooting**
262
+ 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).
263
+
264
+ Let me know if you'd like me to make any adjustments before you deploy!"
@@ -0,0 +1,193 @@
1
+ # Task: Enable AWS Application Signals for Java on ECS
2
+
3
+ ## Overview
4
+ This guide provides complete steps to enable AWS Application Signals for ECS Fargate services, distributed tracing, performance monitoring, and service mapping.
5
+
6
+ ## Prerequisites
7
+ - Services running on ECS both the ec2 and Fargate launch types.
8
+ - Applications using Java language
9
+
10
+ ## Implementation Steps
11
+
12
+ **Constraints:**
13
+ You must strictly follow the steps in the order below, do not skip or combine steps.
14
+
15
+ ### Step 1: Setup CloudWatch Agent Task
16
+ When running in ECS, the CloudWatch Agent is deployed as a sidecar container next to the application container.
17
+ Proper permissions, a CWAgentConfig configuration file, and the target log group must be set up to enable logging and metrics collection.
18
+
19
+ #### 1.1 Add CloudWatch Agent Permissions to ECS Task Role
20
+
21
+ Update ECS task role to add CloudWatchAgentServerPolicy:
22
+
23
+ ```typescript
24
+ // Update existing taskRole or create new one
25
+ const taskRole = new iam.Role(this, 'EcsTaskRole', {
26
+ assumedBy: new iam.ServicePrincipal('ecs-tasks.amazonaws.com'),
27
+ managedPolicies: [
28
+ iam.ManagedPolicy.fromAwsManagedPolicyName('AWSXRayDaemonWriteAccess'),
29
+ iam.ManagedPolicy.fromAwsManagedPolicyName('CloudWatchAgentServerPolicy'),
30
+ ],
31
+ inlinePolicies: {
32
+ // Your existing inline policies...
33
+ },
34
+ });
35
+ ```
36
+
37
+ #### 1.2 Create CloudWatch Agent Log Group
38
+ ```typescript
39
+ const cwAgentLogGroup = new logs.LogGroup(this, 'CwAgentLogGroup', {
40
+ logGroupName: '/ecs/ecs-cwagent',
41
+ removalPolicy: cdk.RemovalPolicy.DESTROY,
42
+ retention: logs.RetentionDays.ONE_WEEK,
43
+ });
44
+ ```
45
+
46
+ #### 1.3 Add CloudWatch Agent Container to Each Task Definition
47
+ ```typescript
48
+ // Add CloudWatch Agent sidecar to each task definition
49
+ const cwAgentContainer = taskDefinition.addContainer('ecs-cwagent-{SERVICE_NAME}', {
50
+ image: ecs.ContainerImage.fromRegistry('public.ecr.aws/cloudwatch-agent/cloudwatch-agent:latest'),
51
+ essential: false,
52
+ memoryReservationMiB: 128,
53
+ cpu: 64,
54
+ environment: {
55
+ CW_CONFIG_CONTENT: JSON.stringify({
56
+ "traces": {
57
+ "traces_collected": {
58
+ "application_signals": {}
59
+ }
60
+ },
61
+ "logs": {
62
+ "metrics_collected": {
63
+ "application_signals": {}
64
+ }
65
+ }
66
+ }),
67
+ },
68
+ logging: ecs.LogDrivers.awsLogs({
69
+ streamPrefix: 'ecs',
70
+ logGroup: cwAgentLogGroup,
71
+ }),
72
+ });
73
+ ```
74
+
75
+ ### Step 2: Add AWS Distro of OpenTelemetry Zero-Code Instrumentation to Main Service
76
+
77
+ #### 2.1 Add Bind Mount Volumes to Task Definition
78
+ ```typescript
79
+ const taskDefinition = new ecs.FargateTaskDefinition(this, '{SERVICE_NAME}TaskDefinition', {
80
+ // Existing configuration...
81
+ volumes: [
82
+ {
83
+ name: "opentelemetry-auto-instrumentation-java"
84
+ }
85
+ ],
86
+ });
87
+ ```
88
+
89
+ #### 2.2 Add ADOT Auto-instrumentation Init Container
90
+ ```typescript
91
+ const initContainer = taskDefinition.addContainer('init', {
92
+ image: ecs.ContainerImage.fromRegistry('public.ecr.aws/aws-observability/adot-autoinstrumentation-java:v2.20.0'),
93
+ essential: false,
94
+ memoryReservationMiB: 64,
95
+ cpu: 32,
96
+ command: ['cp', '-a', '/javaagent.jar', '/otel-auto-instrumentation-java/javaagent.jar'],
97
+ logging: ecs.LogDrivers.awsLogs({
98
+ streamPrefix: 'init-{SERVICE_NAME}',
99
+ logGroup: serviceLogGroup,
100
+ }),
101
+ });
102
+
103
+ // Add mount point to init container
104
+ initContainer.addMountPoints({
105
+ sourceVolume: 'opentelemetry-auto-instrumentation-java',
106
+ containerPath: '/otel-auto-instrumentation-java',
107
+ readOnly: false,
108
+ });
109
+ ```
110
+
111
+ #### 2.3 Configure Main Application Container OpenTelemetry Environment Variables
112
+
113
+ ##### Java Application Configuration:
114
+ ```typescript
115
+ const mainContainer = taskDefinition.addContainer('{SERVICE_NAME}-container', {
116
+ // Existing configuration...
117
+ environment: {
118
+ // Existing environment variables...
119
+
120
+ // ADOT Configuration for Application Signals
121
+ OTEL_RESOURCE_ATTRIBUTES: 'service.name={SERVICE_NAME}', // SERVICE_NAME is defined by user
122
+ OTEL_METRICS_EXPORTER: 'none',
123
+ OTEL_LOGS_EXPORTER: 'none',
124
+ JAVA_TOOL_OPTIONS: ' -javaagent:/otel-auto-instrumentation-java/javaagent.jar',
125
+ OTEL_TRACES_EXPORTER: 'otlp',
126
+ OTEL_EXPORTER_OTLP_PROTOCOL: 'http/protobuf',
127
+ OTEL_EXPORTER_OTLP_TRACES_ENDPOINT: 'http://localhost:4316/v1/traces',
128
+ OTEL_AWS_APPLICATION_SIGNALS_EXPORTER_ENDPOINT: 'http://localhost:4316/v1/metrics',
129
+ OTEL_AWS_APPLICATION_SIGNALS_ENABLED: 'true',
130
+ },
131
+ });
132
+ ```
133
+
134
+ #### 2.4 Add Mount Point to Main Container
135
+ ```typescript
136
+ // Add mount point to main application container
137
+ mainContainer.addMountPoints({
138
+ sourceVolume: 'opentelemetry-auto-instrumentation-java',
139
+ containerPath: '/otel-auto-instrumentation-java',
140
+ readOnly: false,
141
+ });
142
+ ```
143
+
144
+ #### 2.5 Configure Container Dependencies
145
+ ```typescript
146
+ // Ensure containers start in correct order
147
+ mainContainer.addContainerDependencies({
148
+ container: initContainer,
149
+ condition: ecs.ContainerDependencyCondition.SUCCESS,
150
+ });
151
+
152
+ mainContainer.addContainerDependencies({
153
+ container: cwAgentContainer,
154
+ condition: ecs.ContainerDependencyCondition.START,
155
+ });
156
+ ```
157
+
158
+ ## Completion
159
+
160
+ **Tell the user:**
161
+
162
+ "I've completed the Application Signals enablement for your application. Here's what I modified:
163
+
164
+ **Files Changed:**
165
+ - IAM role: Added CloudWatchAgentServerPolicy
166
+ - ECS container: Installed and configured CloudWatch Agent as sidecar
167
+ - ADOT SDK container: Mounted ADOT SDK dependencies into Application container
168
+ - Applicaiton container: Enabled zero-code instrumentation for Application
169
+
170
+ **Next Steps:**
171
+ 1. Ensure that [Application Signals is enabled in AWS account](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch-Application-Signals-Enable.html).
172
+ This is a one-time setup; if already enabled, you can skip this step.
173
+ 2. Review the changes I made using `git diff`
174
+ 3. Deploy your infrastructure:
175
+ - For CDK: `cdk deploy`
176
+ - For Terraform: `terraform apply`
177
+ - For CloudFormation: Deploy your stack
178
+ 4. After deployment, wait 5-10 minutes for telemetry data to start flowing
179
+
180
+ **Verification:**
181
+ Once deployed, you can verify Application Signals is working by:
182
+ - Opening the AWS CloudWatch Console
183
+ - Navigating to Application Signals → Services
184
+ - Looking for your service (named: {{SERVICE_NAME}})
185
+ - Checking that traces and metrics are being collected
186
+
187
+ **Monitor Application Health:**
188
+ After enablement, you can monitor your application'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).
189
+
190
+ **Troubleshooting**
191
+ 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).
192
+
193
+ Let me know if you'd like me to make any adjustments before you deploy!"
@@ -0,0 +1,198 @@
1
+ # Task: Enable AWS Application Signals for Node.js on ECS
2
+
3
+ ## Overview
4
+ This guide provides complete steps to enable AWS Application Signals for ECS Fargate services, distributed tracing, performance monitoring, and service mapping.
5
+
6
+ ## Prerequisites
7
+ - Services running on ECS both the ec2 and Fargate launch types.
8
+ - Applications using Node.js language
9
+
10
+ ## Implementation Steps
11
+
12
+ **Constraints:**
13
+ You must strictly follow the steps in the order below, do not skip or combine steps.
14
+
15
+ ### Step 1: Setup CloudWatch Agent Task
16
+ When running in ECS, the CloudWatch Agent is deployed as a sidecar container next to the application container.
17
+ Proper permissions, a CWAgentConfig configuration file, and the target log group must be set up to enable logging and metrics collection.
18
+
19
+ #### 1.1 Add CloudWatch Agent Permissions to ECS Task Role
20
+
21
+ Update ECS task role to add CloudWatchAgentServerPolicy:
22
+
23
+ ```typescript
24
+ // Update existing taskRole or create new one
25
+ const taskRole = new iam.Role(this, 'EcsTaskRole', {
26
+ assumedBy: new iam.ServicePrincipal('ecs-tasks.amazonaws.com'),
27
+ managedPolicies: [
28
+ iam.ManagedPolicy.fromAwsManagedPolicyName('AWSXRayDaemonWriteAccess'),
29
+ iam.ManagedPolicy.fromAwsManagedPolicyName('CloudWatchAgentServerPolicy'),
30
+ ],
31
+ inlinePolicies: {
32
+ // Your existing inline policies...
33
+ },
34
+ });
35
+ ```
36
+
37
+ #### 1.2 Create CloudWatch Agent Log Group
38
+ ```typescript
39
+ const cwAgentLogGroup = new logs.LogGroup(this, 'CwAgentLogGroup', {
40
+ logGroupName: '/ecs/ecs-cwagent',
41
+ removalPolicy: cdk.RemovalPolicy.DESTROY,
42
+ retention: logs.RetentionDays.ONE_WEEK,
43
+ });
44
+ ```
45
+
46
+ #### 1.3 Add CloudWatch Agent Container to Each Task Definition
47
+ ```typescript
48
+ // Add CloudWatch Agent sidecar to each task definition
49
+ const cwAgentContainer = taskDefinition.addContainer('ecs-cwagent-{SERVICE_NAME}', {
50
+ image: ecs.ContainerImage.fromRegistry('public.ecr.aws/cloudwatch-agent/cloudwatch-agent:latest'),
51
+ essential: false,
52
+ memoryReservationMiB: 128,
53
+ cpu: 64,
54
+ environment: {
55
+ CW_CONFIG_CONTENT: JSON.stringify({
56
+ "traces": {
57
+ "traces_collected": {
58
+ "application_signals": {}
59
+ }
60
+ },
61
+ "logs": {
62
+ "metrics_collected": {
63
+ "application_signals": {}
64
+ }
65
+ }
66
+ }),
67
+ },
68
+ logging: ecs.LogDrivers.awsLogs({
69
+ streamPrefix: 'ecs',
70
+ logGroup: cwAgentLogGroup,
71
+ }),
72
+ });
73
+ ```
74
+
75
+ ### Step 2: Add ADOT Zero-Code Instrumentation to Main Service
76
+
77
+ #### 2.1 Add Bind Mount Volumes to Task Definition
78
+ ```typescript
79
+ const taskDefinition = new ecs.FargateTaskDefinition(this, '{SERVICE_NAME}TaskDefinition', {
80
+ // Existing configuration...
81
+ volumes: [
82
+ {
83
+ name: "opentelemetry-auto-instrumentation-node"
84
+ }
85
+ ],
86
+ });
87
+ ```
88
+
89
+ #### 2.2 Add AWS Distro of OpenTelemetry Auto-instrumentation Init Container
90
+ ```typescript
91
+ const initContainer = taskDefinition.addContainer('init', {
92
+ image: ecs.ContainerImage.fromRegistry('public.ecr.aws/aws-observability/adot-autoinstrumentation-node:v0.8.0'),
93
+ essential: false,
94
+ memoryReservationMiB: 64,
95
+ cpu: 32,
96
+ command: ['cp', '-a', '/autoinstrumentation/.', '/otel-auto-instrumentation-node'],
97
+ logging: ecs.LogDrivers.awsLogs({
98
+ streamPrefix: 'init-{SERVICE_NAME}',
99
+ logGroup: serviceLogGroup,
100
+ }),
101
+ });
102
+
103
+ // Add mount point to init container
104
+ initContainer.addMountPoints({
105
+ sourceVolume: 'opentelemetry-auto-instrumentation-node',
106
+ containerPath: '/otel-auto-instrumentation-node',
107
+ readOnly: false,
108
+ });
109
+ ```
110
+
111
+ #### 2.3 Configure Main Application Container OpenTelemetry Environment Variables
112
+
113
+ ##### Node.js Application Configuration:
114
+ ```typescript
115
+ const mainContainer = taskDefinition.addContainer('{SERVICE_NAME}-container', {
116
+ // Existing configuration...
117
+ environment: {
118
+ // Existing environment variables...
119
+
120
+ // ADOT Configuration for Application Signals - Node.js
121
+ OTEL_RESOURCE_ATTRIBUTES: 'service.name=${SERVICE_NAME}', // SERVICE_NAME is defined by user
122
+ OTEL_METRICS_EXPORTER: 'none',
123
+ OTEL_LOGS_EXPORTER: 'none',
124
+ NODE_OPTIONS: '--require /otel-auto-instrumentation-node/autoinstrumentation.js', // CJS
125
+ OTEL_TRACES_EXPORTER: 'otlp',
126
+ OTEL_EXPORTER_OTLP_PROTOCOL: 'http/protobuf',
127
+ OTEL_EXPORTER_OTLP_TRACES_ENDPOINT: 'http://localhost:4316/v1/traces',
128
+ OTEL_AWS_APPLICATION_SIGNALS_EXPORTER_ENDPOINT: 'http://localhost:4316/v1/metrics',
129
+ OTEL_AWS_APPLICATION_SIGNALS_ENABLED: 'true',
130
+ },
131
+ });
132
+ ```
133
+ If the project uses CJS, then
134
+ NODE_OPTIONS: '--require /otel-auto-instrumentation-node/autoinstrumentation.js',
135
+
136
+ but if it uses ESM, then
137
+ NODE_OPTIONS: '--import /otel-auto-instrumentation-node/autoinstrumentation.js --experimental-loader=/otel-auto-instrumentation-node/node_modules/@opentelemetry/instrumentation/instrumentation/hook.mjs'
138
+
139
+ #### 2.4 Add Mount Point to Main Container
140
+ ```typescript
141
+ // Add mount point to main application container
142
+ mainContainer.addMountPoints({
143
+ sourceVolume: 'opentelemetry-auto-instrumentation-node',
144
+ containerPath: '/otel-auto-instrumentation-node',
145
+ readOnly: false,
146
+ });
147
+ ```
148
+
149
+ #### 2.5 Configure Container Dependencies
150
+ ```typescript
151
+ // Ensure containers start in correct order
152
+ mainContainer.addContainerDependencies({
153
+ container: initContainer,
154
+ condition: ecs.ContainerDependencyCondition.SUCCESS,
155
+ });
156
+
157
+ mainContainer.addContainerDependencies({
158
+ container: cwAgentContainer,
159
+ condition: ecs.ContainerDependencyCondition.START,
160
+ });
161
+ ```
162
+
163
+ ## Completion
164
+
165
+ **Tell the user:**
166
+
167
+ "I've completed the Application Signals enablement for your application. Here's what I modified:
168
+
169
+ **Files Changed:**
170
+ - IAM role: Added CloudWatchAgentServerPolicy
171
+ - ECS container: Installed and configured CloudWatch Agent as sidecar
172
+ - ADOT SDK container: Mounted ADOT SDK dependencies into Application container
173
+ - Applicaiton container: Enabled zero-code instrumentation for Application
174
+
175
+ **Next Steps:**
176
+ 1. Ensure that [Application Signals is enabled in AWS account](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch-Application-Signals-Enable.html).
177
+ This is a one-time setup; if already enabled, you can skip this step.
178
+ 2. Review the changes I made using `git diff`
179
+ 3. Deploy your infrastructure:
180
+ - For CDK: `cdk deploy`
181
+ - For Terraform: `terraform apply`
182
+ - For CloudFormation: Deploy your stack
183
+ 4. After deployment, wait 5-10 minutes for telemetry data to start flowing
184
+
185
+ **Verification:**
186
+ Once deployed, you can verify Application Signals is working by:
187
+ - Opening the AWS CloudWatch Console
188
+ - Navigating to Application Signals → Services
189
+ - Looking for your service (named: {{SERVICE_NAME}})
190
+ - Checking that traces and metrics are being collected
191
+
192
+ **Monitor Application Health:**
193
+ After enablement, you can monitor your application'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).
194
+
195
+ **Troubleshooting**
196
+ 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).
197
+
198
+ Let me know if you'd like me to make any adjustments before you deploy!"