この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
データアナリティクス事業本部の鈴木です。
最近はAmazon EventBridgeとCloudWatch Alarmを使って、いいかんじのメール通知を送ることに凝っています。
今回はEventBridgeルールの入力トランスフォーマーを使って複数行のメールをSNS経由で送信する設定をCloudFormationからデプロイするのに試行錯誤したので、分かったことをまとめました。
やりたいこと
EventBridgeの入力トランスフォーマーを使って、読みやすいように整形した複数行のメールをメールアドレス宛に送信したいです。
以下のようなメールが届きます。
構成は以下のようなイメージです。
結論
- 入力テンプレートに複数行の文字列を登録するとできる。ただし、各行は二重引用符で閉じるようにする。
- メール本文の各行に
"
が入ってしまうので、Step Functionsなどを挟むとより綺麗なメールを送ることができた。
やってみる
CloudFormationテンプレートの作成
検証用のCloudFormationテンプレートを作成しました。
SQSのキューからのメトリクスを監視してアラームが発火するように設定してあります。
テンプレートは以下です。
template.yml
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テンプレートを一部以下のように変えて、スタックをアップデートすると、以下のように失敗しました。
template.ymlの抜粋
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からデプロイされているようなケースだと、何が問題でデプロイが失敗するのか切り分けが難しかったりするので、参考になりましたら幸いです。