EventBridgeの内容をStep Functionsで整形してSNSトピックに流す

EventBridgeの内容はそのままだと見づらいことも多く、見栄えを良くしたい場合がある。 そういった場合に、Step Functionsのパスに飛ばして内容を整形することができるよ、というお話。

別途IAMロール、CloudWatch Alarmがすでに作成してある前提。 EventBridgeの内容をStep Functionsに送り、Step Functionsのステートマシン内で整形しSNSトピックへ送信している。

最終的に、下記の様なメールを飛ばせる

# CloudWatch AlarmでCPU使用率が0%になったことを受け取るEventBridge
resource "aws_cloudwatch_event_rule" "ecs_cpu_utilization_zero_rule" {
  name          = "ecs-task-connectivity-rule"
  description   = "Capture ECS Tasks Connectivity Alarm Rule"
  event_pattern = <<EOF
{
  "source": ["aws.cloudwatch"],
  "detail-type": ["CloudWatch Alarm State Change"],
  "resources": [
    "${aws_cloudwatch_metric_alarm.ecs_cpu_utilization_zero.arn}"
  ],
  "detail": {"state": {"value": ["ALARM"]}}
}
EOF
}

# EventBridgeとStep Functionsを連携するターゲット
resource "aws_cloudwatch_event_target" "ecs_task_connectivity_event" {
  rule     = aws_cloudwatch_event_rule.ecs_cpu_utilization_zero_rule.name
  arn      = aws_sfn_state_machine.ecs_task_connectivity_state_machine.arn
  role_arn = aws_iam_role.sfn_execution_role.arn
}

# EventBridgeの通知内容を整形してSNSを送るStep Functions
resource "aws_sfn_state_machine" "ecs_task_connectivity_state_machine" {
  name     = "ecs-connectivity"
  role_arn = aws_iam_role.publish_sns_role.arn

  definition = <<EOF
{
  "StartAt": "InputToOutput",
  "States": {
    "InputToOutput": {
      "Type": "Pass",
      "Parameters": {
        "serviceName.$" :"$.detail.configuration.metrics[0].metricStat.metric.dimensions.ServiceName",
        "failedMessage": "ECSの死活監視が失敗しました。"
      },
      "ResultPath": "$.input",
      "Next": "PublishSns"
    },
    "PublishSns": {
      "Type": "Task",
      "Resource": "arn:aws:states:::sns:publish",
      "Parameters": {
        "TopicArn": "${var.infra_alert_sns_topic}",
        "Message.$": "States.Format('{} \n \n 死活監視が失敗したリソース: {}',$.input.failedMessage , $.input.serviceName)",
        "Subject": "ECSの死活監視が失敗しました"
      },
      "End": true
    }
  }
}
EOF
}

参考

自分が使っためちゃくちゃわかりやすい参考書。