-
Notifications
You must be signed in to change notification settings - Fork 24
Description
Feature Request
Describe the Feature Request
The CloudTrail created by this Terraform module should support setting up a proper logging integration with CloudWatch.
Is your feature request related to a problem? Please describe
The created CloudTrail is non-compliant with CIS Benchmarks and is listed as a Medium severity in Lacework's generated reports for compliance with AWS ISO 27001:2013 and AWS ISO/IEC 27002:2022.
The non-compliance in question is lacework-global-55.
Describe Preferred Solution
The module creates resources that by default are compliant with CIS Benchmarks.
Add input variables cloudwatch_logs_encryption_enabled
, cloudwatch_logs_encryption_key_arn
, and cloudwatch_logs_iam_role_arn
, and set them in the aws_cloudtrail resource. If no IAM role ARN is provided then one should be created by the module.
Additional Context
I think the changes needed are the following:
variables.tf
:
variable "cloudwatch_logs_encryption_enabled" {
type = bool
default = true
}
variable "cloudwatch_logs_encryption_key_arn" {
type = string
default = ""
}
variable "cloudwatch_logs_iam_role_arn" {
type = string
default = ""
}
main.tf
:
locals {
...
create_cloudwatch_iam_role = var.cloudwatch_logs_encryption_enabled && var.cloudwatch_logs_iam_role_arn == null
cloudwatch_key_arn = var.cloudwatch_logs_encryption_enabled ? (length(var.cloudwatch_logs_encryption_key_arn) > 0 ? var.cloudwatch_logs_encryption_key_arn : aws_kms_key.lacework_kms_key[0].arn) : ""
cloudwatch_logstream_arn = "${aws_cloudwatch_log_group.cloudtrail_log_group.arn}:log-stream:${data.aws_caller_identity.current.account_id}_CloudTrail_${data.aws_region.current.name}*" # Reference: https://docs.aws.amazon.com/awscloudtrail/latest/userguide/send-cloudtrail-events-to-cloudwatch-logs.html
}
data "aws_iam_policy_document" "kms_key_policy" {
...
dynamic "statement" {
for_each = (var.cloudwatch_logs_encryption_enabled && length(var.cloudwatch_logs_encryption_key_arn) == 0) ? [1] : []
content {
sid = "Allow CloudWatch service to encrypt/decrypt"
effect = "Allow"
actions = [
"kms:Encrypt*",
"kms:Decrypt*",
"kms:ReEncrypt*",
"kms:GenerateDataKey*",
"kms:Describe*"
]
resources = ["*"]
principals {
type = "Service"
identifiers = [
"logs.${data.aws_region.current.name}.amazonaws.com",
]
}
condition {
test = "ArnEquals"
variable = "kms:EncryptionContext:aws:logs:arn"
values = [
"arn:aws:logs:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:log-group:${var.cloudtrail_name}",
]
}
}
}
}
resource "aws_cloudwatch_log_group" "cloudtrail_log_group" {
name = var.cloudtrail_name
kms_key_id = local.cloudwatch_key_arn
retention_in_days = 90
}
data "aws_iam_policy_document" "cloudtrail_assume_role" {
count = local.create_cloudwatch_iam_role ? 1 : 0
statement {
effect = "Allow"
actions = [
"sts:AssumeRole",
]
principals {
type = "Service"
identifiers = [
"cloudtrail.amazonaws.com"
]
}
}
}
data "aws_iam_policy_document" "cloudtrail_logging" {
count = local.create_cloudwatch_iam_role ? 1 : 0
statement {
sid = "AWSCloudTrailCreateLogStream"
effect = "Allow"
actions = [
"logs:CreateLogStream",
]
resources = [
local.cloudwatch_logstream_resource,
]
}
statement {
sid = "AWSCloudTrailPutLogEvents"
effect = "Allow"
actions = [
"logs:PutLogEvents",
]
resources = [
local.cloudwatch_logstream_resource,
]
}
}
resource "aws_iam_policy" "cloudtrail_logging" {
count = local.create_cloudwatch_iam_role ? 1 : 0
name = var.cloudtrail_name
policy = data.aws_iam_policy_document.cloudtrail_logging[count.index].json
description = "Allows CloudTrail to create log streams and to put logs in CloudWatch"
}
resource "aws_iam_role" "cloudtrail_logging" {
count = local.create_cloudwatch_iam_role ? 1 : 0
name = var.cloudtrail_name
assume_role_policy = data.aws_iam_policy_document.cloudtrail_assume_role[count.index].json
}
resource "aws_iam_role_policy_attachment" "cloudtrail_logging" {
count = local.create_cloudwatch_iam_role ? 1 : 0
role = aws_iam_role.cloudtrail_logging[count.index].name
policy_arn = aws_iam_policy.cloudtrail_logging[count.index].arn
}
resource "aws_cloudtrail" "lacework_cloudtrail" {
...
enable_logging = true
cloud_watch_logs_group_arn = "${aws_cloudwatch_log_group.cloudtrail_log_group.arn}:*"
cloud_watch_logs_role_arn = local.create_cloudwatch_iam_role ? coalesce(var.cloudwatch_logs_iam_role_arn, aws_iam_role.cloudtrail_logging.arn) : null
enable_log_file_validation = var.enable_log_file_validation
...
}
Please note that this code has not been properly tested. I've simply adjusted Terraform configurations that I've found elsewhere.
Thanks!