なんのために
メールをトラッキングするため。
“トラッキング” is 何
メールが送信対象者に届いたかや、届いた後にメールが開封されたのか等を追跡すること。
トラッキングすると何が良い
- メールの送信時トラブル(リジェクト、バウンスなど)の検知ができる
- 開封率などのデータ収集が行え、マーケティングに使える
Solution
- Kinesis Data Firehose + Open Search
- Kinesis Data Firehose + Redshift
- Kinesis Data Firehose + S3 ← 今回はこちらを採用
全体像
- iam周り作る
- S3のバケットリソース作る
- sesの構成リソースを作成
- eventの宛先リソースを作成
- Kinesis Data Firehoseを作る
- 諸々つなぎこむ
手始めにiam(role)を作りましょう。ざっくりと、
- kinesisへイベントを流すためのses用のロール
- eventを受け取りS3へputしてくれるkinesis用のロール
の2つのロールを作るイメージです。
iam.tf
// sesに渡すロールにアタッチするAssume Role用のポリシーのドキュメント
data "aws_iam_policy_document" "ses_asssume" {
statement {
sid = ""
effect = "Allow"
actions = [
"sts:AssumeRole"
]
principals {
type = "Service"
identifiers = [
"ses.amazonaws.com"
]
}
}
}
// sesに渡すロール
resource "aws_iam_role" "ses" {
name = "ses"
assume_role_policy = data.aws_iam_policy_document.ses_asssume
}
// sesに渡すロールにアタッチするポリシードキュメント
data "aws_iam_policy_document" "ses" {
statement {
sid = ""
actions = [
"firehose:PutRecord",
"firehose:PutRecordBatch"
]
resources = [aws_kinesis_firehose_delivery_stream.ses.arn]
}
}
// sesに渡すロールにアタッチするポリシー
resource "aws_iam_policy" "ses" {
name = "ses"
path = "/"
policy = data.aws_iam_policy_document.ses.json
}
// ses用ロールにポリシーをアタッチ
resource "aws_iam_policy_attachment" "ses" {
name = "ses"
roles = [aws_iam_role.ses.name]
policy_arn = aws_iam_policy.ses.arn
}
大まかにやることとしては以下のような感じです。
- AssumeRoleのポリシードキュメント作成
- ロールの作成
- ロールにAssumeRoleをアタッチ
- サービス利用のためのポリシードキュメント作成
- ポリシー作成
- ポリシーとドキュメントを紐付け
- ロールにポリシーをアタッチ
aws_kinesis_firehose_delivery_stream.ses_extended_s3_stream.arn
のリソースはあとから作成するので一旦は流しましょう。
同じ流れでkinesis側のロールも作りましょう。
// kinesisに渡すロールにアタッチするAssume Role用のポリシーのドキュメント
data "aws_iam_policy_document" "kinesis_data_firehose_assume" {
statement {
sid = ""
effect = "Allow"
actions = ["sts:AssumeRole"]
principals {
type = "Service"
identifiers = ["firehose.amazonaws.com"]
}
}
}
// kinesisに渡すロール
resource "aws_iam_role" "kinesis_data_firehose" {
name = "kinesis"
assume_role_policy = data.aws_iam_policy_document.kinesis_data_firehose_assume.json
}
// kinesisに渡すロールにアタッチするポリシードキュメント
data "aws_iam_policy_document" "kinesis_data_firehose" {
statement {
sid = ""
effect = "Allow"
actions = [
"s3:AbortMultipartUpload",
"s3:GetBucketLocation",
"s3:GetObject",
"s3:ListBucket",
"s3:ListBucketMultipartUploads",
"s3:PutObject"
]
resources = [
aws_s3_bucket.ses.arn,
"${aws_s3_bucket.ses.arn}/*"
]
}
}
// kinesisに渡すロールにアタッチするポリシー
resource "aws_iam_policy" "kinesis_data_firehose" {
name = "kinesis-data-firehose"
path = "/"
policy = data.aws_iam_policy_document.kinesis_data_firehose.json
}
// kinesis用ロールにポリシーをアタッチ
resource "aws_iam_policy_attachment" "kinesis_data_firehose" {
name = "kinesis-data-firehose"
roles = [aws_iam_role.kinesis_data_firehose.name]
policy_arn = aws_iam_policy.kinesis_data_firehose
}
aws_cloudwatch_log_stream.kinesis_data_firehose.arn
のリソースはあとから作ります。
次にバケットを作ります。
s3.tf
resource "aws_s3_bucket" "ses" {
bucket = "ses-event-log"
acl = "private"
}
sesリソースの作成に参りましょう。
ses.tf
// イベント関連構成セットのリソース
resource "aws_ses_configuration_set" "main" {
name = "main"
}
resource "aws_ses_event_destination" "kinesis_data_firehose" {
name = "kinesis-data-firehose"
configuration_set_name = aws_ses_configuration_set.main.name
enabled = true
matching_types = [
"send",
"reject",
"delivery",
"bounce",
"complaint"
]
kinesis_destination {
stream_arn = aws_kinesis_firehose_delivery_stream.ses.arn
role_arn = aws_iam_role.kinesis_data_firehose.arn
}
}
aws_ses_configuration_set
はメール配信時の受信するイベントやそのイベントの宛先を構成するためのリソースです。
具体的な送信先は aws_ses_event_destination
で設定しています。
この宛先を aws_ses_configuration_set
へセットしているイメージですね。
matching_types
は受け取るイベントのタイプです。それぞれが何を示すのかは公式ページを参照ください。
https://docs.aws.amazon.com/ja_jp/ses/latest/dg/monitor-using-event-publishing.html
kinesis_destination
では実際に受け取ったイベントを宛先に設定しています。
(他にもCloud WatchやSNSも宛先として選択可能なようです。)
そして最後に、主役(?)となるkinesisのリソースを作ります。
kiesisdatafirehose.tf
resource "aws_kinesis_firehose_delivery_stream" "ses" {
name = "ses"
destination = "extended_s3"
extended_s3_configuration {
role_arn = aws_iam_role.kinesis_data_firehose.arn
bucket_arn = aws_s3_bucket.ses.arn
prefix = "ses"
buffer_interval = 60
}
}
destination
は配信先のリソースですね。s3がどうやら非推奨になっていたっぽいので、代わりに extended_s3
を指定しました。拡張設定オプションなるものなるものらしいのですが、細かい違いについてはよくわかっていません。。。
extended_s3_configuration
では色々配信に関する設定が行えます。
ひとまず受信データを宛先に配信するまでのバッファリングをデフォルトの300秒から最小の60秒に変えています。(リアルタイム性を上げたいため)
あとは本記事ではカットしてますが、必要に応じて、cloudwatch_logging_options
などを追加してログ周りの強化を図るなどすれば良さそうですね。
一旦以上で必要最低限のリソース構築はできたかなと思います。
あとはアプリケーションからのメール送信機能などにおいて実際にメールを送信した際にトラッキングを有効にするには、カスタムヘッダーに X-SES-CONFIGURATION-SET
を含む必要があります。
以下のnameとvalueを送ってあげる感じです。
name ... X-SES-CONFIGURATION-SET
value ... main
(これは aws_ses_configuration_set
で作成した構成リソースを指定します。)
具体的な方法についてはアプリケーションに依存する形になるかと思いますのでここでは割愛します。
ここまでの流れでリソースが構築できていればカスタムヘッダーの送信により、イベントのトラッキングが発動し、ログが取れるかなと思います。(内容に不備等がありましたら申し訳ございません。そっと教えてくださいませ。。)
参考
公式
https://aws.amazon.com/jp/premiumsupport/knowledge-center/ses-email-sending-history/
クラメソさん
https://dev.classmethod.jp/articles/amazon-ses-open-click-tracking/