# Setting Up Application Signals Onboarding with ADOT Auto-Instrumentation: A Complete Guide

> Learn how to set up Application Signals onboarding with ADOT auto-instrumentation. Follow this complete guide for deploying the CloudWatch Observability add-on and configuring IAM policies for seamless integration.

- Repository: [Amazon Web Services/agent-toolkit-for-aws](https://github.com/aws/agent-toolkit-for-aws)
- Tags: how-to-guide
- Published: 2026-07-02

---

**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`](https://github.com/aws/agent-toolkit-for-aws/blob/main/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`](https://github.com/aws/agent-toolkit-for-aws/blob/main/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:

```hcl
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:

```typescript
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:

```yaml
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.

```yaml
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`](https://github.com/aws/agent-toolkit-for-aws/blob/main/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.

```hcl

# 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`](https://github.com/aws/agent-toolkit-for-aws/blob/main/skills/core-skills/aws-observability/references/appsignals-guides/ecs-nodejs.md).

```typescript
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.

```yaml
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`](https://github.com/aws/agent-toolkit-for-aws/blob/main/skills/core-skills/aws-observability/references/application-signals-onboarding.md) – Master workflow defining Tier 1/Tier 2 logic and platform constraints
- [`skills/core-skills/aws-observability/references/appsignals-guides/eks-python.md`](https://github.com/aws/agent-toolkit-for-aws/blob/main/skills/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`](https://github.com/aws/agent-toolkit-for-aws/blob/main/skills/core-skills/aws-observability/references/appsignals-guides/ecs-nodejs.md) – Node.js ECS task definition patterns
- [`skills/core-skills/aws-observability/references/appsignals-cicd-metadata.md`](https://github.com/aws/agent-toolkit-for-aws/blob/main/skills/core-skills/aws-observability/references/appsignals-cicd-metadata.md) – ServiceEvents environment variable specifications
- [`skills/core-skills/aws-observability/references/tracing.md`](https://github.com/aws/agent-toolkit-for-aws/blob/main/skills/core-skills/aws-observability/references/tracing.md) – ADOT collector configuration and SDK requirements
- [`skills/core-skills/aws-observability/SKILL.md`](https://github.com/aws/agent-toolkit-for-aws/blob/main/skills/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 (`CloudWatchAgentServerPolicy` and `AWSXRayDaemonWriteAccess`).
- 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`](https://github.com/aws/agent-toolkit-for-aws/blob/main/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.