Skip to main content


In the Logging section, the Benchmark recommendations target the following services:

We’ll cover each of them in turn.

AWS CloudTrail

The Benchmark has specific requirements for the CloudTrail configuration, described in recommendations 3.1-4, 3.6-7 and 3.10-11. The CloudTrail must have the following characteristics:

  1. Collects eventsin all regions

  2. Enables log file integrity validation

  3. Ensures that the S3 bucket used by CloudTrail is not publicly accessible

  4. Integrates CloudTrail with CloudWatch Logs

  5. Encrypts CloudTrail logs at rest

  6. Enables access logging for the CloudTrail S3 bucket

  7. Enables object-level logging for read and write events for the CloudTrail S3 bucket

Use the aws_cloudtrail Terraform resource to create the CloudTrail. Include the following settings in the CloudTrail configuration:

is_multi_region_trail         = true
include_global_service_events = true
enable_log_file_validation = true
s3_bucket_name = "<YOUR CLOUDTRAIL BUCKET NAME>"
cloud_watch_logs_group_arn = "<YOUR CLOUDWATCH LOGS GROUP ARN>"

event_selector {
read_write_type = "All"
include_management_events = true

data_resource {
type = "AWS::S3::Object"

You’ll also need the aws_s3_bucket, aws_s3_account_public_access_block resources to create an S3 bucket for the CloudTrail to send its events to and to disable public access to the bucket; you wouldn’t want to expose the CloudTrail data publicly!

Finally, you’ll need the aws_cloudwatch_log_group resource to create a CloudWatch Log group as another location for CloudTrail to send events. Use this ARN for the aws_cloudtrail resource cloud_watch_logs_group_arn parameter when creating the CloudTrail.

AWS Config

Benchmark recommendation 3.5 states that AWS Config be enabled in all regions. This is challenging to implement with Terraform because running a particular configuration in all regions is not a feature that Terraform has natively. Terraform has loops, but they aren’t available for the purpose of repeating a resource in many regions. Unfortunately, at the time of writing, there isn’t a way to complete this recommendation without repetitive code.

To proceed, start by creating a Terraform module that takes the following actions:

  1. Creates an SNS topic for publishing Config events

  2. Creates an S3 bucket for Config events and disables public access

  3. Creates an IAM role for the config service to access an S3 bucket and an SNS topic

  4. Creates a configuration recorder

  5. Creates a delivery channel

  6. Enables the configuration recorder

When the module is working and sets up AWS Config according to the prescribed configuration, you should invoke it once for each region in the account. One way to do this is to use provider aliases. For example, you could specify one provider for each region, then invoke the module for each provider:

# The default provider configuration
provider "aws" {
alias = "us-east-1"
region = "us-east-1"

# Additional provider configuration for west coast region
provider "aws" {
alias = "us-west-2"
region = "us-west-2"

# ... repeat the provider for each region in the AWS account

module "aws_config_us_east_1" {
source = "/path/to/your/config/module"
providers = {
aws =

module "aws_config_us_west_2" {
source = "/path/to/your/config/module"
providers = {
aws =

# ... repeat the module invocation for each provider

When AWS launches new regions, they are not enabled by default, so you won’t need to add to this list over time.

Alternatively, you could disable the regions you aren’t using and only enable AWS Config for those that you need.

KMS Key rotation

Finally, a simple recommendation! To meet recommendation 3.8, create KMS keys with key rotation enabled. Using Terraform, it looks like this:

resource "aws_kms_key" "example" {
description = "Example Key"
enable_key_rotation = true

VPC Flow Logs

Under the Benchmark, all VPCs must have a Flow Log to log network traffic. Use the aws_flow_log Terraform resource, being sure to use log_destination_type=cloud-watch-logs.

Because the recommendation is to attach flow logs to every single VPC, you’ll need to repeat the configuration for all the default VPCs which exist in all regions of the account. You can use the cloud-nuke defaults-aws command to easily remove all the default VPCs (and default security groups) from all regions of an account, making it easier to achieve this recommendation.