AWS WAFAWS Firewall ManagerKinesis Data FirehoseCentralized LoggingMulti-AccountAthenaS3 Access Points

How to Centralize AWS WAF Logs Across Multiple AWS Organizations and Accounts

A comprehensive technical guide to centralizing AWS WAF logs across multiple AWS Organizations and accounts using AWS Firewall Manager, Kinesis Data Firehose, and a dedicated logging account following AWS best practices.

Cloudignyte

·7 min read

Overview

Centralizing AWS WAF logs across multiple AWS Organizations and accounts is essential for maintaining security visibility, reducing costs, and enabling efficient threat analysis at scale. This guide provides a step-by-step approach to implementing centralized WAF logging following AWS best practices.

Why Centralize WAF Logs?

Operational Benefits:

  • Single pane of glass for security analysis across all accounts
  • Reduced investigation time from hours to minutes
  • Consistent log retention and lifecycle policies
  • Simplified compliance reporting

Cost Benefits:

  • Eliminate duplicate logging infrastructure
  • Reduce CloudWatch Logs costs by 90%+ by writing directly to S3
  • Optimize storage with lifecycle policies
  • Predictable, scalable cost model

Security Benefits:

  • Organization-wide threat visibility
  • Cross-account attack pattern detection
  • Centralized access control
  • Immutable audit trail

Architecture Overview

The solution uses a three-account architecture following AWS best practices:

  1. Client Accounts: Where WAF Web ACLs protect CloudFront distributions and other resources
  2. Tooling Account: Hosts AWS Firewall Manager and Kinesis Data Firehose for log transformation
  3. Logging Account: Dedicated account for centralized log storage, Glue Data Catalog, and Athena

Data Flow

Client Accounts (WAF Web ACLs)
        ↓ WAF Logs
Tooling Account (Kinesis Data Firehose → Transform)
        ↓ Transformed Logs
Logging Account (S3 → Glue → Athena)
        ↓ S3 Access Points
Client Accounts (Account-level log access)

Prerequisites

Before implementing this solution, ensure you have:

  • AWS Organizations set up with multiple accounts
  • Administrative access to the management account
  • A dedicated Tooling account for centralized management
  • A dedicated Logging account for log storage
  • Terraform for infrastructure as code
  • Understanding of IAM cross-account permissions

Step 1: Set Up AWS Firewall Manager in Tooling Account

AWS Firewall Manager provides centralized management of WAF policies across accounts and Organizations.

Key Configuration:

  • Deploy FMS in the Tooling account using Terraform
  • Enable FMS as the delegated administrator in AWS Organizations
  • Create shared WAF RuleGroups for consistent protection
  • Configure FMS policies to deploy WAF Web ACLs to target accounts

Benefits:

  • Automatic WAF deployment to new accounts
  • Consistent rule enforcement across all accounts
  • Centralized policy management with version control
  • Infrastructure as code for auditability

Step 2: Configure WAF Logging to Kinesis Data Firehose

Configure all WAF Web ACLs to send logs to Kinesis Data Firehose in the Tooling account.

Why Kinesis Data Firehose?

  • Enables log transformation before storage
  • Buffers and batches logs for efficient S3 writes
  • Supports cross-account delivery
  • Significantly cheaper than CloudWatch Logs

Configuration Steps:

  1. Create Kinesis Data Firehose delivery stream in Tooling account
  2. Configure WAF Web ACLs to log to the Firehose stream
  3. Set up log transformation for enrichment and optimization
  4. Configure buffering and compression settings (GZIP recommended)

Cost Savings: Switching from CloudWatch Logs to S3 via Kinesis can save $20,000+ per month for high-volume environments.

Step 3: Set Up Dedicated Logging Account

Following AWS best practices, use a dedicated account for centralized log storage.

S3 Bucket Configuration

  • Create central S3 bucket for WAF logs
  • Enable versioning and encryption (AWS KMS)
  • Configure lifecycle policies for cost optimization
  • Set up bucket policies for cross-account access from Kinesis

S3 Access Points

  • Create S3 Access Points for each client account
  • Enable account-level log access control
  • Simplify IAM permissions management
  • Provide secure, isolated access to account-specific logs

AWS Glue Data Catalog

  • Create Glue database for WAF logs
  • Define table schema matching WAF log format
  • Configure projected partitioning (no crawlers needed)
  • Enable automatic partition discovery

Amazon Athena

  • Set up Athena workgroup in Logging account
  • Configure query result location
  • Create saved queries for common investigations
  • Set up query cost controls

Step 4: Configure Cross-Account Permissions

Proper IAM configuration is critical for secure cross-account log delivery.

Kinesis Data Firehose Role (Tooling Account):

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": ["s3:PutObject", "s3:PutObjectAcl"],
      "Resource": "arn:aws:s3:::logging-account-waf-logs/*"
    }
  ]
}

S3 Bucket Policy (Logging Account):

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowKinesisFromToolingAccount",
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::TOOLING-ACCOUNT-ID:role/KinesisFirehoseRole"
      },
      "Action": ["s3:PutObject", "s3:PutObjectAcl"],
      "Resource": "arn:aws:s3:::logging-account-waf-logs/*"
    }
  ]
}

S3 Access Point Policy (Per Client Account):

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::CLIENT-ACCOUNT-ID:root"
      },
      "Action": ["s3:GetObject", "s3:ListBucket"],
      "Resource": [
        "arn:aws:s3:REGION:LOGGING-ACCOUNT-ID:accesspoint/client-ap/*",
        "arn:aws:s3:REGION:LOGGING-ACCOUNT-ID:accesspoint/client-ap"
      ],
      "Condition": {
        "StringLike": {
          "s3:prefix": "CLIENT-ACCOUNT-ID/*"
        }
      }
    }
  ]
}

