Skill 98 · Setting Up Cloudtrail Multi Region
Subchapter 98.1
references/cloudtrail-multi-region-setup.mdMarkdown18 KBView on GitHub
This SOP enables AWS CloudTrail across all regions to capture comprehensive API activity logs and configures CloudWatch Logs Insights for analysis. It creates a centralized logging solution for security monitoring, compliance auditing, and operational insights across your entire AWS infrastructure.
MANDATORY STEP EXECUTION CONSTRAINTS:
RESPONSE REPORTING CONSTRAINTS:
Check for required tools and permissions before starting the setup.
Constraints:
aws sts get-caller-identity --region ${region}Create a dedicated S3 bucket with proper permissions, encryption, and lifecycle policies for CloudTrail log storage.
Constraints:
aws sts get-caller-identity --region ${region}aws s3api create-bucket --bucket ${s3_bucket_name} --region ${region} --create-bucket-configuration LocationConstraint=${region} (omit create-bucket-configuration for us-east-1)aws s3api put-bucket-versioning --bucket ${s3_bucket_name} --versioning-configuration Status=Enabled --region ${region}aws s3api put-bucket-tagging --bucket ${s3_bucket_name} --tagging TagSet='[${parsed_tags}]' --region ${region}aws s3api put-bucket-encryption --bucket ${s3_bucket_name} --server-side-encryption-configuration Rules='[{"ApplyServerSideEncryptionByDefault":{"SSEAlgorithm":"aws:kms","KMSMasterKeyID":"${kms_key_id}"}}]' --region ${region}aws s3api put-bucket-lifecycle-configuration --bucket ${s3_bucket_name} --lifecycle-configuration '{"Rules":[{"ID":"CloudTrailLogLifecycle","Status":"Enabled","Filter":{"Prefix":""},"Transitions":[{"Days":30,"StorageClass":"STANDARD_IA"},{"Days":90,"StorageClass":"GLACIER"},{"Days":365,"StorageClass":"DEEP_ARCHIVE"}]}]}' --region ${region}aws s3api put-bucket-policy --bucket ${s3_bucket_name} --policy '{"Version":"2012-10-17","Statement":[{"Sid":"AWSCloudTrailAclCheck","Effect":"Allow","Principal":{"Service":"cloudtrail.amazonaws.com"},"Action":"s3:GetBucketAcl","Resource":"arn:aws:s3:::${s3_bucket_name}","Condition":{"StringEquals":{"AWS:SourceAccount":"${account_id}"}}},{"Sid":"AWSCloudTrailWrite","Effect":"Allow","Principal":{"Service":"cloudtrail.amazonaws.com"},"Action":"s3:PutObject","Resource":"arn:aws:s3:::${s3_bucket_name}/*","Condition":{"StringEquals":{"s3:x-amz-acl":"bucket-owner-full-control","AWS:SourceAccount":"${account_id}"},"StringLike":{"AWS:SourceArn":"arn:aws:cloudtrail:*:${account_id}:trail/${trail_name}"}}},{"Sid":"AWSCloudTrailBucketExistenceCheck","Effect":"Allow","Principal":{"Service":"cloudtrail.amazonaws.com"},"Action":"s3:ListBucket","Resource":"arn:aws:s3:::${s3_bucket_name}","Condition":{"StringEquals":{"AWS:SourceAccount":"${account_id}"}}}]}' --region ${region}Set up CloudWatch log group for real-time log analysis.
Constraints:
aws logs create-log-group --log-group-name ${cloudwatch_log_group} --region ${region}aws logs put-retention-policy --log-group-name ${cloudwatch_log_group} --retention-in-days 90 --region ${region}aws logs tag-log-group --log-group-name ${cloudwatch_log_group} --tags ${tags} --region ${region}Create IAM role with necessary permissions for CloudTrail operations.
Constraints:
CloudTrail-CloudWatchLogs-Role-${trail_name}aws iam tag-role --role-name CloudTrail-CloudWatchLogs-Role-${trail_name} --tags ${tags} --region ${region}Create and configure CloudTrail to capture events across all regions.
Constraints:
aws cloudtrail create-trail --name ${trail_name} --s3-bucket-name ${s3_bucket_name} --include-global-service-events --is-multi-region-trail --enable-log-file-validation --cloud-watch-logs-log-group-arn ${log_group_arn} --cloud-watch-logs-role-arn ${role_arn} --region ${region}--kms-key-id ${kms_key_id}aws cloudtrail add-tags --resource-id ${trail_arn} --tags-list ${tags} --region ${region}aws cloudtrail start-logging --name ${trail_name} --region ${region}Configure data events for S3 and Lambda if requested.
Constraints:
aws cloudtrail put-event-selectors --trail-name ${trail_name} --event-selectors '[{"ReadWriteType": "All","IncludeManagementEvents": true,"DataResources": [{"Type":"AWS::S3::Object", "Values": ["arn:aws:s3"]},{"Type": "AWS::Lambda::Function","Values": ["arn:aws:lambda"]}]}]' --region ${region}Enable CloudTrail Insights for anomaly detection if requested.
Constraints:
aws cloudtrail put-insight-selectors --trail-name ${trail_name} --insight-selectors InsightType=ApiCallRateInsight --region ${region}Test the CloudTrail setup and log analysis capabilities.
Constraints:
You MUST verify trail is logging: aws cloudtrail get-trail-status --name ${trail_name} --region ${region}
You MUST check CloudWatch log group exists: aws logs describe-log-groups --log-group-name-prefix ${cloudwatch_log_group} --region ${region}
You MUST generate test events in at least 2 different standard regions (e.g., eu-west-1, ap-southeast-1)
You MUST check S3 bucket for log files from different regions
You MUST provide actual verification results, not just generation confirmation
You MUST inform user that events may take 5-15 minutes to appear in CloudWatch logs and opt-in region events may take several hours to appear (per AWS documentation)
You MUST provide commands for later verification:
# Check for events
aws logs start-query --log-group-name ${cloudwatch_log_group} --start-time "<start-time>" --end-time "<end-time>" --query-string "fields @timestamp, awsRegion, eventName | filter awsRegion!=\${region} | sort @timestamp desc" --region ${region}Create comprehensive documentation of the CloudTrail configuration.
Constraints:
aws cloudtrail describe-trails --trail-name-list ${trail_name} --region ${region}aws cloudtrail get-trail-status --name ${trail_name} --region ${region}aws s3api get-bucket-location --bucket ${s3_bucket_name} and aws s3api get-bucket-versioning --bucket ${s3_bucket_name}aws logs describe-log-groups --log-group-name-prefix ${cloudwatch_log_group} --region ${region}aws iam get-role --role-name CloudTrail-CloudWatchLogs-Role-${trail_name}trail_name: security-audit-trail
s3_bucket_name: my-org-cloudtrail-logs-2024
region: us-east-1
cloudwatch_log_group: CloudTrail/SecurityLogs
enable_data_events: true
enable_insights: true
kms_key_id: 12345678-1234-1234-1234-123456789012
tags: {"Environment":"prod","Owner":"security-team","Project":"audit","CostCenter":"IT-001"}fields @timestamp, sourceIPAddress, userIdentity.userName, eventName, errorCode, errorMessage
| filter errorCode exists
| stats count() by userIdentity.userName, errorCode, eventName
| sort count descfields @timestamp, sourceIPAddress, eventName, userAgent, awsRegion
| filter userIdentity.type = "Root"
| sort @timestamp descfields @timestamp, userIdentity.userName, eventName, sourceIPAddress, awsRegion, resources
| filter eventName like /Delete/
| sort @timestamp descfields @timestamp, userIdentity.userName, eventName, sourceIPAddress, awsRegion
| filter eventName like /SecurityGroup/
| sort @timestamp descfields @timestamp, userIdentity.userName, eventName, sourceIPAddress, resources
| filter eventName like /Policy/ or eventName like /Role/ or eventName like /User/
| sort @timestamp descIf the S3 bucket name is already taken:
Check your identity: aws sts get-caller-identity --region ${region}
Required IAM actions for this procedure:
CreateTrail, StartLogging, PutEventSelectors, PutInsightSelectors, DescribeTrails, GetTrailStatus, AddTagsCreateBucket, PutBucketPolicy, PutBucketVersioning, PutEncryptionConfiguration, PutLifecycleConfiguration, PutBucketTagging, GetBucketLocation, GetBucketVersioningCreateLogGroup, PutRetentionPolicy, DescribeLogGroups, TagLogGroupCreateRole, PutRolePolicy, GetRole, TagRole, PassRoleDo NOT use *FullAccess managed policies — they grant admin-level wildcards beyond what this procedure requires.
If log group creation fails:
If the trail shows as not logging:
start-logging commandIf events aren’t appearing in CloudWatch Logs:
If events from opt-in regions aren’t showing up:
aws ec2 describe-regions --filters "Name=opt-in-status,Values=opted-in" --region ${region}aws cloudtrail describe-trails --region [opt-in-region]If CloudTrail creation fails with InvalidCloudWatchLogsLogGroupArnException:
aws iam get-role --role-name CloudTrail-CloudWatchLogs-Role-${trail_name} --region ${region}If KMS encryption fails:
aws kms describe-key --key-id ${kms_key_id} --region ${region}If resource tagging fails: