Matt Karmazyn

# GuardDuty Threat Detection (Optional)

Enable AI-powered threat detection across your AWS organization.

# When to Enable

# When to Skip


# What is GuardDuty?

GuardDuty uses machine learning to detect threats including:


# Cost Estimate

GuardDuty pricing is based on:

Typical Cost:

For 6 accounts: ~$30-300/month depending on activity level

First 30 days: Free trial for new accounts!


# How It Works

  1. Automatic Enablement: When configured at organization level, GuardDuty automatically enables in all member accounts
  2. Retroactive Coverage: Applies to existing accounts immediately
  3. Future Accounts: Auto-enables in any new accounts added to the organization
  4. No Agent Required: Uses existing AWS logs (CloudTrail, VPC Flow Logs, DNS logs)
  5. Delegated Admin: Security team can manage findings from dedicated Security account

# Implementation

Account Scope: Run in the management account - automatically enables in all member accounts.

# Terraform Configuration

Create terraform/organization/guardduty.tf:

terraform {
  required_version = ">= 1.0"
  
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }

  backend "s3" {
    bucket         = "my-company-terraform-state"
    key            = "management/guardduty/terraform.tfstate"
    region         = "us-east-2"
    dynamodb_table = "terraform-state-lock"
    encrypt        = true
    profile        = "terraform-admin"
  }
}

provider "aws" {
  region  = "us-east-2"
  profile = "terraform-admin"
}

# Enable GuardDuty detector in management account
resource "aws_guardduty_detector" "main" {
  enable = true

  # Enable S3 Protection (monitors S3 data events)
  datasources {
    s3_logs {
      enable = true
    }
    
    # Enable Kubernetes Protection (monitors EKS audit logs)
    kubernetes {
      audit_logs {
        enable = true
      }
    }
    
    # Enable Malware Protection (scans EBS volumes)
    malware_protection {
      scan_ec2_instance_with_findings {
        ebs_volumes {
          enable = true
        }
      }
    }
  }

  tags = {
    Name        = "Organization GuardDuty"
    Environment = "Management"
    ManagedBy   = "Terraform"
  }
}

# Delegate GuardDuty administration to Security account
resource "aws_guardduty_organization_admin_account" "security" {
  admin_account_id = "222222222222"  # Replace with your Security Account ID
}

# Enable GuardDuty organization configuration
# This automatically enables GuardDuty in all current and future member accounts
resource "aws_guardduty_organization_configuration" "main" {
  auto_enable = true
  detector_id = aws_guardduty_detector.main.id

  # Auto-enable S3 Protection in all accounts
  datasources {
    s3_logs {
      auto_enable = true
    }
    
    # Auto-enable Kubernetes Protection in all accounts
    kubernetes {
      audit_logs {
        enable = true
      }
    }
    
    # Auto-enable Malware Protection in all accounts
    malware_protection {
      scan_ec2_instance_with_findings {
        ebs_volumes {
          enable = true
        }
      }
    }
  }

  depends_on = [aws_guardduty_organization_admin_account.security]
}

# Optional: SNS topic for GuardDuty findings
resource "aws_sns_topic" "guardduty_alerts" {
  name = "guardduty-alerts"

  tags = {
    Name        = "GuardDuty Alerts"
    Environment = "Management"
    ManagedBy   = "Terraform"
  }
}

resource "aws_sns_topic_subscription" "guardduty_email" {
  topic_arn = aws_sns_topic.guardduty_alerts.arn
  protocol  = "email"
  endpoint  = "[email protected]"
}

# Optional: EventBridge rule to send high/critical findings to SNS
resource "aws_cloudwatch_event_rule" "guardduty_findings" {
  name        = "guardduty-high-severity-findings"
  description = "Capture GuardDuty findings with HIGH or CRITICAL severity"

  event_pattern = jsonencode({
    source      = ["aws.guardduty"]
    detail-type = ["GuardDuty Finding"]
    detail = {
      severity = [7, 7.0, 7.1, 7.2, 7.3, 7.4, 7.5, 7.6, 7.7, 7.8, 7.9,
                  8, 8.0, 8.1, 8.2, 8.3, 8.4, 8.5, 8.6, 8.7, 8.8, 8.9]
    }
  })
}

