Operations

How to Configure AWS CloudTrail and Export to S3

A step-by-step guide to setting up AWS CloudTrail for your account, saving logs to S3, and the real-world challenges of querying them with Amazon Athena.

5 min read Last updated: April 2026

Overview

Setting up AWS CloudTrail is the foundational step for any cloud security program. CloudTrail records API calls and management events across your AWS environment, giving you the visibility needed to detect threats and investigate incidents.

According to AWS documentation, you can quickly configure a trail using the AWS CLI. In this guide, you will learn how to configure a multi-region CloudTrail trail, export those logs to a centralized S3 bucket, and understand why many security teams struggle when trying to query these logs directly using Amazon Athena.


Step 1: Create a dedicated S3 Bucket

Your CloudTrail logs need a secure, centralized home. Create a dedicated Amazon S3 bucket for this purpose. Do not use this bucket for any other application data.

aws s3api create-bucket \
    --bucket my-company-cloudtrail-logs \
    --region us-east-1

Once created, ensure you block public access and enable default encryption on the bucket to meet security best practices.


Step 2: Apply the bucket policy

CloudTrail needs permission to write log files to your new S3 bucket. You must attach a resource-based policy to the bucket that allows the cloudtrail.amazonaws.com service principal to perform s3:GetBucketAcl and s3:PutObject.

Create a file named bucket-policy.json with the following policy, replacing the bucket name and account ID with your own:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AWSCloudTrailAclCheck",
            "Effect": "Allow",
            "Principal": {
                "Service": "cloudtrail.amazonaws.com"
            },
            "Action": "s3:GetBucketAcl",
            "Resource": "arn:aws:s3:::my-company-cloudtrail-logs"
        },
        {
            "Sid": "AWSCloudTrailWrite",
            "Effect": "Allow",
            "Principal": {
                "Service": "cloudtrail.amazonaws.com"
            },
            "Action": "s3:PutObject",
            "Resource": "arn:aws:s3:::my-company-cloudtrail-logs/AWSLogs/111122223333/*",
            "Condition": {
                "StringEquals": {
                    "s3:x-amz-acl": "bucket-owner-full-control"
                }
            }
        }
    ]
}

Apply this policy using the AWS CLI:

aws s3api put-bucket-policy \
    --bucket my-company-cloudtrail-logs \
    --policy file://bucket-policy.json

Step 3: Create and start the trail

Now, configure the trail itself. Before doing so, it is important to understand the different event types you can capture with CloudTrail:

  • Management events: (Also known as control plane operations). These log management operations performed on resources in your AWS account, such as creating a VPC (CreateVpc) or modifying IAM permissions (AttachRolePolicy). This is enabled by default.
  • Data events: (Also known as data plane operations). These log high-volume resource operations, such as S3 object-level APIs (GetObject, PutObject) or AWS Lambda function executions (Invoke). These are disabled by default due to high volume and additional costs, but are crucial for tracking data exfiltration.
  • Network activity events: These record VPC endpoint activity, allowing you to see AWS API calls made through private VPC endpoints from your network.
  • Insights events: CloudTrail Insights analyzes your normal management events and logs an event when it detects unusual activity, such as a sudden spike in resource provisioning.

It is critical to enable the trail for all regions so you do not miss activity in regions you do not actively use. Attackers often spin up resources in unused regions to avoid detection.

aws cloudtrail create-trail \
    --name management-events-trail \
    --s3-bucket-name my-company-cloudtrail-logs \
    --is-multi-region-trail \
    --enable-log-file-validation

After creating the trail, start the logging process:

aws cloudtrail start-logging --name management-events-trail

Your AWS account is now recording all management events and delivering them to your S3 bucket as gzipped JSON files.


Step 4: Alternative: Deploy using CloudFormation

If your team prefers Infrastructure-as-Code (IaC), you can deploy the S3 bucket, bucket policy, and the multi-region CloudTrail trail in one go using AWS CloudFormation.

Save the following template as cloudtrail-setup.yaml:

AWSTemplateFormatVersion: '2010-09-09'
Description: 'CloudFormation Template to set up a multi-region CloudTrail and an S3 bucket for log storage.'

Resources:
  CloudTrailBucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Sub 'my-company-cloudtrail-logs-${AWS::AccountId}'
      PublicAccessBlockConfiguration:
        BlockPublicAcls: true
        BlockPublicPolicy: true
        IgnorePublicAcls: true
        RestrictPublicBuckets: true
      BucketEncryption:
        ServerSideEncryptionConfiguration:
          - ServerSideEncryptionByDefault:
              SSEAlgorithm: AES256

  CloudTrailBucketPolicy:
    Type: AWS::S3::BucketPolicy
    Properties:
      Bucket: !Ref CloudTrailBucket
      PolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Sid: AWSCloudTrailAclCheck
            Effect: Allow
            Principal:
              Service: cloudtrail.amazonaws.com
            Action: s3:GetBucketAcl
            Resource: !Sub 'arn:aws:s3:::${CloudTrailBucket}'
          - Sid: AWSCloudTrailWrite
            Effect: Allow
            Principal:
              Service: cloudtrail.amazonaws.com
            Action: s3:PutObject
            Resource: !Sub 'arn:aws:s3:::${CloudTrailBucket}/AWSLogs/${AWS::AccountId}/*'
            Condition:
              StringEquals:
                s3:x-amz-acl: bucket-owner-full-control

  CompanyCloudTrail:
    Type: AWS::CloudTrail::Trail
    DependsOn: CloudTrailBucketPolicy
    Properties:
      TrailName: management-events-trail
      S3BucketName: !Ref CloudTrailBucket
      IsLogging: true
      IsMultiRegionTrail: true
      EnableLogFileValidation: true
      IncludeGlobalServiceEvents: true

Deploy the stack via the AWS CLI:

aws cloudformation create-stack \
    --stack-name CloudTrailSetup \
    --template-body file://cloudtrail-setup.yaml

Step 5: Understand Athena challenges

Many teams attempt to use Amazon Athena to query their CloudTrail logs directly from S3. While AWS documentation provides DDL statements for Athena, real-world security operations tell a different story.

Here is why querying CloudTrail with Athena is challenging:

  1. Complex JSON schema: CloudTrail logs are deeply nested arrays of JSON objects. Writing SQL to unnest and extract fields like userIdentity.arn or requestParameters requires advanced, fragile queries.
  2. Dynamic schema changes: AWS frequently adds new fields to CloudTrail events (e.g., tlsDetails, sessionContext). Athena’s JSON SerDe expects a rigid schema. When the schema changes, queries often break or return null values until you manually update your table definitions.
  3. Partitioning overhead: To keep Athena queries fast and cost-effective, you must partition your S3 bucket by year, month, day, and region. Setting up and maintaining AWS Glue Crawlers or Athena Partition Projection is a significant engineering effort. Without it, every query scans your entire bucket, resulting in slow response times and massive AWS bills.
  4. Poor incident response speed: During an active incident, you need answers in seconds. Athena queries over unoptimized JSON data can take minutes to execute. Waiting for MapReduce jobs to spin up is not acceptable when tracking lateral movement.

Instead of fighting Athena, high-performing teams ingest CloudTrail into a dedicated SIEM or log analytics platform built for nested JSON, where schema-on-read and rapid indexing come out of the box.


Need Help?

Xpernix can help you configure reliable log collection. Reach out in your dedicated channel or book a discovery call if you want help reviewing your AWS detection engineering and log pipelines.

Ready to get started?

Book a free discovery call — we'll have your managed SIEM environment live within hours.

Book a Discovery Call