Setting Up Application Signals Onboarding with ADOT Auto-Instrumentation: A Complete Guide
You can set up Application Signals onboarding with ADOT auto-instrumentation by deploying the CloudWatch Observability add-on on EKS (or ADOT SDK/Layers on ECS/EC2/Lambda), attaching the CloudWatchAgentServerPolicy and AWSXRayDaemonWriteAccess IAM policies, and applying language-specific instrumentation annotations—all managed through the AWS Agent Toolkit for AWS repository's structured two-tier workflow.
The AWS Agent Toolkit for AWS provides a comprehensive, language-agnostic workflow for setting up Application Signals onboarding with ADOT auto-instrumentation across EC2, ECS, EKS, and Lambda. This implementation uses a two-tiered approach defined in skills/core-skills/aws-observability/references/application-signals-onboarding.md that separates baseline observability enablement from advanced metadata collection, allowing you to deploy auto-instrumentation with minimal changes to your existing infrastructure-as-code.
Understanding the Two-Tier Onboarding Model
The onboarding workflow divides capabilities into two distinct tiers based on platform and language support.
Tier 1 – Application Signals Enablement provides ADOT auto-instrumentation via the CloudWatch Observability add-on (EKS), init containers, or Lambda layers. This tier supports all platforms (EC2, ECS, EKS, Lambda) and all languages (Python, Node.js, Java, .NET).
Tier 2 – ServiceEvents Extras adds Git/CI-CD metadata, OTLP endpoint environment variables, and optional dynamic instrumentation. This tier is limited to EC2, ECS, and EKS running Python, Node.js, or Java only. According to the source code in application-signals-onboarding.md (line 27), Tier 2 is explicitly disabled for Lambda and .NET workloads.
Tier 1 Implementation – Enabling Application Signals
EKS CloudWatch Observability Add-on
For Amazon EKS clusters, the toolkit installs the CloudWatch Observability add-on, which automatically injects ADOT via an init container and runs the CloudWatch Agent.
In your Terraform configuration, add the following resource as shown in lines 63-70 of the onboarding guide:
resource "aws_eks_addon" "cloudwatch_observability" {
cluster_name = aws_eks_cluster.app_cluster.name
addon_name = "amazon-cloudwatch-observability"
}
For AWS CDK (TypeScript), implement the add-on with the proper IAM service account role:
import * as eks from 'aws-cdk-lib/aws-eks';
import * as iam from 'aws-cdk-lib/aws-iam';
const cwRole = new iam.Role(this, 'CWAgentRole', {
assumedBy: new iam.ServicePrincipal('eks.amazonaws.com'),
managedPolicies: [
iam.ManagedPolicy.fromAwsManagedPolicyName('CloudWatchAgentServerPolicy')
],
});
new eks.CfnAddon(this, 'CWObservability', {
addonName: 'amazon-cloudwatch-observability',
clusterName: cluster.clusterName,
serviceAccountRoleArn: cwRole.roleArn,
});
IAM Permissions Configuration
All platforms require two specific managed policies: CloudWatchAgentServerPolicy and AWSXRayDaemonWriteAccess.
For EKS node groups, attach these policies via iam_role_additional_policies (see lines 95-122 of the onboarding guide). For ECS tasks, attach them to the task execution role. For EC2 instances, add them to the instance profile.
Language-Specific Instrumentation Annotations
After installing the base add-on, apply language-specific instrumentation by updating your Kubernetes Deployment manifests. The toolkit references guides located at skills/core-skills/aws-observability/references/appsignals-guides/<platform>-<language>.md.
For Python on EKS, add the following annotation to your Deployment metadata:
metadata:
annotations:
instrumentation.opentelemetry.io/inject-python: "true"
Similar annotations exist for Node.js (inject-nodejs), Java (inject-java), and .NET (inject-dotnet).
ECS and EC2 Deployment Patterns
For ECS and EC2, the toolkit configures ADOT auto-instrumentation through task definition sidecars or host-based agent installations rather than Kubernetes add-ons. The initialization follows the same IAM permission requirements but uses the ADOT init container pattern specific to your container runtime.
Lambda Function Instrumentation
Lambda functions use the ADOT Lambda layer for instrumentation. Since Tier 2 is disabled for Lambda (as noted in line 27 of the onboarding guide), only baseline Application Signals enablement is applied.
Resources:
MyFunction:
Type: AWS::Serverless::Function
Properties:
Runtime: python3.11
Layers:
- arn:aws:lambda:us-east-1:123456789012:layer:AWSOpenTelemetryDistroPython:6
Policies:
- AWSXRayDaemonWriteAccess
- CloudWatchAgentServerPolicy
Tier 2 Implementation – ServiceEvents and CI/CD Metadata
When running on supported platforms (EC2, ECS, EKS) with Python, Node.js, or Java, the toolkit automatically injects ServiceEvents environment variables to enrich telemetry with deployment context.
The following environment variables are configured according to skills/core-skills/aws-observability/references/appsignals-cicd-metadata.md:
| Variable | Purpose | Injection Point |
|---|---|---|
OTEL_AWS_SERVICE_EVENTS_GIT_REPO_URL |
Source repository URL | Build-time (Dockerfile) |
OTEL_AWS_SERVICE_EVENTS_GIT_COMMIT_SHA |
Git commit SHA | Build-time (Dockerfile) |
OTEL_AWS_SERVICE_EVENTS_DEPLOYMENT_URL |
Deployment system URL | Runtime (Pod/Task) |
OTEL_AWS_SERVICE_EVENTS_DEPLOYMENT_ID |
Unique deployment identifier | Runtime (Pod/Task) |
OTEL_AWS_SERVICE_EVENTS_DEPLOYMENT_TIMESTAMP |
Deployment timestamp | Runtime (Pod/Task) |
OTEL_AWS_OTLP_LOGS_ENDPOINT |
OTLP collector for logs (port 4316) | Runtime configuration |
OTEL_AWS_OTLP_METRICS_ENDPOINT |
OTLP collector for metrics (port 4316) | Runtime configuration |
To enable dynamic instrumentation, set OTEL_AWS_DYNAMIC_INSTRUMENTATION_ENABLED to true. For per-function instrumentation, populate OTEL_AWS_SERVICE_EVENTS_PACKAGES_INCLUDE as documented in Step 5c of the onboarding guide (lines 42-124).
Complete Implementation Examples
Terraform: EKS with Python Auto-Instrumentation
This complete example from the onboarding guide (lines 67-104) demonstrates the three required components: IAM attachment, add-on installation, and Kubernetes annotation.
# IAM policy attachment for CloudWatch Agent
resource "aws_iam_role_policy_attachment" "cloudwatch_agent_policy" {
policy_arn = "arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy"
role = aws_iam_role.node_role.name
}
# CloudWatch Observability add-on
resource "aws_eks_addon" "cloudwatch_observability" {
cluster_name = aws_eks_cluster.app_cluster.name
addon_name = "amazon-cloudwatch-observability"
depends_on = [
aws_iam_role_policy_attachment.cloudwatch_agent_policy,
aws_eks_node_group.app_nodes,
]
}
# Deployment with Python instrumentation
resource "kubernetes_deployment" "app" {
metadata {
name = var.app_name
labels = { app = var.app_name }
annotations = {
"instrumentation.opentelemetry.io/inject-python" = "true"
}
}
# Container spec remains unchanged
}
CDK: ECS with Node.js and ServiceEvents
This implementation for ECS Node.js services includes the CloudWatch Agent sidecar and Tier 2 metadata variables, referencing skills/core-skills/aws-observability/references/appsignals-guides/ecs-nodejs.md.
import * as ecs from 'aws-cdk-lib/aws-ecs';
import * as iam from 'aws-cdk-lib/aws-iam';
import * as ecsPatterns from 'aws-cdk-lib/aws-ecs-patterns';
const cwRole = new iam.Role(this, 'CWAgentRole', {
assumedBy: new iam.ServicePrincipal('ecs-tasks.amazonaws.com'),
managedPolicies: [
iam.ManagedPolicy.fromAwsManagedPolicyName('CloudWatchAgentServerPolicy'),
iam.ManagedPolicy.fromAwsManagedPolicyName('AWSXRayDaemonWriteAccess'),
],
});
new ecsPatterns.ApplicationLoadBalancedFargateService(this, 'Service', {
taskImageOptions: {
image: ecs.ContainerImage.fromRegistry('myrepo/my-node-app:latest'),
containerPort: 8080,
environment: {
OTEL_AWS_SERVICE_EVENTS_GIT_REPO_URL: 'https://github.com/myorg/myrepo',
OTEL_AWS_SERVICE_EVENTS_GIT_COMMIT_SHA: '$(git rev-parse HEAD)',
},
},
// CloudWatch Agent sidecar configuration
});
Lambda: Minimal Tier 1 Configuration
For Lambda functions, restrict configuration to Tier 1 only, as ServiceEvents extras are not supported.
Resources:
MyFunction:
Type: AWS::Serverless::Function
Properties:
Runtime: python3.11
Handler: app.lambda_handler
Layers:
- arn:aws:lambda:us-east-1:123456789012:layer:AWSOpenTelemetryDistroPython:6
Policies:
- AWSXRayDaemonWriteAccess
- CloudWatchAgentServerPolicy
Environment:
Variables:
OTEL_AWS_APPLICATION_SIGNALS_EXPORTER_ENDPOINT: "https://aps-workspaces.<region>.amazonaws.com"
Reference Configuration Files
The following source files in the aws/agent-toolkit-for-aws repository define the implementation details:
skills/core-skills/aws-observability/references/application-signals-onboarding.md– Master workflow defining Tier 1/Tier 2 logic and platform constraintsskills/core-skills/aws-observability/references/appsignals-guides/eks-python.md– Python-specific EKS instrumentation (annotations, IAM roles)skills/core-skills/aws-observability/references/appsignals-guides/ecs-nodejs.md– Node.js ECS task definition patternsskills/core-skills/aws-observability/references/appsignals-cicd-metadata.md– ServiceEvents environment variable specificationsskills/core-skills/aws-observability/references/tracing.md– ADOT collector configuration and SDK requirementsskills/core-skills/aws-observability/SKILL.md– High-level AWS Observability skill overview
Summary
- Setting up Application Signals onboarding with ADOT auto-instrumentation requires the CloudWatch Observability add-on for EKS or ADOT layers/SDK for ECS, EC2, and Lambda, plus mandatory IAM policies (
CloudWatchAgentServerPolicyandAWSXRayDaemonWriteAccess). - The two-tier model separates baseline instrumentation (Tier 1, all platforms/languages) from advanced metadata collection (Tier 2, limited to EC2/ECS/EKS with Python/Node.js/Java).
- Language-specific guides in
skills/core-skills/aws-observability/references/appsignals-guides/provide exact annotations and configuration patterns for each runtime. - ServiceEvents variables (
OTEL_AWS_SERVICE_EVENTS_*) enrich telemetry with Git and deployment metadata but are automatically excluded for Lambda and .NET workloads. - Tier 2 OTLP endpoints use port 4316 for logs and metrics collection on EC2, ECS, and EKS nodes.
Frequently Asked Questions
What IAM permissions are required for ADOT auto-instrumentation?
You must attach the CloudWatchAgentServerPolicy and AWSXRayDaemonWriteAccess managed policies to your IAM roles. For EKS, attach these to the node group role via iam_role_additional_policies. For ECS, attach them to the task execution role. These permissions allow the CloudWatch Agent to publish metrics and the X-Ray daemon to write trace data.
Why are ServiceEvents features unavailable for Lambda and .NET?
According to the source code in application-signals-onboarding.md (line 27), Tier 2 ServiceEvents extras are explicitly disabled for Lambda functions and .NET applications. This limitation means these workloads only receive Tier 1 Application Signals enablement (basic tracing and metrics) without the CI/CD metadata, dynamic instrumentation, or OTLP endpoint configurations available for Python, Node.js, and Java on container platforms.
How do I enable dynamic instrumentation for supported languages?
Set the environment variable OTEL_AWS_DYNAMIC_INSTRUMENTATION_ENABLED to true in your container or task definition. For per-function instrumentation, populate OTEL_AWS_SERVICE_EVENTS_PACKAGES_INCLUDE with the specific packages you want to instrument, as documented in Step 5c of the onboarding guide. This feature is only available for Tier 2 supported combinations (EC2/ECS/EKS with Python, Node.js, or Java).
What is the difference between the CloudWatch Observability add-on and ADOT Lambda layers?
The CloudWatch Observability add-on is an EKS-specific managed add-on that installs the CloudWatch Agent and ADOT auto-instrumentation via init containers. ADOT Lambda layers are AWS Lambda layers that package the OpenTelemetry runtime and SDK, injected into your function execution environment. The add-on manages the entire cluster lifecycle, while Lambda layers provide language-specific instrumentation per function.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →