CloudWatch log group permissions are required in order for the log groups to receive events from a sources such as Cloud Watch Event rule. these permissions are added automatically when you create log groups using AWS Console.
However when we use terraform to automate the process, these permissions should be added separately otherwise your log groups will not work.
Lets look into a use case of creating guard duty CloudWatch event rule and then create a CW Log group and then add CloudWatch log group as a target of the event rule. following is a CloudWatch terraform example
Refer to AWS documentation to lean more about Log groups
Lets look into a Cloud Watch log group Terraform example to understand the CloudWatch log group permissions better.
Step #1: Create Cloud Watch event rule for Guard Duty high severity findings
resource "aws_cloudwatch_event_rule" "guardduty_event_rule" {
name = "Name of event rule"
description = "Capture GuardDuty high severity findins and trigger CW Log Group"
tags = {
"Name" = "Name of event rule
}
event_pattern = <<PATTERN
{
"source":
["aws.guardduty"],
"detail-type":
["GuardDuty Finding"],
"detail":
{"severity":[7.0,7.1,7.2,7.3,7.4,7.5,7.6,7.7,7.8,7.9,8.0,8.1,8.2,8.3,8.4,8.5,8.6,8.7,8.8,8.9]}}
PATTERN
}
Step #2: Create CloudWatch log group to store logs for 5 days
#create CW Log group
resource "aws_cloudwatch_log_group" "guard_duty_log_group" {
name = "Guard Duty findings log group name"
#delete logs after 5 days
retention_in_days = 5
tags = {
"Name" = "Guard Duty findings log group name"
}
}
Step #3: Add CW event Target
#add CW Log group to store logs.
resource "aws_cloudwatch_event_target" "cw_target_to_cw_logs" {
rule = aws_cloudwatch_event_rule.guardduty_event_rule.name
target_id = "SendToCWLogGroup"
arn = "${substr(aws_cloudwatch_log_group.guard_duty_log_group.arn,0,length(aws_cloudwatch_log_group.guard_duty_log_group.arn) - 2)}"
}
Step #4: Add CloudWatch log group permissions
These permissions allows CloudWatch events to create logs stream and publish events to the logs. change the resource from the policy as per your needs.
#Provides a CW events to manage a CloudWatch log resource policy
data "aws_iam_policy_document" "cw-event-log-publishing-policy" {
statement {
actions = [
"logs:CreateLogStream",
"logs:PutLogEvents",
"logs:PutLogEventsBatch",
]
#resources = ["arn:aws:logs:*"]
resources = ["arn:aws:logs:eu-central-1:<AccountId>:log-group:/aws/events/*:*]
principals {
identifiers = ["delivery.logs.amazonaws.com", "events.amazonaws.com"]
type = "Service"
}
}
}
resource "aws_cloudwatch_log_resource_policy" "cw-rule-log-publishing-policy" {
policy_document = "${data.aws_iam_policy_document.cw-event-log-publishing-policy.json}"
policy_name = "cw-rule-log-publishing-policy"
}
Now we should see the Guard Duty events flowing into CloudWatch log groups.
This screenshot shows how your CloudWatch even should look like.
Refer to this article to learn setting up guard duty service in a multi account environment