AWS for DevOps — CloudTrail

2 minute read

10.4 — CloudTrail

CloudTrail records every API call made in your AWS account. It answers the question: “Who did what, when, and from where?”

How CloudTrail Works

  ┌──────────────────────────────────────────────────────┐
  │                     AWS Account                       │
  │                                                       │
  │  Console ──┐                                          │
  │            ├──→ API Call ──→ CloudTrail ──→ S3 Bucket │
  │  CLI ──────┘                    │                     │
  │  SDK ──────┘                    ├──→ CloudWatch Logs  │
  │  Service ──┘                    └──→ EventBridge      │
  └──────────────────────────────────────────────────────┘

Real-World Analogy

CloudTrail is like a security camera system for your AWS account. Every door opened, every light switched on, every drawer accessed — all recorded with timestamps and who did it.

Event Types

Type What It Records Example
Management Events Control-plane operations CreateBucket, RunInstances, DeleteStack
Data Events Data-plane operations GetObject, PutObject, Invoke (Lambda)
Insights Events Unusual API activity Spike in RunInstances calls

Creating a Trail

# Create an S3 bucket for CloudTrail logs
$ aws s3 mb s3://my-cloudtrail-logs-123456

# Create a trail that logs all regions
$ aws cloudtrail create-trail \
    --name production-trail \
    --s3-bucket-name my-cloudtrail-logs-123456 \
    --is-multi-region-trail \
    --enable-log-file-validation
{
    "Name": "production-trail",
    "S3BucketName": "my-cloudtrail-logs-123456",
    "IsMultiRegionTrail": true,
    "LogFileValidationEnabled": true,
    "TrailARN": "arn:aws:cloudtrail:ap-south-1:123456789012:trail/production-trail"
}

# Start logging
$ aws cloudtrail start-logging --name production-trail

Querying CloudTrail Events

# Look up recent events
$ aws cloudtrail lookup-events \
    --lookup-attributes AttributeKey=EventName,AttributeValue=StopInstances \
    --max-results 5
{
    "Events": [
        {
            "EventId": "abc-123",
            "EventName": "StopInstances",
            "EventTime": "2026-03-30T10:15:00Z",
            "Username": "dev-user",
            "Resources": [
                {
                    "ResourceType": "AWS::EC2::Instance",
                    "ResourceName": "i-0abc123def456"
                }
            ]
        }
    ]
}

# Who deleted a security group?
$ aws cloudtrail lookup-events \
    --lookup-attributes AttributeKey=EventName,AttributeValue=DeleteSecurityGroup \
    --start-time "2026-03-29T00:00:00Z" \
    --end-time "2026-03-30T23:59:59Z"

CloudTrail + CloudWatch Logs

Send CloudTrail events to CloudWatch Logs for real-time alerting:

# Create a log group for CloudTrail
$ aws logs create-log-group --log-group-name /aws/cloudtrail/production

# Update the trail to send logs to CloudWatch
$ aws cloudtrail update-trail \
    --name production-trail \
    --cloud-watch-logs-log-group-arn \
      arn:aws:logs:ap-south-1:123456789012:log-group:/aws/cloudtrail/production:* \
    --cloud-watch-logs-role-arn \
      arn:aws:iam::123456789012:role/CloudTrailToCloudWatch

Security Investigation with CloudTrail

Question How to Answer
Who launched that EC2 instance? Filter RunInstances events by time range
When was IAM policy changed? Filter PutUserPolicy or AttachUserPolicy events
Who deleted the S3 bucket? Filter DeleteBucket events
Was the root account used? Filter events where Username = root
Who created access keys? Filter CreateAccessKey events

Log File Validation

CloudTrail can cryptographically validate that logs haven’t been tampered with:

# Validate logs for the last 24 hours
$ aws cloudtrail validate-logs \
    --trail-arn arn:aws:cloudtrail:ap-south-1:123456789012:trail/production-trail \
    --start-time "2026-03-29T00:00:00Z" \
    --end-time "2026-03-30T00:00:00Z"
Results requested for 2026-03-29T00:00:00Z to 2026-03-30T00:00:00Z
Results found for 2026-03-29T00:00:00Z to 2026-03-30T00:00:00Z:
24/24 digest files valid
142/142 log files valid

Common Mistakes

Mistake Why It Hurts Fix
Not enabling multi-region trail Miss events in other regions Always use --is-multi-region-trail
No log file validation Can’t prove logs are tamper-free Enable --enable-log-file-validation
Not monitoring data events Miss S3/Lambda access patterns Enable data events for critical buckets
No CloudWatch Logs integration Delayed incident response Send trail to CloudWatch for real-time alerts

Quick Reference

Task Command
Create trail aws cloudtrail create-trail --name NAME --s3-bucket-name BUCKET
Start logging aws cloudtrail start-logging --name NAME
Look up events aws cloudtrail lookup-events --lookup-attributes ...
Get trail status aws cloudtrail get-trail-status --name NAME
Validate logs aws cloudtrail validate-logs --trail-arn ARN --start-time ... --end-time ...

Next → X-Ray & SNS

Updated: