Automating AWS EKS Observability with Terraform, Datadog, and PagerDuty Incident Management

Architecture Pro-Tip:

Always adopt an "Infrastructure as Code First" approach. Managing your observability stack with Terraform ensures consistent, repeatable, and version-controlled deployments, drastically reducing configuration drift and accelerating incident response by providing a clear audit trail of your monitoring setup.

Automating AWS EKS Observability with Terraform, Datadog, and PagerDuty Incident Management

In today's fast-paced cloud-native environments, ensuring robust observability of your Amazon Elastic Kubernetes Service (EKS) clusters is paramount. Manual configuration is prone to errors, slow, and unsustainable at scale. This comprehensive technical guide walks you through automating your EKS observability stack using Terraform for infrastructure as code, Datadog for comprehensive monitoring and alerting, and PagerDuty for streamlined incident management. By the end, you'll have a fully automated, end-to-end observability pipeline that enhances reliability and reduces Mean Time To Resolution (MTTR).

Why Automate EKS Observability?

The dynamic nature of Kubernetes clusters, especially EKS, makes traditional monitoring approaches inadequate. Automation offers significant advantages:

Consistency and Repeatability

Terraform ensures that your observability agents, monitors, and incident response configurations are deployed identically across all your EKS environments, from development to production. This eliminates configuration drift and reduces "it works on my machine" scenarios.

Faster Mean Time To Resolution (MTTR)

Automated monitoring with Datadog quickly identifies issues, while PagerDuty's automated incident routing ensures the right team is notified immediately. This drastically cuts down the time from detection to resolution.

Proactive Problem Detection

With Datadog's extensive integrations and machine learning capabilities, you can move beyond reactive alerting to proactive anomaly detection, often identifying potential problems before they impact users.

Scalability and Efficiency

As your EKS clusters grow, manually managing observability becomes a bottleneck. Terraform allows you to scale your monitoring infrastructure with your application infrastructure seamlessly, without additional manual effort.

Core Components Overview

This guide leverages three powerful tools to build a robust EKS observability pipeline.

Terraform: Infrastructure as Code (IaC)

Terraform is an open-source IaC tool by HashiCorp that allows you to define and provision infrastructure using a declarative configuration language. We'll use it to provision Datadog agents on EKS, configure Datadog monitors, and set up PagerDuty services and escalation policies.

Datadog: Monitoring, Tracing, and Logging

Datadog is a leading monitoring and analytics platform for cloud-scale applications. It provides comprehensive visibility across your EKS clusters by collecting metrics, logs, and traces, offering real-time dashboards, powerful alerting, and AI-driven anomaly detection.

PagerDuty: Incident Management

PagerDuty is an incident management platform that integrates with monitoring systems to route alerts to the right on-call personnel, manage incident lifecycles, and facilitate collaboration. It turns Datadog alerts into actionable incidents.

Prerequisites

Before diving into the configuration, ensure you have the following in place:

  • AWS Account with EKS Cluster: An existing EKS cluster where you want to deploy the Datadog Agent.
  • Datadog Account: With API and Application keys. You can find these under Organization Settings > API Keys.
  • PagerDuty Account: With an API token. Generate one under Integrations > API Access Keys. You'll also need a User ID for escalation policies.
  • Terraform Installed: Version 1.0 or newer.
  • aws-cli & kubectl Installed: Configured to connect to your EKS cluster. Terraform will use these to interact with AWS and Kubernetes.
  • Helm Installed: Terraform will use the Helm provider to deploy the Datadog Agent chart.

Step-by-Step Implementation Guide

Step 1: Setting up Datadog for EKS

This involves deploying the Datadog Agent to your EKS cluster and configuring monitors to alert on critical metrics.

  • Datadog Agent: The agent collects metrics, logs, and traces from your Kubernetes nodes, pods, and applications. We'll deploy it using the official Datadog Helm chart via Terraform.
  • Datadog Monitors: These are the rules that define what conditions constitute an alert (e.g., high CPU, low memory, pod restarts).

Step 2: Integrating Datadog with PagerDuty

For critical alerts, we need to escalate them to the on-call team using PagerDuty.

  • PagerDuty Escalation Policy: Defines the sequence of users or teams to be notified when an incident occurs.
  • PagerDuty Service: Represents a component or application that PagerDuty monitors. Datadog will integrate with this service.
  • Datadog PagerDuty Integration: Connects your Datadog monitors to your PagerDuty service, ensuring alerts are automatically converted into incidents.

Step 3: Deploying EKS Observability with Terraform

We'll consolidate all configurations into a single Terraform project. This involves setting up providers, defining resources for Datadog and PagerDuty, and linking them.

Copy & Paste: Your Automated Observability Stack

Here's a simplified, yet comprehensive, Terraform configuration to get you started. Create these files in a directory, replace placeholder values (`YOUR_...` or similar comments) with your actual API keys, EKS cluster name, and desired configurations.


