Back to Blog Hub

AWS Security in Depth: GuardDuty, Security Hub, WAF & the Defence-in-Depth Model

May 8, 2026 25 min read Security Ops Architecture

AWS Series | Part 9 — Building secure, cost-optimised, cloud-native infrastructure on AWS

AWS Security Architecture Deep Dive

TL;DR Comparison

Service What It Does Layer Cost Model
AWS WAF Blocks L7 HTTP attacks (SQLi, XSS, bots) Edge / ALB / CloudFront $5/WebACL + $1/rule + $0.60/million requests
AWS Shield Standard DDoS protection for L3/L4 Edge Free
AWS Shield Advanced Enhanced DDoS + 24/7 DRT support Edge $3,000/month
Amazon GuardDuty Threat detection from logs (ML-based) Account-wide Per GB of logs analysed
AWS Security Hub Centralised findings aggregator + compliance Account/Org-wide Per finding ingested
AWS Config Resource configuration compliance Account-wide Per rule evaluation
Amazon Inspector Vulnerability scanning (EC2, ECR, Lambda) Workload Per instance/image scanned
AWS Macie Sensitive data discovery in S3 S3 Per GB scanned

Introduction

In Blog 7 we covered network-level defence — Security Groups, NACLs, and Network Firewall. In Blog 8 we covered identity defence — IAM, SCPs, and OIDC. This post covers the third pillar: detection, response, and application-layer protection.

The reality of cloud security is that prevention is never 100% effective. Misconfigured resources get deployed. Credentials get compromised. Zero-day vulnerabilities appear. The question is not whether something will go wrong — it's how quickly you detect it, how clearly you understand the blast radius, and how fast you can respond.

GuardDuty, Security Hub, WAF, and the surrounding AWS security services answer those questions. Together they form a continuous security posture that detects threats in real time, aggregates findings across your entire organisation, blocks malicious traffic before it reaches your application, and proves compliance to auditors without manual effort.

Every service in this post has working Terraform. The architecture patterns are production-grade and directly applicable to regulated environments like financial services.

1. The Defence-in-Depth Model — All Layers Together

Before diving into individual services, here is the complete layered security architecture that this post builds toward:

Internet
    ↓
[Layer 0]  AWS Shield Advanced          ← DDoS protection (L3/L4)
    ↓
[Layer 1]  AWS WAF                      ← L7 attack filtering (SQLi, XSS, bots)
    ↓
[Layer 2]  CloudFront / ALB             ← TLS termination, geo-restriction
    ↓
[Layer 3]  Network ACL                  ← Subnet-level IP blocking
    ↓
[Layer 4]  AWS Network Firewall         ← Deep packet inspection, IPS, domain filtering
    ↓
[Layer 5]  Security Groups              ← Instance-level, least privilege
    ↓
[Layer 6]  Application (ECS/Lambda)     ← Runtime protection
    ↓
[Layer 7]  Data (S3/RDS/DynamoDB)       ← Encryption, Macie, access logging

Detection & Response (spans all layers):
├── GuardDuty        → Threat detection from CloudTrail, VPC Flow Logs, DNS logs
├── Security Hub     → Aggregates findings from all services + compliance standards
├── Inspector        → Vulnerability scanning of EC2, ECR images, Lambda
├── Macie            → Sensitive data discovery in S3
├── Config           → Configuration compliance and drift detection
└── CloudTrail       → Immutable API audit log for every action in every account

Each layer is independent. A threat that bypasses WAF still hits Network Firewall. A threat that bypasses Network Firewall still hits Security Groups. Detection services observe all layers simultaneously — they don't sit in the traffic path, so they can't be bypassed by routing.

2. AWS WAF — Application Layer Protection

What It Does

AWS WAF (Web Application Firewall) inspects HTTP/HTTPS requests at Layer 7 before they reach your application. It can allow, block, count, or rate-limit requests based on:

  • IP addresses and CIDR ranges
  • Geographic origin (country-level blocking)
  • HTTP headers, URI strings, query parameters, body content
  • SQL injection patterns
  • Cross-site scripting (XSS) signatures
  • Bot signatures and browser fingerprints
  • Request rate (rate-based rules)

WAF integrates with CloudFront, ALB, API Gateway, and AppSync. For most architectures, attach it to CloudFront for the lowest latency inspection — requests are inspected at the edge before they traverse the AWS backbone.

Full WAF Terraform — Production Configuration

# WAF Web ACL — production configuration
resource "aws_wafv2_web_acl" "main" {
  name        = "prod-web-acl"
  description = "Production WAF — blocks L7 attacks, bots, and rate abuse"
  scope       = "CLOUDFRONT"   # or "REGIONAL" for ALB/API GW

  default_action {
    allow {}   # Default: allow — rules below define what to block
  }

  # Rule 1 — AWS Managed Core Rule Set (CRS)
  # Blocks OWASP Top 10 including SQLi, XSS, RCE, LFI
  rule {
    name     = "AWSManagedRulesCommonRuleSet"
    priority = 1

    override_action {
      none {}   # Enforce — don't override to count
    }

    statement {
      managed_rule_group_statement {
        name        = "AWSManagedRulesCommonRuleSet"
        vendor_name = "AWS"

        # Override specific rules to count-only during initial rollout
        rule_action_override {
          name = "SizeRestrictions_BODY"
          action_to_use { count {} }   # Count first, block after validating
        }
      }
    }

    visibility_config {
      cloudwatch_metrics_enabled = true
      metric_name                = "CommonRuleSet"
      sampled_requests_enabled   = true
    }
  }

  # Rule 2 — AWS Managed Known Bad Inputs
  rule {
    name     = "AWSManagedRulesKnownBadInputsRuleSet"
    priority = 2
    override_action { none {} }
    statement {
      managed_rule_group_statement {
        name        = "AWSManagedRulesKnownBadInputsRuleSet"
        vendor_name = "AWS"
      }
    }
    visibility_config {
      cloudwatch_metrics_enabled = true
      metric_name                = "KnownBadInputs"
      sampled_requests_enabled   = true
    }
  }

  # Rule 3 — Bot Control
  rule {
    name     = "AWSManagedRulesBotControlRuleSet"
    priority = 3
    override_action { none {} }
    statement {
      managed_rule_group_statement {
        name        = "AWSManagedRulesBotControlRuleSet"
        vendor_name = "AWS"
        managed_rule_group_configs {
          aws_managed_rules_bot_control_rule_set {
            inspection_level = "TARGETED"   # Deep bot inspection
          }
        }
      }
    }
    visibility_config {
      cloudwatch_metrics_enabled = true
      metric_name                = "BotControl"
      sampled_requests_enabled   = true
    }
  }

  # Rule 4 — Rate Limiting
  rule {
    name     = "RateLimitPerIP"
    priority = 5
    action {
      block {
        custom_response {
          response_code = 429
        }
      }
    }
    statement {
      rate_based_statement {
        limit              = 1000
        aggregate_key_type = "IP"
      }
    }
    visibility_config {
      cloudwatch_metrics_enabled = true
      metric_name                = "RateLimit"
      sampled_requests_enabled   = true
    }
  }

  visibility_config {
    cloudwatch_metrics_enabled = true
    metric_name                = "ProdWebACL"
    sampled_requests_enabled   = true
  }
}

WAF Rollout Strategy — Count Before Block

Never deploy a new WAF rule directly to block mode in production. Use this staged rollout:

  1. Week 1: Deploy all rules in COUNT mode → observe CloudWatch metrics
  2. Week 2: Review sampled requests → identify false positives
  3. Week 3: Move high-confidence rules to BLOCK → keep edge cases in COUNT
  4. Week 4: Tune remaining COUNT rules → move to BLOCK or exclude

3. AWS Shield — DDoS Protection

Shield Standard vs Advanced

Shield Standard is automatically enabled for every AWS account at no cost. It protects against common Layer 3 and Layer 4 DDoS attacks — SYN floods, UDP reflection attacks, and similar volumetric threats.

Shield Advanced adds Layer 7 DDoS protection with automatic WAF rule creation during attacks, 24/7 access to the AWS DDoS Response Team (DRT), and cost protection against abnormal data transfer charges during a DDoS event.

# Shield Advanced — enable and protect resources
resource "aws_shield_protection" "cloudfront" {
  name         = "cloudfront-ddos-protection"
  resource_arn = aws_cloudfront_distribution.main.arn
}
Cost reality: Shield Advanced costs $3,000/month as a flat fee. For smaller organisations, Shield Standard + WAF covers the vast majority of threats.

4. Amazon GuardDuty — Intelligent Threat Detection

How It Works

