EventBridgeとSNSで複数行のメール通知を送る方法をCloudFormationから試してみた
データアナリティクス事業本部の鈴木です。
最近はAmazon EventBridgeとCloudWatch Alarmを使って、いいかんじのメール通知を送ることに凝っています。
今回はEventBridgeルールの入力トランスフォーマーを使って複数行のメールをSNS経由で送信する設定をCloudFormationからデプロイするのに試行錯誤したので、分かったことをまとめました。
やりたいこと
EventBridgeの入力トランスフォーマーを使って、読みやすいように整形した複数行のメールをメールアドレス宛に送信したいです。
以下のようなメールが届きます。
構成は以下のようなイメージです。
結論
- 入力テンプレートに複数行の文字列を登録するとできる。ただし、各行は二重引用符で閉じるようにする。
- メール本文の各行に
"
が入ってしまうので、Step Functionsなどを挟むとより綺麗なメールを送ることができた。
やってみる
CloudFormationテンプレートの作成
検証用のCloudFormationテンプレートを作成しました。
SQSのキューからのメトリクスを監視してアラームが発火するように設定してあります。
テンプレートは以下です。
AWSTemplateFormatVersion: 2010-09-09 Description: SQS Standard Queue with alerm & notification Parameters: QueueName: Description: Name for queue Type: String SNSTopicName: Description: SNSTopicName for Alarm Type: String NotificationTarget: Description: Email for notification Type: String Resources: # イベント作成用のリソース ## SQSキュー SQSQueue: Type: AWS::SQS::Queue Properties: MessageRetentionPeriod: 1209600 QueueName: !Ref QueueName VisibilityTimeout: 120 ## CloudWatch アラーム SQSAlarm: Type: AWS::CloudWatch::Alarm Properties: AlarmName: !Sub ${QueueName}-alerm ComparisonOperator: GreaterThanThreshold DatapointsToAlarm: 1 EvaluationPeriods: 1 Threshold: 0 Namespace: AWS/SQS Dimensions: - Name: QueueName Value: !Ref QueueName MetricName: ApproximateNumberOfMessagesVisible Period: 60 Statistic: Maximum TreatMissingData: notBreaching # アラーム検出・通知用のリソース ## SNSトピック SnsTopic: Type: AWS::SNS::Topic Properties: TopicName: !Ref SNSTopicName Subscription: - Endpoint: !Ref NotificationTarget Protocol: email ## SNSトピックポリシー EventTopicPolicy: Type: AWS::SNS::TopicPolicy Properties: PolicyDocument: Statement: - Effect: "Allow" Principal: Service: "events.amazonaws.com" Action: "sns:Publish" Resource: "*" Topics: - !Ref SnsTopic ## EventBridge AlarmEvent: Type: AWS::Events::Rule Properties: Description: String EventPattern: !Sub | { "source": ["aws.cloudwatch"], "detail-type": ["CloudWatch Alarm State Change"], "resources": [{"prefix": "arn:aws:cloudwatch:${AWS::Region}:${AWS::AccountId}:alarm:${QueueName}-alerm"}], "detail": {"state": {"value": ["ALARM"]}} } Targets: - Arn: !Ref SnsTopic Id: sns-topic InputTransformer: InputPathsMap: "AlarmName": "$.detail.alarmName" InputTemplate: | "Alarm Change state to Alarm!" "Alarm name : <AlarmName>"
ポイントはハイライト箇所です。
InputTemplate
にブロックスタイルでメールに記載したい複数行の文字列を渡しています。
各行は"
をつけるようにしています。
動作確認
CloudFormationから上記テンプレートをデプロイします。設定したメールアドレスにサブスクリプションの承認メールが届くので、承諾しておきます。
作成されたEventBridgeルールの設定を確認すると、以下のように入力トランスフォーマーが設定されていることが確認できました。
作成されたSQSキューにメッセージを投入し、しばらくするとCloudWatch Alarmがアラーム状態になるので、それに伴いメールが送られてきました。
気になった点
メールの各行の"
は取れないのかな?と思いましたが、以下の公式ドキュメントでも、改行を含むテンプレートを保存する際に Invalid InputTemplate エラーが表示された場合は、各行は必ず二重引用符で閉じるようにしてください。
と記載があり、入力トランスフォーマーを使用する際は必要になりそうでした。
例えば、上記のCloudFormationテンプレートを一部以下のように変えて、スタックをアップデートすると、以下のように失敗しました。
Targets: - Arn: !Ref SnsTopic Id: sns-topic InputTransformer: InputPathsMap: "AlarmName": "$.detail.alarmName" InputTemplate: | Alarm Change state to Alarm! Alarm name : <AlarmName>
CloudFormationからなのが悪いのかな?と思い、作成したEventBridgeルールを手動で変えてみましたが、ドキュメントの通り、Invalid InputTemplate エラーが表示されることが分かりました。
として設定を上書きしようとすると、
のようにエラーが表示されました。
どうしても体裁が気になる場合は、こちらのブログのように、Step Functionsなどもう一層カスタマイズ用のリソースを挟むことで、件名と併せて設定できたので、参考にしてみてください。
CloudWatchアラームとSNSで日本語の件名・本文のメールを送るためのCloudFormationテンプレートを作ってみた | DevelopersIO
最後に
今回はEventBridgeルールの入力トランスフォーマーを使って複数行のメールをSNS経由で送信する設定をCloudFormationからデプロイするのに試行錯誤した結果をまとめてみました。
初めて使われる方で、特にCloudFormationからデプロイされているようなケースだと、何が問題でデプロイが失敗するのか切り分けが難しかったりするので、参考になりましたら幸いです。