compliance.tf
Compliance ControlsAWS CloudTrail

CloudTrail trails should be integrated with CloudWatch logs

CloudTrail records every API call in your AWS account, but the logs sit in S3 by default with no active monitoring. Without CloudWatch Logs integration, you cannot create metric filters for unauthorized access attempts, console sign-in failures, or security group changes. Detection depends entirely on someone manually inspecting S3 objects.

Streaming CloudTrail events to CloudWatch Logs enables near-real-time alerting through metric filters and CloudWatch Alarms. Every CIS-recommended alarm depends on this integration, and it's a prerequisite for automated incident response workflows using EventBridge or Lambda.

Retrofit consideration

Existing trails often lack an IAM role with the correct trust policy for CloudWatch Logs delivery. Adding cloud_watch_logs_role_arn to a live trail requires standing up the IAM role first. There is a short window during apply where the trail is configured but log delivery has not started yet.

Implementation

Choose the approach that matches how you manage Terraform.

Use AWS provider resources directly. See docs for the resources involved: aws_cloudtrail.

resource "aws_cloudtrail" "this" {
  advanced_event_selector {
    field_selector {
      equals = ["Data"]
      field  = "eventCategory"
    }
    field_selector {
      equals = ["AWS::S3::Object"]
      field  = "resources.type"
    }

    name = "Log all S3 data events"
  }

  cloud_watch_logs_group_arn = local.cloudtrail_log_group_arn
  cloud_watch_logs_role_arn  = "arn:aws:iam::123456789012:role/example-role"
  name                       = "example-abc123"
  s3_bucket_name             = "example-bucket-abc123"
}

What this control checks

The control checks that aws_cloudtrail has cloud_watch_logs_group_arn and cloud_watch_logs_role_arn set, and that CloudTrail actually delivered events to the log group within the last day. cloud_watch_logs_role_arn must reference an IAM role whose trust policy allows cloudtrail.amazonaws.com to assume it and whose permissions grant logs:CreateLogStream and logs:PutLogEvents on the target log group. A trail fails when the log group is missing, and also when the latest CloudWatch Logs delivery is older than one day, which is what happens when the role or ARN is wrong and delivery is failing. Setting retention_in_days on the aws_cloudwatch_log_group is recommended but not required by this control.

Common pitfalls

IAM role trust policy missing CloudTrail principal

The IAM role referenced by cloud_watch_logs_role_arn must include cloudtrail.amazonaws.com in its assume_role_policy. If the trust policy only allows EC2 or Lambda, CloudTrail fails to deliver logs and the trail appears configured but produces no CloudWatch log streams.

Log group ARN suffix mismatch

CloudTrail expects the log group ARN with a :* suffix, for example arn:aws:logs:us-east-1:123456789012:log-group:my-group:*. The aws_cloudwatch_log_group resource arn attribute is the base ARN without that suffix, so you need to append :* when setting cloud_watch_logs_group_arn. Hardcode the ARN or omit the suffix and delivery silently fails.

Multi-region trail only needs one integration

A multi-region trail configured with is_multi_region_trail = true delivers events from all regions to a single CloudWatch Logs group in the trail's home region. Creating per-region log groups for the same trail is unnecessary and creates confusion during audits.

Organization trail requires delegated admin permissions

For organization trails (is_organization_trail = true), the CloudWatch Logs IAM role needs logs:PutLogEvents scoped to the management account's log group. Member account events flow through the organization trail but land in the management account's log group only.

Broken delivery fails the control within a day

CloudTrail usually delivers events to CloudWatch Logs within about 5 minutes, so a new trail can show no log streams right after terraform apply. If nothing arrives for a full day, the control fails even though the log group is configured. Check LatestCloudWatchLogsDeliveryError in aws cloudtrail get-trail-status to find the cause.

Audit evidence

An auditor expects to see Config rule evaluation results for the managed rule cloud-trail-cloud-watch-logs-enabled, showing all trails as COMPLIANT. Supporting evidence includes the CloudTrail console or aws cloudtrail describe-trails output confirming CloudWatchLogsLogGroupArn and CloudWatchLogsRoleArn are populated for each trail. The auditor may also request aws logs describe-log-groups output showing the referenced log group exists and is receiving recent log streams, confirming active delivery rather than a stale configuration.

Framework-specific interpretation

SOC 2: CC7.2 and CC7.3 expect continuous visibility into security-relevant events and the ability to detect anomalies. Streaming CloudTrail to CloudWatch Logs gives you that visibility at the API layer and lets you define the alerting thresholds auditors will ask about.

PCI DSS v4.0: Requirement 10 calls for automated log review capabilities on in-scope infrastructure. Metric filters and CloudWatch Alarms on CloudTrail events are one approach to meeting that outcome for AWS API activity.

HIPAA Omnibus Rule 2013: 45 CFR 164.312(b) requires audit controls that record and examine activity in systems containing ePHI. CloudWatch Logs integration gives you an active monitoring layer on top of CloudTrail's passive S3 archive, which is what examiners actually want to see for health data workloads.

ISO/IEC 27001:2022: Delivering CloudTrail events to CloudWatch Logs satisfies the active monitoring intent of A.8.16 and gives you the centralized log collection that A.8.15 asks for.

GDPR: Article 32 requires technical measures to ensure security of processing, including the ability to detect and respond to incidents involving personal data. Centralized API monitoring through CloudWatch Logs contributes to that capability, though it is one part of a broader data security posture.

NIS2 Directive (EU 2022/2555): Article 21 requires appropriate measures for incident detection and handling. Routing CloudTrail events to CloudWatch Logs provides the detection capability needed to identify security incidents affecting network and information systems before they become breaches.

NIST SP 800-53 Rev 5: AU-6 and AU-12 together require both generating audit records and analyzing them. CloudWatch Logs integration handles the analysis side, enabling automated correlation and alerting on CloudTrail events. SI-4 monitoring requirements are addressed through the same integration.

NIST Cybersecurity Framework v2.0: CloudTrail events streaming into CloudWatch Logs feed directly into DE.CM and DE.AE monitoring, turning a passive audit log into a live detection pipeline. Without this integration, continuous monitoring of security events and anomalous API activity is not practical.

FedRAMP Moderate Baseline Rev 4: AU-6 (Audit Review, Analysis, and Reporting) at the Moderate baseline expects automated review of audit records, which metric filters and alarms on CloudWatch Logs provide. SI-4 (Information System Monitoring) is also supported through near-real-time visibility into API-level activity.

Tool mappings

Use these identifiers to cross-reference this control across tools, reports, and evidence.

  • Compliance.tf Control: cloudtrail_trail_integrated_with_logs
  • Checkov Check: CKV2_AWS_10
  • Powerpipe Control: aws_compliance.control.cloudtrail_trail_integrated_with_logs
  • Prowler Check: cloudtrail_cloudwatch_logging_enabled
  • AWS Security Hub Control: CloudTrail.5
  • KICS Query: 17b30f8f-8dfb-4597-adf6-57600b6cf25e

Last reviewed: 2026-10-03

On this page

Ask AI about this

Help improve this page