GuardDuty is a continuous threat detection service that analyses three data sources without any agents required: CloudTrail logs, VPC Flow Logs, and DNS logs.

It uses machine learning and AWS threat intelligence feeds to generate findings — prioritised alerts that describe a specific threat with context about the affected resource.

# Enable GuardDuty in the delegated administrator account
resource "aws_guardduty_detector" "main" {
  enable = true
  datasources {
    s3_logs { enable = true }
    kubernetes { audit_logs { enable = true } }
  }
}

Automated Response — Isolate a Compromised Instance

Always preserve the instance for forensic investigation — do NOT terminate it. Use EventBridge and Lambda to isolate it automatically.

import boto3

def handler(event, context):
    finding = event['detail']
    instance_id = finding['resource']['instanceDetails']['instanceId']
    
    ec2 = boto3.client('ec2')
    # Automated response: isolate instance by replacing its SG
    ec2.modify_instance_attribute(
        InstanceId=instance_id,
        Groups=['sg-quarantine-xxxxxxxx']   # Empty quarantine SG
    )
    print(f"Quarantined instance {instance_id}")

5. AWS Security Hub — Centralised Security Posture

Security Hub is the single pane of glass that aggregates findings from GuardDuty, Inspector, Macie, Config, and IAM Access Analyzer. It also runs automated compliance checks against standards like CIS AWS Foundations and PCI-DSS.

# Enable Security Hub and compliance standards
resource "aws_securityhub_account" "main" {}

resource "aws_securityhub_standards_subscription" "fsbp" {
  standards_arn = "arn:aws:securityhub:eu-west-1::standards/aws-foundational-security-best-practices/v/1.0.0"
}

6. Amazon Inspector — Vulnerability Scanning

Inspector automatically scans your workloads for known CVEs. Use it as a CI/CD Gate: fail your pipeline if Inspector finds CRITICAL vulnerabilities in your container images before they reach production.

# Fail deployment if findings exist
if findings:
    raise Exception(f"Deployment blocked: {len(findings)} CRITICAL vulnerabilities found.")

7. Amazon Macie — Sensitive Data Discovery

Macie uses machine learning to discover and classify sensitive data in your S3 buckets (PII, financial data, etc.). It answers the auditor's question: "Do you know where all your sensitive data is?"

8. AWS Config — Configuration Compliance at Scale

Config records the state of every resource and detects configuration drift. Unlike GuardDuty (threats), Config detects misconfigurations — the root cause of most security incidents.

# Auto-remediate S3 public access violations
resource "aws_config_remediation_configuration" "s3_public_block" {
  config_rule_name = aws_config_config_rule.s3_public_access.name
  target_id         = "AWS-DisableS3BucketPublicReadWrite"
  automatic         = true
}

9. CloudTrail — The Immutable Audit Log

CloudTrail is the foundation of everything. Without it, you have no visibility into who did what. Always use is_multi_region_trail = true and is_organization_trail = true.

10. Architecture Decision Matrix

Threat / Requirement WAF Shield GuardDuty Security Hub Inspector Macie Config
SQL injection / XSS ✅ Primary
DDoS volumetric ✅ Primary
Compromised credentials ✅ Primary ✅ Aggregates
CVE vulnerabilities ✅ Aggregates ✅ Primary
Misconfigured resources ✅ Aggregates ✅ Primary

11. Common Mistakes & Anti-Patterns

Mistake 1: GuardDuty Without Automation

Findings without automation are just logs nobody reads. Always wire findings to EventBridge response workflows.

Mistake 2: WAF in Count Mode Permanently

Count mode is only for rollout. Leaving it on permanently is a false sense of security — it's not blocking anything.

Mistake 3: Single-Region CloudTrail

A single-region trail misses API activity in other regions. Always use multi-region, organisation-wide trails.

Mistake 4: Not Testing Response Pipelines

An incident is not the time to discover your alerting broke. Use create-sample-findings quarterly to test your automation.

The Golden Rule

"Prevention is your first priority — stop threats before they reach your app. But detection is your safety net. Security Hub is the thread that ties every finding together. Treat security tooling costs as insurance — the premium is always less than the claim."

Tags: #AWS #WAF #GuardDuty #SecurityHub #CloudSecurity #DevSecOps

Ankush Panday

Specializing in highly scalable AWS infrastructure and automated quality engineering.

Connect on LinkedIn