// providers.tf
terraform {
  required_providers {
    datadog = {
      source  = "DataDog/datadog"
      version = "~> 3.0"
    }
    pagerduty = {
      source  = "PagerDuty/pagerduty"
      version = "~> 1.0"
    }
    helm = {
      source  = "hashicorp/helm"
      version = "~> 2.0"
    }
    kubernetes = {
      source  = "hashicorp/kubernetes"
      version = "~> 2.0"
    }
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
}

provider datadog {
  api_key = var.datadog_api_key
  app_key = var.datadog_app_key
  api_url = var.datadog_api_url // e.g., "https://api.datadoghq.com/" or "https://api.eu.datadoghq.com/"
}

provider pagerduty {
  token = var.pagerduty_auth_token
}

// Configure Kubernetes provider to connect to your EKS cluster
data aws_eks_cluster cluster {
  name = var.eks_cluster_name
}

data aws_eks_cluster_auth cluster_auth {
  name = var.eks_cluster_name
}

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

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

// main.tf

// 1. PagerDuty Escalation Policy
resource pagerduty_escalation_policy eks_observability_policy {
  name      = "EKS Observability Escalation Policy"
  num_loops = 2
  rule {
    delay = 5 // minutes
    target {
      type = "user"
      id   = var.pagerduty_primary_oncall_user_id // Replace with a valid PagerDuty user ID (e.g., PLK0T4S)
    }
    target {
      type = "schedule"
      id   = var.pagerduty_secondary_oncall_schedule_id // Optional: replace with a valid PagerDuty schedule ID
    }
  }
}

// 2. PagerDuty Service for EKS Observability
resource pagerduty_service eks_observability_service {
  name                    = "AWS EKS Observability Service - ${var.environment}"
  auto_resolve_timeout    = 14400 // 4 hours in seconds
  acknowledgement_timeout = 600   // 10 minutes in seconds
  escalation_policy       = pagerduty_escalation_policy.eks_observability_policy.id
  alert_creation          = "create_incidents_and_alerts"
}

// 3. Datadog PagerDuty Integration
resource datadog_integration_pagerduty main_pagerduty_integration {
  api_token = var.pagerduty_auth_token // Use the global API token here for the integration itself
  services = [
    {
      service_key = pagerduty_service.eks_observability_service.integration[0].integration_key
      service_name = pagerduty_service.eks_observability_service.name
    },
  ]
}

// 4. Datadog Agent Deployment on EKS via Helm
resource helm_release datadog_agent {
  name             = "datadog-agent"
  repository       = "https://helm.datadoghq.com"
  chart            = "datadog"
  namespace        = "datadog"
  create_namespace = true

  set {
    name  = "datadog.apiKey"
    value = var.datadog_api_key
    sensitive = true
  }
  set {
    name  = "datadog.appKey"
    value = var.datadog_app_key
    sensitive = true
  }
  set {
    name  = "datadog.site"
    value = var.datadog_site // e.g., "datadoghq.com" or "eu.datadoghq.com"
  }
  set {
    name  = "kubeStateMetricsCore.enabled"
    value = true
  }
  set {
    name  = "clusterAgent.enabled"
    value = true
  }
  set {
    name  = "logs.enabled"
    value = true
  }
  set {
    name  = "processAgent.enabled"
    value = true
  }
  set {
    name  = "containerRuntime.containerd.enabled" // Adjust based on your EKS runtime (containerd or docker)
    value = true
  }
  set {
    name  = "clusterName"
    value = var.eks_cluster_name
  }
  set {
    name  = "datadog.env.DD_KUBERNETES_KUBELET_HOST"
    value = "$(NODE_IP)"
  }
}

// 5. Datadog Monitor for high EKS CPU usage
resource datadog_monitor eks_cpu_alert {
  name    = "EKS Cluster CPU Usage High (${var.eks_cluster_name}) - ${var.environment}"
  type    = "metric alert"
  query   = "avg(last_5m):sum:kubernetes.cpu.usage.total{cluster_name:${var.eks_cluster_name}} by {pod_name} > 80"
  message = "High CPU usage detected in EKS cluster ${var.eks_cluster_name} (${var.environment}). Pod: {{`{{pod_name.name}}`}} is at {{`{{value}}`}}%.\n\n@pagerduty-${datadog_integration_pagerduty.main_pagerduty_integration.services[0].service_name}"
  tags    = ["environment:${var.environment}", "eks-observability", "critical", "service:eks-control-plane"]
  priority = 1 // 1 = highest, 5 = lowest
  thresholds {
    critical = 80
    warning  = 70
  }
  notify_no_data = false
  new_group_delay = 60 // In seconds, to debounce alerts
  renotify_interval = 0 // Do not renotify after initial alert, PagerDuty manages follow-ups
}

// variables.tf
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 datadog_api_url {
  description = "Datadog API URL (e.g., https://api.datadoghq.com/ or https://api.eu.datadoghq.com/)"
  type        = string
  default     = "https://api.datadoghq.com/"
}

variable datadog_site {
  description = "Datadog Site (e.g., datadoghq.com or eu.datadoghq.com)"
  type        = string
  default     = "datadoghq.com"
}

variable pagerduty_auth_token {
  description = "PagerDuty API token (for general API access, not just integration keys)"
  type        = string
  sensitive   = true
}

variable pagerduty_primary_oncall_user_id {
  description = "ID of a PagerDuty user to be the primary on-call in the escalation policy. Find this in PagerDuty UI under 'Users' -> click user -> copy ID from URL."
  type        = string
}

variable pagerduty_secondary_oncall_schedule_id {
  description = "Optional: ID of a PagerDuty schedule for secondary escalation. Find this in PagerDuty UI under 'Schedules' -> click schedule -> copy ID from URL."
  type        = string
  default     = "" // Set to an actual ID if you want a secondary schedule
}

variable eks_cluster_name {
  description = "The name of the EKS cluster to monitor."
  type        = string
}

variable environment {
  description = "The environment name (e.g., dev, staging, prod) for tagging and naming."
  type        = string
  default     = "development"
}

// outputs.tf
output pagerduty_service_url {
  description = "URL to the created PagerDuty Service"
  value       = pagerduty_service.eks_observability_service.html_url
}

output datadog_monitor_url {
  description = "URL to the created Datadog Monitor"
  value       = datadog_monitor.eks_cpu_alert.monitor_url
}
        

To deploy this configuration:

  1. Save the code blocks into providers.tf, main.tf, variables.tf, and outputs.tf files in a new directory.
  2. Set your environment variables for sensitive data or use a terraform.tfvars file:
    export TF_VAR_datadog_api_key="YOUR_DATADOG_API_KEY"
    export TF_VAR_datadog_app_key="YOUR_DATADOG_APP_KEY"
    export TF_VAR_pagerduty_auth_token="YOUR_PAGERDUTY_API_TOKEN"
    export TF_VAR_pagerduty_primary_oncall_user_id="YOUR_PD_USER_ID"
    export TF_VAR_eks_cluster_name="your-eks-cluster-name"
    export TF_VAR_environment="production"
  3. Initialize Terraform: terraform init
  4. Review the plan: terraform plan
  5. Apply the changes: terraform apply (and type yes when prompted)

Testing Your Setup

After successful deployment, verify that everything is working as expected:

  • Datadog Agent: In your Datadog account, navigate to Infrastructure > Hosts or Kubernetes > Clusters. You should see your EKS nodes and pods reporting data.
  • Datadog Monitors: Go to Monitors > Monitor Status. Your newly created EKS CPU monitor should be listed.
  • PagerDuty Service: In PagerDuty, navigate to Services > Service Directory. Your "AWS EKS Observability Service" should appear.
  • Simulate an Incident: To trigger an alert, you might intentionally create a high CPU load on a pod in your EKS cluster (e.g., using a tool like stress-ng). Observe if the Datadog monitor triggers and if PagerDuty creates an incident and notifies the on-call person.

Advanced Considerations & Best Practices

Comprehensive Tagging Strategy

Implement consistent tagging across AWS resources, EKS workloads, Datadog metrics/logs, and PagerDuty services. Tags like environment, service, team, and owner are crucial for filtering, correlating data, and routing incidents effectively. Terraform allows you to inject these tags programmatically.

Custom Metrics and Logs

Beyond default Kubernetes metrics, configure Datadog to collect custom application metrics and structured logs. This provides deeper insights into your specific application performance and behavior. Utilize Datadog's APM for tracing application requests across your EKS services.

Granular Alerting and Escalation

As your system matures, refine your Datadog monitors with more specific queries and thresholds. Create multiple PagerDuty services and escalation policies for different levels of criticality and different teams (e.g., separate policies for application teams vs. infrastructure teams).

Automated Runbooks and Remediation

Integrate PagerDuty with automation tools to trigger automatic remediation steps or provide contextual runbook links directly within the incident. This further accelerates MTTR.

SLOs and Dashboards

Define Service Level Objectives (SLOs) in Datadog and build comprehensive dashboards to visualize the health and performance of your EKS cluster and applications. This provides a holistic view for operational teams.

GitOps Integration

For a truly automated workflow, integrate your Terraform configurations into a GitOps pipeline (e.g., using Argo CD or Flux CD for Kubernetes resources, and a CI/CD tool for Terraform). This ensures that all changes to your observability stack are reviewed, tested, and deployed in a controlled manner.

Conclusion

Automating AWS EKS observability with Terraform, Datadog, and PagerDuty is a game-changer for maintaining high-performing, reliable cloud-native applications. By codifying your monitoring and incident management, you gain consistency, reduce operational overhead, and empower your teams to respond to issues with unprecedented speed and accuracy. Embrace this automated approach to build a resilient and observable EKS environment, driving better outcomes for your applications and end-users.

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