resource "aws_cloudwatch_event_target" "guardduty_sns" {
  rule      = aws_cloudwatch_event_rule.guardduty_findings.name
  target_id = "SendToSNS"
  arn       = aws_sns_topic.guardduty_alerts.arn
}

resource "aws_sns_topic_policy" "guardduty_publish" {
  arn = aws_sns_topic.guardduty_alerts.arn

  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Effect = "Allow"
        Principal = {
          Service = "events.amazonaws.com"
        }
        Action   = "SNS:Publish"
        Resource = aws_sns_topic.guardduty_alerts.arn
      }
    ]
  })
}

# Apply Configuration

cd terraform/organization
terraform init
terraform plan
terraform apply

# What You Get

Organization-Wide Protection: Automatically monitors all current and future member accounts
AI-Powered Threat Detection: Machine learning identifies suspicious activity
S3 Protection: Monitors S3 data events for unusual access patterns
Kubernetes Protection: Analyzes EKS audit logs for threats
Malware Protection: Scans EBS volumes when threats are detected
Centralized Management: Security team views findings from dedicated Security account
Real-Time Alerts: Notifications for high/critical severity findings


# Validation

# Verify GuardDuty is enabled in management account
aws guardduty list-detectors --profile terraform-admin

# Check detector status
DETECTOR_ID=$(aws guardduty list-detectors --query 'DetectorIds[0]' --output text --profile terraform-admin)
aws guardduty get-detector --detector-id $DETECTOR_ID --profile terraform-admin

# Verify organization configuration
aws guardduty describe-organization-configuration --detector-id $DETECTOR_ID --profile terraform-admin

# List member accounts (should show all member accounts auto-enrolled)
aws guardduty list-members --detector-id $DETECTOR_ID --profile terraform-admin

Expected outputs:


# Understanding Findings

GuardDuty findings are categorized by:

# Severity Levels

# Common Finding Types

Finding Description Action
UnauthorizedAccess:IAMUser/InstanceCredentialExfiltration Credentials used outside AWS Rotate keys immediately
CryptoCurrency:EC2/BitcoinTool.B!DNS EC2 mining cryptocurrency Terminate instance
Recon:IAMUser/MaliciousIPCaller API calls from known threat IP Block IP, rotate credentials
Trojan:EC2/DriveBySourceTraffic!DNS EC2 communicating with malware C&C Isolate instance, investigate
UnauthorizedAccess:S3/MaliciousIPCaller S3 access from threat actor IP Review S3 permissions

# Integration with Other Tools

GuardDuty findings can be sent to:


# Cost Optimization Tips

  1. Start with Free Trial: 30 days free for new accounts
  2. Disable Unused Features: Turn off S3 or Kubernetes protection if not needed
  3. Filter Low-Severity Findings: Focus alerts on HIGH/CRITICAL only
  4. Suppress Known False Positives: Create suppression rules for recurring non-threats
  5. Monitor Usage: Check GuardDuty cost in Cost Explorer monthly

# Troubleshooting

# GuardDuty not enabled in member account

# Verify organization configuration
aws guardduty describe-organization-configuration --detector-id $DETECTOR_ID

# Check if auto-enable is true
# If false, manually enable in member accounts or fix organization config

# High costs

# Check which data source is generating most events
aws guardduty get-usage-statistics --detector-id $DETECTOR_ID \
  --usage-statistic-type SUM_BY_DATA_SOURCE \
  --usage-criteria "DataSources={}"

# Consider disabling expensive data sources if not needed

# Missing findings

# Verify detector is enabled and healthy
aws guardduty get-detector --detector-id $DETECTOR_ID

# Check if CloudTrail is enabled (GuardDuty needs it)
aws cloudtrail describe-trails

← CloudTrail Security Hub →