はじめに
terraform で Amazon EventBridge → Amazon CloudWatch Logs の構成を作るときの例を紹介します。若干詰まった部分も書いているので、参考にしていただけると幸いです。
実装例
例えば、Amazon ECSの停止理由をAmazon CloudWatch Logs に残したい場合は以下の構成になります。
1 |
Amazon ECS → Amazon EventBridge → Amazon CloudWatch Logs |
これをTerraformで宣言すると、以下の様になります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
# ECS stopped tasks resource "aws_cloudwatch_event_rule" "ecs_stopped_tasks_event_rule" { name = "ECSStoppedTasksEvent" description = "Triggered when an Amazon ECS Task is stopped" event_pattern = jsonencode({ source = ["aws.ecs"] "detail-type" = ["ECS Task State Change"] detail = { desiredStatus = ["STOPPED"] lastStatus = ["STOPPED"] } }) state = "ENABLED" } resource "aws_cloudwatch_event_target" "ecs_stopped_tasks_event_target" { target_id = "ECSStoppedTasks" rule = aws_cloudwatch_event_rule.ecs_stopped_tasks_event_rule.name arn = "${aws_cloudwatch_log_group.ecs_stopped_tasks_event.arn}:*" } # ECS stoppped task resource "aws_cloudwatch_log_group" "ecs_stopped_tasks_event" { name = "/aws/events/ECSStoppedTasksEvent" retention_in_days = 90 } # ECS Scheduled tasks resource policy resource "aws_cloudwatch_log_resource_policy" "log_event_policy" { policy_name = "LogEventsPolicy" policy_document = jsonencode({ Version = "2012-10-17", Statement = [ { Effect = "Allow", Principal = { Service = [ "events.amazonaws.com", "delivery.logs.amazonaws.com" ] }, Action = [ "logs:CreateLogStream", "logs:PutLogEvents" ], Resource = ["${aws_cloudwatch_log_group.ecs_stopped_tasks_event.arn}:*"] } ] }) } # 異常終了時のアラーム設定 resource "aws_cloudwatch_log_metric_filter" "task_failed_log_metric_filter" { name = "TaskFailedLogMetricFilter" log_group_name = aws_cloudwatch_log_group.ecs_stopped_tasks_event.name pattern = "failed" metric_transformation { name = "FailedLogCount" namespace = "TaskLogMetrics" value = "1" } } resource "aws_cloudwatch_metric_alarm" "task_failed_log_alarm" { alarm_name = "TaskFailedLogAlarm" comparison_operator = "GreaterThanOrEqualToThreshold" evaluation_periods = "1" metric_name = aws_cloudwatch_log_metric_filter.task_failed_log_metric_filter.metric_transformation[0].name namespace = aws_cloudwatch_log_metric_filter.task_failed_log_metric_filter.metric_transformation[0].namespace period = "60" statistic = "Sum" threshold = "1" alarm_description = "Alarm when there are task failed log entries" actions_enabled = true alarm_actions = [ aws_sns_topic.unpaid_notificate.arn(任意の通知先) ] } |
上記のコードを見てみると、次のような見慣れないリソースが登場します。
1 |
aws_cloudwatch_log_resource_policy |
この設定、実はコンソールから設定・確認できないパラメータになっています。
AWS CLI からは以下の様に確認することができます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
aws logs describe-resource-policies --no-cli-pager { "resourcePolicies": [ { "policyName": "AWSLogDeliveryWrite20150319", "policyDocument": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Sid\":\"AWSLogDeliveryWrite\",\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"delivery.logs.amazonaws.com\"},\"Action\":[\"logs:CreateLogStream\",\"logs:PutLogEvents\"],\"Resource\":\"arn:aws:logs:ap-northeast-1:786813063316:log-group:/aws/api_gw/unpaid-api:log-stream:*\",\"Condition\":{\"StringEquals\":{\"aws:SourceAccount\":\"AWSAccountID\"},\"ArnLike\":{\"aws:SourceArn\":\"arn:aws:logs:ap-northeast-1:AWSAccountID:*\"}}}]}", "lastUpdatedTime": 1712559794739 }, { "policyName": "LogEventsPolicy", "policyDocument": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Principal\":{\"Service\":[\"delivery.logs.amazonaws.com\",\"events.amazonaws.com\"]},\"Action\":[\"logs:CreateLogStream\",\"logs:PutLogEvents\"],\"Resource\":\"arn:aws:logs:ap-northeast-1:AWSAccountID:log-group:/aws/events/ECSStoppedTasksEvent:*\"}]}", "lastUpdatedTime": 1720579910972 } ] } |
リソースポリシーは「〇〇からのアクセスは許可する」というルールです。
コンソールからAmazon EventBridgeを作成すると自動で作られるようですが、Terraformで宣言する場合は明示的に宣言してあげる必要があります。
おわりに
今回はTerraformを利用する場合のAmazon EventBridgeとAmazon CloudWatch Logsを連携する方法について紹介しました。
Terraformを利用して構築する場合、ご参考になれば幸いです。