Terraform for AWS EKS Observability with Datadog and PagerDuty Integration

Architecture Pro-Tip:

For production AWS EKS environments, always deploy your Datadog Agent as a Kubernetes DaemonSet using the official Helm chart. This ensures the agent runs on every node, capturing comprehensive metrics, logs, and traces (including APM and process data) without manual intervention, and scales automatically with your cluster nodes for robust, cluster-wide observability.

Terraform for AWS EKS Observability: A Comprehensive Guide with Datadog and PagerDuty Integration

In today's dynamic cloud-native landscape, ensuring the health and performance of your Kubernetes clusters is paramount. AWS Elastic Kubernetes Service (EKS) provides a robust platform for orchestrating containers, but gaining deep visibility into its inner workings requires a powerful observability stack. This guide will walk you through implementing a comprehensive observability solution for EKS using Terraform, integrating Datadog for rich monitoring and PagerDuty for streamlined incident response.

Why EKS Observability is Critical for Modern Applications

EKS, while powerful, introduces significant complexity. Applications are decoupled into microservices, running across multiple nodes, pods, and namespaces. This distributed nature makes traditional monitoring challenging. Robust observability, encompassing metrics, logs, and traces, is crucial for:

  • Proactive Issue Identification: Spotting anomalies and potential problems before they impact users.
  • Faster Root Cause Analysis: Quickly pinpointing the source of problems across complex dependencies.
  • Performance Optimization: Identifying bottlenecks and areas for resource efficiency.
  • Enhanced Reliability: Maintaining high availability and a positive user experience.

Datadog: The EKS Observability Powerhouse

Datadog is a leading monitoring and analytics platform that provides end-to-end visibility across your entire technology stack. For EKS, Datadog excels by:

  • Unified Data Collection: Gathers metrics, logs, and traces from your EKS cluster, nodes, pods, and applications.
  • Kubernetes-Native Integration: Automatically discovers and tags Kubernetes resources, providing out-of-the-box dashboards and monitors.
  • APM & Distributed Tracing: Tracks requests across microservices, helping visualize service dependencies and latencies.
  • Intelligent Alerting: Configurable alerts based on various metrics and logs, reducing noise and focusing on critical events.
  • Customizable Dashboards: Build insightful visualizations tailored to your specific needs.

PagerDuty: Streamlining Incident Response

When a critical issue arises, quick and efficient incident response is crucial. PagerDuty is an incident management platform that transforms Datadog alerts into actionable incidents by:

  • Automated On-Call Scheduling: Ensures the right person is notified at the right time.
  • Multi-Channel Notifications: Alerts teams via phone calls, SMS, email, and push notifications.
  • Escalation Policies: Automatically escalates incidents if they are not acknowledged or resolved within defined timeframes.
  • Incident Context: Provides rich context from Datadog to help responders understand and resolve issues faster.

Terraform: Orchestrating Your Observability Infrastructure as Code

Terraform, an Infrastructure as Code (IaC) tool, allows you to define and provision your entire observability stack using declarative configuration files. This brings numerous benefits:

  • Version Control: Track changes to your observability setup in Git.
  • Reproducibility: Easily replicate your observability stack across different environments.
  • Automation: Automate the deployment and management of agents, monitors, and alerting configurations.
  • Standardization: Enforce consistent configurations across your organization.

Prerequisites for Your Observability Stack

Before you begin, ensure you have the following:

  • An active AWS Account with administrative permissions.
  • An existing AWS EKS Cluster. This guide assumes you have one; if not, you'll need to provision it separately (e.g., using a dedicated Terraform EKS module).
  • A Datadog Account with API and Application Keys.
  • A PagerDuty Account with a valid API Token and the User ID for an initial contact.
  • Terraform CLI installed (v1.0+ recommended).
  • kubectl installed and configured to access your EKS cluster.
  • AWS CLI installed and configured.

Implementing EKS Observability with Terraform, Datadog, and PagerDuty

This section provides a step-by-step guide to setting up your observability stack using Terraform.

1. Terraform Configuration and Provider Setup

First, define your required providers and configure them with the necessary credentials. We'll use the AWS, Datadog, PagerDuty, Kubernetes, and Helm providers.

2. Deploying the Datadog Agent to EKS

The Datadog Agent is crucial for collecting metrics, logs, and traces from your EKS cluster. We'll deploy it using the official Datadog Helm chart via Terraform's helm_release resource.

For the Kubernetes provider to interact with your EKS cluster, it needs the cluster's endpoint, CA certificate, and a token. We retrieve these dynamically using AWS data sources.

3. Configuring PagerDuty Services and Integrations

Next, we'll define a PagerDuty service, an escalation policy, and a Datadog integration. The integration provides a unique key that Datadog will use to send alerts to PagerDuty.

