Setting up Datadog APM on EKS + Fargate
Tags: eks, fargate, datadog, apm
Published: 2022-09-09 16:33:17

In this post, I will go through the steps required to integrate Datadog APM with EKS using Fargate as computing option.

The process is very similar to [Setting up Datadog APM on ECS, Fargate(Spring Boot)](https://dev.to/aws-builders/setting-up-datadog-apm-on-ecs-fargatespring-boot-4ema).

The datadog agent container must run as a sidecar of each of your application's container.

## Installing datadog agent

We will use helm to install datadog agent into Kubernetes cluster.

First, run the command below to add datadog's repository to helm.

```sh
helm repo add datadog https://helm.datadoghq.com
helm repo update
```

After that, we have to edit [values.yaml](https://github.com/DataDog/helm-charts/blob/main/charts/datadog/values.yaml) file, which will be used as a configuration file used by datadog agent running in the cluster. The fields I overrided(edited) are as below.

  - `registry`: Apply the value of AWS in the comment.
  - `datadog.apiKey`: Value of the API key that you created in Datadog.
  - `datadog.apm.portEnabled`: Set to true.

Finally, let's run the command below to finish installation.

```sh
helm install datadog-agent -f values.yaml datadog/datadog
```

---

## Configuring APM

To integrate Datadog APM with your application, you must make sure that your application uses datadog agent when running itself. For instance, I have a Spring boot application (JVM), and corresponding dockerfile looks as below.

> There is 1 datadog agent installed on your EKS cluster, and another datadog agent running as a process of your application to collect metrics.

```Dockerfile
FROM openjdk:11-jdk AS builder
WORKDIR application
ARG JAR_FILE=build/libs/MY_APP.jar
COPY ${JAR_FILE} application.jar
RUN java -Djarmode=layertools -jar application.jar extract

FROM openjdk:11-jdk
WORKDIR application
RUN  apt-get update \
  && apt-get install -y wget \
  && rm -rf /var/lib/apt/lists/*
RUN wget -O dd-java-agent.jar 'https://dtdg.co/latest-java-tracer'

COPY --from=builder application/application.jar ./application.jar
RUN true
COPY --from=builder application/dependencies/ ./
RUN true
COPY --from=builder application/spring-boot-loader/ ./
RUN true
COPY --from=builder application/snapshot-dependencies/ ./
RUN true
COPY --from=builder application/application/ ./
RUN true

ENV TZ Asia/Seoul

ENTRYPOINT ["java", "-javaagent:dd-java-agent.jar", "-Ddd.profiling.enabled=true", "-XX:FlightRecorderOptions=stackdepth=256", "org.springframework.boot.loader.JarLauncher"]
```

In the example above, `dd-java-agent.jar` uses port 8126 of container running datadog agent to send metrics to datadog.

Now all we have to do is to add another container spec to Kubernetes deployment file.

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: planit-deployment
  namespace: planit
  labels:
    app: planit
spec:
  replicas: 3
  revisionHistoryLimit: 2
  selector:
    matchLabels:
      app: planit
  template:
    metadata:
      labels:
        app: planit
    spec:
      containers:
        - name: "CONTAINER_NAME"
          image: "YOUR_IMAGE_NAME"
          imagePullPolicy: Always
          ports:
            - containerPort: 8080
              protocol: TCP
        - name: datadog-agent 
          image: datadog/agent:latest
          ports:
            - containerPort: 8126
              name: traceport
              protocol: TCP
          env:
            - name: DD_KUBERNETES_KUBELET_NODENAME
              valueFrom:
                fieldRef:
                  apiVersion: v1
                  fieldPath: spec.nodeName
            - name: DD_API_KEY
              valueFrom:
                secretKeyRef:
                  name: datadog-secret
                  key: DD_API_KEY
            - name: DD_SITE
              valueFrom:
                secretKeyRef:
                  name: datadog-secret
                  key: DD_SITE
            - name: DD_EKS_FARGATE
              valueFrom:
                secretKeyRef:
                  name: datadog-secret
                  key: DD_EKS_FARGATE
            - name: DD_APM_ENABLED
              valueFrom:
                secretKeyRef:
                  name: datadog-secret
                  key: DD_APM_ENABLED
            - name: DD_ENV
              valueFrom:
                secretKeyRef:
                  name: datadog-secret
                  key: DD_ENV
            - name: DD_SERVICE
              valueFrom:
                secretKeyRef:
                  name: datadog-secret
                  key: DD_SERVICE
            - name: DD_VERSION
              valueFrom:
                secretKeyRef:
                  name: datadog-secret
                  key: DD_VERSION
            - name: DD_PROFILING_ENABLED
              valueFrom:
                secretKeyRef:
                  name: datadog-secret
                  key: DD_PROFILING_ENABLED
            - name: DD_APM_IGNORE_RESOURCES
              valueFrom:
                secretKeyRef:
                  name: datadog-secret
                  key: DD_APM_IGNORE_RESOURCES
            - name: DD_LOGS_INJECTION
              valueFrom:
                secretKeyRef:
                  name: datadog-secret
                  key: DD_LOGS_INJECTION
```

> `datadog-secret` is a Kubernetes secret object I created to store configuration values related to Datadog.

After deploying new Kubernetes deployment, you should be able to see APM working well as below.


![DD APM UI](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uhwris1jh9t0co278vgj.png)