Step 5: Implement Projected Partitioning for Athena

Projected partitioning eliminates the need for Glue Crawlers and enables instant partition discovery.

Athena Table Definition:

CREATE EXTERNAL TABLE waf_logs (
  timestamp bigint,
  formatversion int,
  webaclid string,
  terminatingruleid string,
  terminatingruletype string,
  action string,
  httpsourcename string,
  httpsourceid string,
  rulegrouplist array<struct<...>>,
  httprequest struct<...>
)
PARTITIONED BY (
  account string,
  region string,
  year string,
  month string,
  day string
)
ROW FORMAT SERDE 'org.openx.data.jsonserde.JsonSerDe'
LOCATION 's3://logging-account-waf-logs/'
TBLPROPERTIES (
  'projection.enabled' = 'true',
  'projection.account.type' = 'enum',
  'projection.account.values' = '111111111111,222222222222',
  'projection.region.type' = 'enum',
  'projection.region.values' = 'us-east-1,eu-west-1,eu-west-2',
  'projection.year.type' = 'integer',
  'projection.year.range' = '2024,2030',
  'projection.month.type' = 'integer',
  'projection.month.range' = '1,12',
  'projection.month.digits' = '2',
  'projection.day.type' = 'integer',
  'projection.day.range' = '1,31',
  'projection.day.digits' = '2',
  'storage.location.template' =
    's3://logging-account-waf-logs/${account}/${region}/${year}/${month}/${day}'
);

Benefits of Projected Partitioning:

  • No Glue Crawlers required (eliminates operational overhead and cost)
  • Instant partition discovery
  • Faster query performance
  • Lower costs

Step 6: Create Athena Query Library

Build a library of common queries for security investigations.

Top Blocked IP Addresses:

SELECT
  httprequest.clientip AS client_ip,
  COUNT(*) AS block_count
FROM waf_logs
WHERE action = 'BLOCK'
  AND year = '2026' AND month = '03'
GROUP BY httprequest.clientip
ORDER BY block_count DESC
LIMIT 100;

Rule Effectiveness Analysis:

SELECT
  terminatingruleid,
  terminatingruletype,
  action,
  COUNT(*) AS hit_count
FROM waf_logs
WHERE year = '2026' AND month = '03'
GROUP BY terminatingruleid, terminatingruletype, action
ORDER BY hit_count DESC;

Geographic Traffic Distribution:

SELECT
  httprequest.country AS country,
  action,
  COUNT(*) AS request_count
FROM waf_logs
WHERE year = '2026' AND month = '03'
GROUP BY httprequest.country, action
ORDER BY request_count DESC;

Account-Specific Investigation:

SELECT
  timestamp,
  httprequest.clientip,
  httprequest.uri,
  action,
  terminatingruleid
FROM waf_logs
WHERE account = '111111111111'
  AND year = '2026' AND month = '03' AND day = '01'
  AND action = 'BLOCK'
ORDER BY timestamp DESC;

Multi-Organization Considerations

When working across multiple AWS Organizations:

  1. Separate Firewall Manager Instances: Deploy FMS in each Organization's Tooling account, all sending logs to the same central Logging account
  2. Cross-Organization IAM: Use IAM roles with trust relationships across Organizations, implement least-privilege access
  3. Log Segregation: Use S3 prefixes to separate logs by Organization, create separate S3 Access Points per Organization
  4. Cost Allocation: Use S3 bucket tagging for cost tracking per Organization

Best Practices

Security:

  • Enable S3 bucket encryption with AWS KMS
  • Use separate KMS keys per Organization for isolation
  • Enable S3 Object Lock for compliance requirements
  • Implement least-privilege IAM policies
  • Use S3 Access Points for fine-grained access control

Cost Optimization:

  • Implement S3 lifecycle policies (transition to Glacier after 90 days)
  • Enable Kinesis Data Firehose compression (GZIP)
  • Set appropriate Kinesis buffer sizes (5 MB / 300 seconds)
  • Use Athena query result caching
  • Partition data by account, region, and date

Operational Excellence:

  • Use Infrastructure as Code (Terraform)
  • Create runbooks for common scenarios
  • Set up automated alerting for log delivery failures
  • Monitor Kinesis Data Firehose metrics
  • Document query patterns and use cases

Common Challenges and Solutions

ChallengeSolution
High log volumeImplement sampling, use Kinesis buffering, enable compression
Cross-account permission errorsUse CloudTrail to debug IAM denials, validate trust relationships
Query performanceAlways use partition filters, limit date ranges, use projected partitioning
Cost managementImplement lifecycle policies, use S3 Intelligent-Tiering, set Athena query limits

Results

Organizations implementing this architecture typically achieve:

  • 85% reduction in security noise requiring investigation
  • $20,000+ per month savings by switching from CloudWatch Logs to S3
  • Investigation time reduced from hours to minutes
  • Consistent security controls across all accounts and Organizations

Need Help?

Cloudignyte specializes in implementing centralized AWS security logging solutions across complex multi-account and multi-organization environments. We've helped organizations manage 2,500+ AWS accounts and reduce logging costs by $20,000+ per month while improving security visibility.

Contact us to discuss your centralized logging requirements.


Related:

Want to Learn More?

Explore more insights from our team or get in touch to discuss how we can help with your cloud journey.