現象
Terraformで以下のようにECSイベントが発生した際にそれをCloudWatch Logsに出力するEventBridge ruleとtargetを作成したところ、うまくCloudWatch Logsにイベントが出力されませんでした。
resource "aws_cloudwatch_log_group" "main" { name = "/aws/events/masasuzu/test/ecs/event" retention_in_days = 3 } module "eventbridge" { source = "terraform-aws-modules/eventbridge/aws" create_bus = false create_role = false rules = { "masasuzu-test-ecs-event-log" = { event_pattern = jsonencode({ "source" : ["aws.ecs"], }) enabled = true } } targets = { "masasuzu-test-ecs-event-log" = [ { name = "masasuzu-test-ecs-event-log" arn = aws_cloudwatch_log_group.main.arn } ] } }
試しにコンソールから同様のリソースを作成したところうまくCloudWatch Logsに出力され、Terraformで作ったEventBridgeも正しく動くようになりました。
ここからわかることはコンソールでEventBridgeの設定をした際に裏側で暗黙的になにかリソースが作られたということです。
原因
EventBridgeからCloudWatch Logsへの出力を許可するためにCloudWatch Logsのリソースポリシーを設定する必要があります。
まっさらなAWSアカウントでは以下のようにCloudWatch Logsのリソースポリシーが設定されています。何も設定されていません。
% aws logs describe-resource-policies --no-cli-pager { "resourcePolicies": [] }
コンソールからEventBridgeの設定をすると以下のような設定が追加されます。これにより、EventBridgeからCloudWatch LogsへのPutLogEventsやCreateLogStreamが許可され、無事イベントがログに出力されるようになります。
% aws logs describe-resource-policies --no-cli-pager { "resourcePolicies": [ { "policyName": "TrustEventsToStoreLogEvents", "policyDocument": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Sid\":\"TrustEventsToStoreLogEvent\",\"Effect\":\"Allow\",\"Principal\":{\"Service\":[\"delivery.logs.amazonaws.com\",\"events.amazonaws.com\"]},\"Action\":[\"logs:CreateLogStream\",\"logs:PutLogEvents\"],\"Resource\":\"arn:aws:logs:ap-northeast-1:xxxxxxxxxx:log-group:/aws/events/*:*\"}]}", "lastUpdatedTime": 1705025982872 } ] }
対策
リソースポリシーを設定するために、以下のような記述を追加してあげると良いでしょう。
data "aws_iam_policy_document" "main" { statement { actions = [ "logs:CreateLogStream", "logs:PutLogEvents", ] resources = ["arn:aws:logs:ap-northeast-1:${var.account_id}:log-group:${var.log_group_path}:*"] principals { identifiers = ["events.amazonaws.com"] type = "Service" } } } resource "aws_cloudwatch_log_resource_policy" "main" { policy_document = data.aws_iam_policy_document.main.json policy_name = "EventsToLog" }
参考: CloudWatch Logs リソースへの許可の管理の概要 - Amazon CloudWatch Logs
参考: aws_cloudwatch_log_resource_policy | Resources | hashicorp/aws | Terraform | Terraform Registry