4. Defining Datadog Monitors and Connecting to PagerDuty

Finally, we'll create Datadog monitors to detect critical issues (e.g., high CPU utilization). The monitor's message will contain a special PagerDuty tag (@pagerduty-YOUR_INTEGRATION_KEY) to route the alert to the correct PagerDuty service.

Copy & Paste: Terraform Configuration for EKS Observability

Save the following content as main.tf, replace the placeholder variables, and run terraform init, terraform plan, and terraform apply.

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
    datadog = {
      source  = "DataDog/datadog"
      version = "~> 3.0"
    }
    pagerduty = {
      source  = "PagerDuty/pagerduty"
      version = "~> 2.0"
    }
    kubernetes = {
      source  = "hashicorp/kubernetes"
      version = "~> 2.23"
    }
    helm = {
      source  = "hashicorp/helm"
      version = "~> 2.11"
    }
  }
}

variable "aws_region" {
  description = "AWS region where your EKS cluster is located"
  type        = string
  default     = "us-east-1"
}

variable "eks_cluster_name" {
  description = "The name of your existing EKS cluster"
  type        = string
  default     = "my-observability-eks-cluster" # <-- CHANGE THIS to your EKS cluster name
}

variable "datadog_api_key" {
  description = "Datadog API Key"
  type        = string
  sensitive   = true
}

variable "datadog_app_key" {
  description = "Datadog Application Key"
  type        = string
  sensitive   = true
}

variable "pagerduty_token" {
  description = "PagerDuty API Token"
  type        = string
  sensitive   = true
}

variable "pagerduty_user_id" {
  description = "The User ID for the initial contact in PagerDuty (e.g., UXXXXXX)"
  type        = string
  default     = "P00XXXX" # <-- CHANGE THIS to a valid PagerDuty user ID
}

provider "aws" {
  region = var.aws_region
}

# --- Kubernetes Provider Configuration (for Helm) ---
data "aws_eks_cluster" "eks_cluster" {
  name = var.eks_cluster_name
}

data "aws_eks_cluster_auth" "eks_cluster_auth" {
  name = var.eks_cluster_name
}

provider "kubernetes" {
  host                   = data.aws_eks_cluster.eks_cluster.endpoint
  cluster_ca_certificate = base64decode(data.aws_eks_cluster.eks_cluster.certificate_authority[0].data)
  token                  = data.aws_eks_cluster_auth.eks_cluster_auth.token
}

provider "helm" {
  kubernetes {
    host                   = data.aws_eks_cluster.eks_cluster.endpoint
    cluster_ca_certificate = base64decode(data.aws_eks_cluster.eks_cluster.certificate_authority[0].data)
    token                  = data.aws_eks_cluster_auth.eks_cluster_auth.token
  }
}

# --- Datadog Provider Configuration ---
provider "datadog" {
  api_key = var.datadog_api_key
  app_key = var.datadog_app_key
}

# --- PagerDuty Provider Configuration ---
provider "pagerduty" {
  token = var.pagerduty_token
}

# --- Deploy Datadog Agent to EKS using Helm ---
resource "helm_release" "datadog_agent" {
  name       = "datadog"
  repository = "https://helm.datadoghq.com"
  chart      = "datadog"
  namespace  = "default" # Consider using a dedicated 'datadog' namespace
  version    = "2.33.0" # Pin to a specific, tested version

  set {
    name   = "datadog.apiKey"
    value  = var.datadog_api_key
    secret = true
  }

  set {
    name   = "datadog.appKey"
    value  = var.datadog_app_key
    secret = true
  }

  # Enable common observability features for EKS
  set { name = "clusterAgent.enabled"; value = "true" }
  set { name = "kubeStateMetricsNetworkPolicy.enabled"; value = "true" }
  set { name = "metricsServer.enabled"; value = "true" }
  set { name = "clusterChecks.enabled"; value = "true" }
  set { name = "logs.enabled"; value = "true" }
  set { name = "logs.containerCollectAll"; value = "true" }
  set { name = "processAgent.enabled"; value = "true" }
  set { name = "apm.enabled"; value = "true" }

  # Add custom tags for filtering and organization in Datadog
  set {
    name  = "tags"
    value = "{environment:production,cluster_name:${var.eks_cluster_name}}"
  }
  set {
    name  = "targetSystem"
    value = "linux"
  }
}

# --- PagerDuty Escalation Policy, Service, and Datadog Integration ---
resource "pagerduty_escalation_policy" "default" {
  name = "EKS Observability Escalation Policy"
  rule {
    delay_in_minutes = 0
    target {
      type = "user"
      id   = var.pagerduty_user_id
    }
  }
}

