I am working on creating a Cloudtrail trail and to log everything to an S3 bucket with Terraform.
This is the code
resource "aws_kms_key" "cloudtrail_kms_key" {
description = "KMS key for Cloudtrail S3 Bucket"
enable_key_rotation = true
}
resource "aws_kms_key_policy" "cloudtrail_kms_key_policy" {
key_id = aws_kms_key.cloudtrail_kms_key.id
policy = jsonencode({
Version = "2012-10-17",
Id = "test",
Statement : [
{
Sid = "Enable IAM User Permissions"
Effect = "Allow"
Principal =
{
AWS = "arn:aws:iam::${var.aws_account_id}:root"
}
Action = "kms:*"
Resource = "*"
},
{
Sid = "Permitted KMS Key Services"
Effect = "Allow"
Principal = {
Service = ["cloudtrail.amazonaws.com"]
AWS = "arn:aws:iam::${var.aws_account_id}:root"
}
Action = ["kms:GenerateDataKey*", "kms:Decrypt"]
Resource = "*",
"Condition" : {
"StringEquals" : {
"aws:SourceArn" : "arn:aws:cloudtrail:${var.aws_region}:${var.aws_account_id}:trail/${var.trail_name}"
}
}
}
]
})
}
resource "aws_s3_bucket" "cloudtrail_bucket" {
bucket = "${var.bucket_name}-${var.aws_region}-${var.aws_account_id}-ls"
}
resource "aws_s3_bucket_server_side_encryption_configuration" "cloudtrail_bucket_sse_configuration" {
bucket = aws_s3_bucket.cloudtrail_bucket.id
rule {
apply_server_side_encryption_by_default {
kms_master_key_id = aws_kms_key.cloudtrail_kms_key.arn
sse_algorithm = "aws:kms"
}
}
resource "aws_s3_bucket_ownership_controls" "cloudtrail_bucket_ownership_controls" {
bucket = aws_s3_bucket.cloudtrail_bucket.id
rule {
object_ownership = "BucketOwnerPreferred"
}
}
resource "aws_s3_bucket_versioning" "cloudtrail_bucket_versioning" {
bucket = aws_s3_bucket.cloudtrail_bucket.id
versioning_configuration {
status = "Enabled"
}
}
data "aws_iam_policy_document" "cloudtrail_bucket_policy" {
statement {
sid = "AWSCloudTrailAclCheck"
effect = "Allow"
principals {
type = "Service"
identifiers = ["cloudtrail.amazonaws.com"]
}
actions = ["s3:GetBucketAcl"]
resources = [aws_s3_bucket.cloudtrail_bucket.arn]
condition {
test = "StringEquals"
variable = "aws:SourceArn"
values = ["arn:aws:cloudtrail:${var.aws_region}:${var.aws_account_id}:trail/${var.trail_name}"]
}
}
statement {
sid = "AWSCloudTrailWrite"
effect = "Allow"
principals {
type = "Service"
identifiers = ["cloudtrail.amazonaws.com"]
}
actions = ["s3:PutObject"]
resources = ["${aws_s3_bucket.cloudtrail_bucket.arn}/prefix/AWSLogs/${var.aws_account_id}/*"]
condition {
test = "StringEquals"
variable = "s3:x-amz-acl"
values = ["bucket-owner-full-control"]
}
condition {
test = "StringEquals"
variable = "aws:SourceArn"
values = ["arn:aws:cloudtrail:${var.aws_region}:${var.aws_account_id}:trail/${var.trail_name}"]
}
}
}
resource "aws_s3_bucket_policy" "cloudtrail_bucket_policy" {
bucket = aws_s3_bucket.cloudtrail_bucket.id
policy = data.aws_iam_policy_document.cloudtrail_bucket_policy.json
}
resource "aws_cloudtrail" "trail" {
depends_on = [aws_s3_bucket_policy.cloudtrail_bucket_policy]
name = var.trail_name
s3_bucket_name = aws_s3_bucket.cloudtrail_bucket.id
s3_key_prefix = "AWSLogs"
is_organization_trail = true
is_multi_region_trail = true
kms_key_id = aws_kms_key.cloudtrail_kms_key.arn
enable_log_file_validation = true
}
This is my provider configuration
terraform {
required_version = "~> 1.3, < 1.6"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
This creates the following resources
When I run terraform apply
, I keep running into the following error:
Error: creating CloudTrail Trail (audit-logs): operation error CloudTrail: CreateTrail, https response error StatusCode: 400, RequestID: abdc7ed4-22c4-4462-9ff9-4f8bda32e509, api error AccessDeniedException: Access Denied: You do not have permission to operate on this resource.
The role that I am using to deploy this has an admin role so I am unsure what else is missing to create Cloudtrail.
When an organization trail needs to be created, it needs to happen in the organization management account:
You must sign in with the management account or a delegated administrator account associated with an organization to create an organization trail. You must also have sufficient permissions for the user or role in the management or delegated administrator account to create the trail. If you don't have sufficient permissions, you won't have the option to apply the trail to an organization.
Looking at the code you have in the question, there is one argument that is set to create the organizational trail:
is_organization_trail = true
means you are in fact creating an organizational trail.