🎹

【コンソール & Terraform】SNSの通知をEventBridgeの入力トランスフォーマーでわかりやすくする

2023/06/26に公開

はじめに

前回はLambdaでEventBridge + SNSの通知を見やすく編集しました。
実はEventBridgeには入力トランスフォーム(input transformation)という機能があります。
この機能でも通知するテキストをカスタマイズできるので、今回はこちらを使用してみます。

入力トランスフォーマーについてはこちら
https://docs.aws.amazon.com/ja_jp/eventbridge/latest/userguide/eb-transform-target-input.html

イメージ図

できること

Lambdaを使わず、このようにカスタムされた文面の通知を送信できます。

メリット

テキストカスタマイズのためにLambdaコードを作成する必要がありません。

デメリット

複雑なことを行う場合は入力トランスフォームで対応しきれない可能性があります。
その場合はLambdaを使用しましょう。

例)イベント内の時間をUTC→JSTに変換したい

方針

こちらの環境を使います。
https://github.com/not75743/FIS-Terminate-SpotInstance

スポットインスタンスの中断通知イベントの文面を編集しましょう。
コンソールで試してから、Terraform化して応用できるようにします。

環境

Terraform 1.4.6
AWSプロバイダ 4.65.0

検証

設定箇所

ターゲット設定の際
ターゲット入力を設定から入力トランスフォーマーを選択することで設定可能です。

設定

サンプルイベント

スポットインスタンスの中断イベントであるEC2 Spot Instance Interruption Warningのサンプル値を選択します。
この内容をカスタマイズするわけですね。

{
  "version": "0",
  "id": "1e5527d7-bb36-4607-3370-4164db56a40e",
  "detail-type": "EC2 Spot Instance Interruption Warning",
  "source": "aws.ec2",
  "account": "123456789012",
  "time": "1970-01-01T00:00:00Z",
  "region": "us-east-1",
  "resources": ["arn:aws:ec2:us-east-1b:instance/i-0b662ef9931388ba0"],
  "detail": {
    "instance-id": "i-0b662ef9931388ba0",
    "instance-action": "terminate"
  }
}

ターゲット入力トランスフォーマー

通知テキストで使用するイベントの値を選択します。
以下の例ではイベントから、インスタンスID・中断通知時間を抜き出しそれぞれ変数に格納しています。

{
    "Instance": "$.detail.instance-id",
    "InterruptionNotice": "$.time"
}

テンプレート

通知する文面を設定します。
前手順で設定した変数InstanceInterruptionNoticeを使用します
以下のようにしました。

"インスタンスID: <Instance>"
"通知を受け取った時間: <InterruptionNotice>"

プレビュー

出力を生成することで実際の出力を確認することができます

インスタンスIDと通知時間が正常に出力されることを確認します。
ここではサンプルイベントの値ですね。

インスタンスID: i-0b662ef9931388ba0"
"通知を受け取った時間: 1970-01-01T00:00:00Z

動作確認

EventBridgeのトリガーを起動させ、通知を飛ばします。
テンプレート通りの通知がきました!

では再利用できるようにTerraform化します。

Terraform化

ドキュメントにサンプルがあったのでパクリましょう。
https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_event_target#input-transformer-usage---json-object

resource "aws_cloudwatch_event_target" "sns" {
  rule = aws_cloudwatch_event_rule.spot-interruption-rule.name
  arn  = aws_sns_topic.topic.arn

  input_transformer {
    input_paths = {
      Instance = "$.detail.instance-id",
      InterruptionNotice  = "$.time",
    }
    input_template = <<EOF
"インスタンスID: <Instance>"
"通知を受け取った時間: <InterruptionNotice>"
EOF
  }
}

見やすくするためにヒアドキュメントを使用しています。
https://developer.hashicorp.com/terraform/language/expressions/strings#heredoc-strings

おわりに

Lambdaを作成しなくていいのは大きいですね!
コンソールが親切なので、文面の作成・どのような通知になるのか確認する、というのも容易です。

要件を見ながら、Lambdaと使い分けていきたいですね。

参考

https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/events/CloudWatch-Events-Input-Transformer-Tutorial.html
https://qiita.com/Regryp/items/c55b497f021cc9cd10d5
https://blog.serverworks.co.jp/eventbridge/

Discussion