# Enable Application Signals Auto-Instrumentation on EKS Using ADOT: Implementation Guide

> Enable Application Signals auto-instrumentation on EKS effortlessly with ADOT. This guide details implementing the CloudWatch Observability add-on for zero code changes and seamless telemetry.

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

---

**You enable Application Signals auto-instrumentation on Amazon EKS by installing the `amazon-cloudwatch-observability` add-on, which deploys the AWS Distro for OpenTelemetry (ADOT) collector as a DaemonSet and automatically injects language-specific SDKs into pods via a mutating webhook, requiring zero application code changes.**

AWS Application Signals (formerly CloudWatch Observability) provides automatic collection of metrics, traces, and logs from containerized workloads. According to the `aws/agent-toolkit-for-aws` repository, this auto-instrumentation architecture relies on the **Amazon CloudWatch Observability EKS add-on** to manage the complete lifecycle of ADOT components, from initial SDK injection to telemetry export, as documented in [`skills/core-skills/aws-observability/SKILL.md`](https://github.com/aws/agent-toolkit-for-aws/blob/main/skills/core-skills/aws-observability/SKILL.md).

## How the ADOT Auto-Instrumentation Architecture Works

The toolkit implements a non-intrusive instrumentation pattern that intercepts pod specifications at deployment time and injects the necessary OpenTelemetry components.

### The CloudWatch Observability EKS Add-on

The `amazon-cloudwatch-observability` add-on runs as a **DaemonSet** on every node in your EKS cluster. It deploys two critical components: the ADOT collector and the CloudWatch Agent. The add-on also registers a **mutating webhook** that monitors for specific annotations on `Deployment` and `StatefulSet` resources. When it detects the `adot.autoinstrumentation=true` annotation, the webhook automatically modifies the pod specification to include an init container and environment variables. This architecture is detailed in the onboarding guide at [`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).

### Init-Container Injection Mechanism

When the webhook detects an annotated workload, it injects an **ADOT init container** into the pod spec before the application containers start. This init container mounts a shared volume and installs the language-specific ADOT auto-instrumentation SDK into the application container's filesystem. For example, the Python init container uses the image `public.ecr.aws/aws-observability/adot-autoinstrumentation-python:v0.18.0` to install the `aws-opentelemetry-distro` package. The init container approach ensures the SDK is present without requiring modifications to the application Docker image.

### Collector Configuration and Exporters

The ADOT collector runs either as a sidecar or as part of the node-level DaemonSet, depending on the configuration. It is pre-configured with several key components:

- **OTLP exporter**: Points to the Application Signals endpoint via the `OTEL_AWS_APPLICATION_SIGNALS_EXPORTER_ENDPOINT` environment variable
- **X-Ray exporter**: Optional component for backward compatibility with existing X-Ray implementations
- **awsproxy extension**: Allows the collector to forward X-Ray traces through the CloudWatch Agent when needed

The collector configuration for EKS DaemonSet deployments is documented in [`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).

## Prerequisites and IAM Configuration

Before enabling auto-instrumentation, you must configure the appropriate IAM permissions for telemetry export.

### Required IAM Policies

The node group IAM role or the pod's service account (via IRSA) must attach the `CloudWatchAgentServerPolicy` managed policy. This grants the ADOT collector permissions to publish metrics and traces to CloudWatch Application Signals. The add-on automatically attaches these policies to the node role when installed; for custom pod roles using IRSA, you must manually attach the policy.

### Supported Language Runtimes

The toolkit provides specific init container images and SDK versions for each supported language:

- **Python**: `aws-opentelemetry-distro` pip package (version `0.18.x`) — see [`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)
- **Node.js**: `@aws/aws-distro-opentelemetry-node-autoinstrumentation` npm package (version `0.12.x`) — see [`skills/core-skills/aws-observability/references/appsignals-guides/eks-nodejs.md`](https://github.com/aws/agent-toolkit-for-aws/blob/main/skills/core-skills/aws-observability/references/appsignals-guides/eks-nodejs.md)
- **Java**: ADOT Java agent JAR (version `2.28.2`) — see [`skills/core-skills/aws-observability/references/appsignals-guides/eks-java.md`](https://github.com/aws/agent-toolkit-for-aws/blob/main/skills/core-skills/aws-observability/references/appsignals-guides/eks-java.md)
- **.NET**: ADOT .NET auto-instrumentation script (`AWSOpenTelemetryDistroDotNet`) — see [`skills/core-skills/aws-observability/references/appsignals-guides/eks-dotnet.md`](https://github.com/aws/agent-toolkit-for-aws/blob/main/skills/core-skills/aws-observability/references/appsignals-guides/eks-dotnet.md)

## Step-by-Step Implementation

### Install the Amazon CloudWatch Observability Add-on

Using AWS CDK (TypeScript), enable the add-on to deploy the DaemonSet and mutating webhook:

```typescript
import * as eks from 'aws-cdk-lib/aws-eks';

const cluster = eks.Cluster.fromClusterAttributes(this, 'MyCluster', {
  clusterName: 'my-eks-cluster',
  vpc: myVpc,
  securityGroup: mySg,
  // additional attributes
});

cluster.addAwsCdkAddon('cloudwatch-observability', {
  addonName: 'amazon-cloudwatch-observability',
  version: 'v6.3.0',
  resolveConflicts: eks.ResolveConflicts.OVERWRITE,
});

```

For Terraform, attach the required policy to your node group role:

```hcl
resource "aws_iam_role_policy_attachment" "cw_observability" {
  role       = aws_eks_node_group.my_node_group.role
  policy_arn = "arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy"
}

```

### Annotate Deployments for Auto-Instrumentation

Add the `adot.autoinstrumentation` annotation to your workload manifests to trigger the mutating webhook:

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-python-app
  annotations:
    adot.autoinstrumentation: "true"
spec:
  replicas: 2
  selector:
    matchLabels:
      app: my-python-app
  template:
    metadata:
      labels:
        app: my-python-app
    spec:
      serviceAccountName: my-app-sa
      containers:
        - name: app
          image: myrepo/my-python-app:latest

```

The webhook automatically injects the appropriate init container based on the detected language runtime.

### Configure ServiceEvents (Optional)

For supported languages (Python, Node.js, Java), the add-on can inject **ServiceEvents** environment variables to include CI/CD metadata in traces:

```yaml
env:
  - name: OTEL_SERVICE_NAME
    value: "my-python-service"
  - name: OTEL_RESOURCE_ATTRIBUTES
    value: "deployment.environment=prod,git.repository=repo-name"

```

These variables are automatically added when ServiceEvents is enabled for the platform and language combination, as noted 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).

## Understanding the End-to-End Flow

The complete telemetry flow follows this path:

1. **Application Pod** starts with the init container copying the ADOT SDK into the container filesystem
2. **ADOT SDK** automatically instruments the application runtime using the attached agent or wrapper
3. **ADOT Collector** receives OTLP data from the SDK via local endpoints
4. **CloudWatch Application Signals** ingests the metrics and traces for visualization and analysis

This architecture ensures that workloads send telemetry to the `OTEL_AWS_APPLICATION_SIGNALS_EXPORTER_ENDPOINT` without requiring manual SDK initialization or exporter configuration in the application code.

## Summary

- **Install the add-on**: Deploy `amazon-cloudwatch-observability` to create the DaemonSet and mutating webhook that manage ADOT components
- **Annotate workloads**: Add `adot.autoinstrumentation=true` to Deployments or StatefulSets to trigger automatic SDK injection
- **Configure IAM**: Ensure node roles or IRSA-attached roles include `CloudWatchAgentServerPolicy` for telemetry export permissions
- **Language support**: Use built-in init containers for Python (0.18.x), Node.js (0.12.x), Java (2.28.2), and .NET without code changes
- **Reference architecture**: Consult [`skills/core-skills/aws-observability/SKILL.md`](https://github.com/aws/agent-toolkit-for-aws/blob/main/skills/core-skills/aws-observability/SKILL.md) and the language-specific guides in `appsignals-guides/` for implementation details

## Frequently Asked Questions

### What is the difference between ADOT and the CloudWatch Observability add-on?

**ADOT (AWS Distro for OpenTelemetry)** is the open-source distribution of OpenTelemetry that provides the SDKs and collectors for telemetry collection. The **Amazon CloudWatch Observability add-on** is the managed EKS component that automates the deployment and configuration of ADOT, including the mutating webhook, init containers, and IAM policy management. You use the add-on to consume ADOT without manually managing the collector configurations or SDK installations.

### Do I need to modify my application code to use auto-instrumentation?

**No.** Auto-instrumentation requires zero code changes. The mutating webhook detects the `adot.autoinstrumentation` annotation and injects an init container that installs the language-specific SDK into the container filesystem. The SDK then automatically instruments supported libraries and frameworks at runtime using environment variables like `OTEL_SERVICE_NAME` and `OTEL_RESOURCE_ATTRIBUTES`.

### Which programming languages support Application Signals auto-instrumentation on EKS?

**Python, Node.js, Java, and .NET** are fully supported. The toolkit provides specific init container images and SDK versions for each: Python uses the `aws-opentelemetry-distro` pip package (0.18.x), Node.js uses the `@aws/aws-distro-opentelemetry-node-autoinstrumentation` npm package (0.12.x), Java uses the ADOT Java agent JAR (2.28.2), and .NET uses the `AWSOpenTelemetryDistroDotNet` script. Each language has a dedicated guide in the `skills/core-skills/aws-observability/references/appsignals-guides/` directory.

### How does the collector export data to Application Signals?

The ADOT collector deployed by the add-on is pre-configured with an **OTLP exporter** that targets the `OTEL_AWS_APPLICATION_SIGNALS_EXPORTER_ENDPOINT`. It also includes the **awsproxy extension** to forward X-Ray traces through the CloudWatch Agent when necessary. This configuration is applied automatically by the DaemonSet deployment described in [`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).