Introduction

Modern cloud applications need scalability, observability, and automation. Manually deploying infrastructure is outdated; instead, we use Infrastructure as Code (IaC) for reproducibility and monitoring tools to keep track of application health.

In this blog, we’ll build and deploy a FastAPI microservice on Amazon EKS (Elastic Kubernetes Service) using Terraform, while integrating Datadog APM (Application Performance Monitoring) for real-time tracing and insights.


Why This Stack?

  • FastAPI – A lightweight, high-performance web framework for APIs.
  • EKS (Elastic Kubernetes Service) ☁️ – Managed Kubernetes for deploying containerized workloads.
  • Terraform 🏗️ – Automates infrastructure provisioning using declarative code.
  • Datadog 🐶 – Provides monitoring, logging, and distributed tracing for better observability.

Project Overview

The project is structured as follows:

eks-datadog-tracing/
│── .gitignore              # Git ignore file
│── .terraform.lock.hcl     # Terraform lock file
│── main.tf                 # Main Terraform configuration
│── outputs.tf              # Terraform outputs
│── providers.tf            # Terraform providers setup
│── README.md               # Project documentation
│── terraform.tfvars        # Terraform variable values
│── variables.tf            # Terraform variables
│
├── app/                    # Application source code
│   ├── Dockerfile          # Docker configuration for the application
│   ├── main.py             # FastAPI application source code
│   ├── requirements.txt    # Dependencies for the application
│
└── modules/                # Modular Terraform configurations
    ├── application/        # Application-specific module
    │   ├── main.tf         # Terraform configuration for the application module
    │   ├── outputs.tf      # Outputs for the application module
    │   ├── ReadMe.md       # Documentation for the module
    │   ├── variables.tf    # Variables for the module
    │
    ├── datadog/            # Datadog monitoring and logging module
    │   ├── datadog.tf      # Datadog configuration
    │   ├── datadog_dashboard.tf  # Datadog dashboards setup
    │   ├── datadog_metric.tf     # Datadog metrics configuration
    │   ├── outputs.tf      # Outputs for the Datadog module
    │   ├── variables.tf    # Variables for the Datadog module
    │
    ├── eks/                # EKS cluster module
    │   ├── main.tf         # Terraform configuration for EKS
    │   ├── outputs.tf      # Outputs for the EKS module
    │   ├── variables.tf    # Variables for the EKS module
    │
    ├── vpc/                # VPC networking module
    │   ├── main.tf         # Terraform configuration for VPC
    │   ├── outputs.tf      # Outputs for the VPC module
    │   ├── variables.tf    # Variables for the VPC module

How It Works

Terraform provisions an EKS cluster and networking infrastructure.
The FastAPI application is containerized with Docker and deployed to EKS.
Datadog APM is integrated to collect real-time traces and metrics.
Observability is improved with Datadog dashboards, metrics, and alerts.

Building the Infrastructure with Terraform
1️⃣ Provisioning the VPC
The VPC module creates the necessary networking resources

module "vpc" {
  source               = "./modules/vpc"
  vpc_name            = var.vpc_name
  vpc_cidr_block      = var.vpc_cidr_block
  vpc_private_subnets = var.vpc_private_subnets
  vpc_public_subnets  = var.vpc_public_subnets
}

2️⃣ Deploying the EKS Cluster
We use the EKS module to create a Kubernetes cluster:

module "eks" {
  source = "./modules/eks"

  k8s_name          = var.k8s_name
  vpc_id            = module.vpc.vpc_id
  subnet_ids        = module.vpc.private_subnet_ids
  cluster_version   = "1.24"
}

Run Terraform commands to deploy:

terraform init
terraform apply -auto-approve

Once completed, EKS is ready to deploy our FastAPI app.

Deploying the FastAPI App on EKS
1️⃣ Writing the FastAPI Application
Our FastAPI app (app/main.py) exposes several endpoints:

from fastapi import FastAPI
import time
import random
from ddtrace import tracer

app = FastAPI()

@tracer.wrap()
@app.get("/")
def hello():
    return {"message": "Hello, World!"}

@tracer.wrap()
@app.get("/slow")
def slow_function():
    time.sleep(2)
    return {"message": "This function is slow!"}

@tracer.wrap()
@app.get("/cpu-intensive")
def cpu_intensive():
    total = sum(i * i for i in range(10**6))
    return {"message": "CPU-intensive task completed!"}

2️⃣ Containerizing the Application
We package our app with a Dockerfile:

FROM python:3.9
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "80"]

Build and push the image to a container registry:

docker build -t your-docker-repo/fastapi-app:latest .
docker push your-docker-repo/fastapi-app:latest

3️⃣ Deploying to Kubernetes
Create a Kubernetes deployment file (k8s/deployment.yaml):

apiVersion: apps/v1
kind: Deployment
metadata:
  name: fastapi-app
spec:
  replicas: 2
  selector:
    matchLabels:
      app: fastapi
  template:
    metadata:
      labels:
        app: fastapi
    spec:
      containers:
        - name: fastapi
          image: your-docker-repo/fastapi-app:latest
          ports:
            - containerPort: 80

Apply the deployment:

kubectl apply -f k8s/deployment.yaml

Monitoring with Datadog
1️⃣ Setting Up Datadog APM
We configure Datadog in main.py:

from ddtrace import tracer
tracer.configure(
    hostname="datadog-agent.datadog",
    port=8126
)

2️⃣ Enabling Logs and Metrics
We define Datadog metrics in Terraform:

resource "datadog_monitor" "high_latency" {
  name    = "High Latency Alert"
  type    = "query alert"
  query   = "avg(last_5m):avg:trace.http.request.duration{service:fastapi-app} > 500"
  message = "Alert! API response time is too high!"
}

3️⃣ Viewing Metrics
Once deployed, log in to Datadog and navigate to:

APM > Services – View real-time traces.
Metrics > Dashboards – Monitor CPU, latency, and traffic.

Testing the API
To check if everything is running:

# Basic "Hello World"
curl http://your-app-url/

# Simulate slow responses
curl http://your-app-url/slow
curl http://your-app-url/random-delay

# Heavy load endpoints
curl http://your-app-url/cpu-intensive

You can also view Swagger UI:

http://your-app-url/docs

Conclusion
By following this setup, we successfully:
✅ Deployed FastAPI as a microservice
✅ Used Terraform to provision EKS and infrastructure
✅ Integrated Datadog for tracing, logging, and monitoring

This approach ensures scalability, observability, and automation, making it ideal for production environments.

If you're interested in extending this, you can:

Add autoscaling policies for Kubernetes pods
Implement Datadog alerts for anomaly detection
Enable log aggregation using Fluentd
feel free to contribute!