resource "pagerduty_service" "eks_observability_service" {
  name                     = "AWS EKS Observability Service"
  auto_resolve_timeout     = 14400 # 4 hours (seconds)
  acknowledgement_timeout  = 600   # 10 minutes (seconds)
  escalation_policy        = pagerduty_escalation_policy.default.id
  alert_creation           = "create_alerts_and_incidents"
}

resource "pagerduty_service_integration" "datadog_integration" {
  name        = "Datadog Integration"
  service     = pagerduty_service.eks_observability_service.id
  type        = "generic_events_api_inbound_integration" # This creates an integration key
}

# --- Datadog Monitors ---
resource "datadog_monitor" "high_cpu_utilization" {
  name               = "[EKS] High CPU Utilization on {{host.name}}"
  type               = "metric alert"
  query              = "avg(last_5m):avg:kubernetes.cpu.usage.total{cluster_name:${var.eks_cluster_name}} by {kube_cluster,host} > 80"
  message            = <<EOT
  @pagerduty-${pagerduty_service_integration.datadog_integration.integration_key}
  High CPU utilization detected on {{host.name}} in EKS cluster ${var.eks_cluster_name}.
  Current usage: {{value}}%. Investigate running pods.
  [View in Datadog](https://app.datadoghq.com/metric/explorer?live=true&paused=false&query=kubernetes.cpu.usage.total%7Bcluster_name%3A${var.eks_cluster_name}%7D)
  EOT
  tags               = ["environment:production", "team:devops", "service:eks"]
  priority           = 1 # P1 for critical alerts
  notify_no_data     = false
  renotify_interval  = 0
  no_data_timeframe  = 20
  include_tags       = true
  require_full_window = false
  timeout_h          = 1
  escalation_message = "CPU is still critically high! Please escalate."
}

# Example: Monitor for Pods in Pending state for too long
resource "datadog_monitor" "pending_pods" {
  name               = "[EKS] Pods in Pending State - {{namespace.name}}"
  type               = "metric alert"
  query              = "sum(last_5m):kubernetes.pod.status{cluster_name:${var.eks_cluster_name},status:pending} by {kube_cluster,kube_namespace} > 0"
  message            = <<EOT
  @pagerduty-${pagerduty_service_integration.datadog_integration.integration_key}
  {{value}} pods are in a Pending state in namespace {{kube_namespace.name}} of EKS cluster ${var.eks_cluster_name}.
  This could indicate insufficient resources or scheduling issues.
  [View in Datadog](https://app.datadoghq.com/container/pods?env=production&cluster=${var.eks_cluster_name}&status=Pending)
  EOT
  tags               = ["environment:production", "team:devops", "service:eks"]
  priority           = 2
  notify_no_data     = false
  renotify_interval  = 0
  no_data_timeframe  = 20
  include_tags       = true
  require_full_window = false
  timeout_h          = 1
}

# Output the PagerDuty integration key for reference
output "pagerduty_datadog_integration_key" {
  description = "The integration key for Datadog to send alerts to PagerDuty."
  value       = pagerduty_service_integration.datadog_integration.integration_key
  sensitive   = true
}

output "datadog_agent_helm_release_status" {
  description = "Status of the Datadog Agent Helm release."
  value       = helm_release.datadog_agent.status
}

Instructions for Use:

  1. Save the code above as main.tf in an empty directory.
  2. Create a terraform.tfvars file or set environment variables for:
    
    aws_region        = "us-east-1"
    eks_cluster_name  = "your-eks-cluster-name"
    datadog_api_key   = "your-datadog-api-key"
    datadog_app_key   = "your-datadog-app-key"
    pagerduty_token   = "your-pagerduty-api-token"
    pagerduty_user_id = "P00XXXX" # Find this in PagerDuty under Users -> select user -> Details tab.
                
  3. Initialize Terraform: terraform init
  4. Review the plan: terraform plan
  5. Apply the configuration: terraform apply
  6. Confirm the Datadog Agent pods are running in your EKS cluster: kubectl get pods -n default -l app.kubernetes.io/name=datadog

Conclusion

By leveraging Terraform, Datadog, and PagerDuty, you can establish a robust, automated, and scalable observability and incident response framework for your AWS EKS clusters. This infrastructure-as-code approach ensures consistency, simplifies management, and significantly reduces the mean time to detect and resolve critical issues, allowing your teams to focus on innovation rather than firefighting.

Start implementing this solution today to gain unparalleled insights into your EKS environments and empower your teams with proactive monitoring and efficient incident management.

Comments

Popular posts from this blog

Terraform Configuration for Datadog-PagerDuty Incident Management on AWS EKS

Terraform-Managed AWS EKS Observability and Incident Response with Datadog and PagerDuty

Terraform for Production AWS EKS Observability with Datadog, Prometheus, and PagerDuty Integration