概要
SESでの開封・クリックのトラッキングについてはいくつか記事がありますが、それをTerraformで実現したという情報はあまり見当たらないのでまとめました。
SESはトラッキングデータをCloudWatch、Kinesis Firehose、SNSに送ることができます。
今回はKinesis Firehose経由でS3に保存します。
SESでの開封・クリックの取得の仕組み
開封・クリックのトラッキングには、HTMLメールを使用する必要があります。
開封のトラッキングは、HTMLメールの末尾に画像が添付されることで実現されます。
クリックのトラッキングは、メール内のリンクがSESによって自動的に書き換えられ、あるURLを経由したリダイレクトとなることで実現されます。
variable.tfの記述
variables.tfに変数を定義します。
variable "name_prefix" {
default = "ses-tracking"
}
variable "s3_bucket" {
default = "xxx"
}
main.tfの記述
Provider
SESが利用できるリージョンを指定します。
# ######## #
# Provider #
# ######## #
provider "aws" {
version = "~> 1.51"
region = "us-east-1"
}
S3
# ## #
# S3 #
# ## #
resource "aws_s3_bucket" "bucket" {
bucket = "${var.s3_bucket}"
acl = "private"
force_destroy = true
}
CloudWatch Logs
Kinesis FirehoseのエラーログをCloudWatch Logsに出力するよう、ロググループとログストリームを作成します。
# ############### #
# CloudWatch Logs #
# ############### #
resource "aws_cloudwatch_log_group" "cloudwatch_log_group" {
name = "${var.name_prefix}-cloudwatch-log-group"
}
resource "aws_cloudwatch_log_stream" "cloudwatch_log_stream" {
name = "${var.name_prefix}-cloudwatch-log-stream"
log_group_name = "${aws_cloudwatch_log_group.cloudwatch_log_group.name}"
}
Kinesis Firehose
S3とCloudWatch Logの権限を与えて、Kinesis Firehoseを作成します。
動作確認を素早く行うため、buffer_intervalを最短の60に設定します。
# ####### #
# Kinesis #
# ####### #
resource "aws_kinesis_firehose_delivery_stream" "firehose" {
name = "${var.name_prefix}-kinesis-firehose"
destination = "s3"
s3_configuration {
role_arn = "${aws_iam_role.firehose_role.arn}"
bucket_arn = "${aws_s3_bucket.bucket.arn}"
buffer_size = 5
buffer_interval = 60
cloudwatch_logging_options {
enabled = true
log_group_name = "${aws_cloudwatch_log_group.cloudwatch_log_group.name}"
log_stream_name = "${aws_cloudwatch_log_stream.cloudwatch_log_stream.name}"
}
}
}
resource "aws_iam_role" "firehose_role" {
name = "${var.name_prefix}-firehose-role"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"Service": "firehose.amazonaws.com"
},
"Effect": "Allow",
"Sid": ""
}
]
}
EOF
}
resource "aws_iam_role_policy" "firehose_role_policy" {
name = "${var.name_prefix}-firehose-role-policy"
role = "${aws_iam_role.firehose_role.id}"
policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Action": [
"s3:AbortMultipartUpload",
"s3:GetBucketLocation",
"s3:GetObject",
"s3:ListBucket",
"s3:ListBucketMultipartUploads",
"s3:PutObject"
],
"Resource": [
"arn:aws:s3:::${aws_s3_bucket.bucket.bucket}",
"arn:aws:s3:::${aws_s3_bucket.bucket.bucket}/*"
]
},
{
"Sid": "",
"Effect": "Allow",
"Action": [
"logs:PutLogEvents"
],
"Resource": [
"${aws_cloudwatch_log_stream.cloudwatch_log_stream.arn}:*"
]
}
]
}
EOF
}
SES Configuration Set
Kinesis Firehoseの権限を与えて、SESのConfiguration SetとEvent Destinationを作成します。
matching_typesは必要なものだけ指定しましょう。
メール送信時にこのConfiguration Setを利用することで、トラッキングが行われます。
resource "aws_ses_configuration_set" "ses_configuration_set" {
name = "${var.name_prefix}-ses-configuration-set"
}
resource "aws_ses_event_destination" "kinesis" {
name = "${var.name_prefix}-event-destination-kinesis"
configuration_set_name = "${aws_ses_configuration_set.ses_configuration_set.name}"
enabled = true
matching_types = ["send", "reject", "bounce", "complaint", "delivery", "open", "click", "renderingFailure"]
kinesis_destination = {
stream_arn = "${aws_kinesis_firehose_delivery_stream.firehose.arn}"
role_arn = "${aws_iam_role.ses_role.arn}"
}
depends_on = ["aws_iam_role_policy.ses_role_policy"]
}
resource "aws_iam_role" "ses_role" {
name = "${var.name_prefix}-ses-role"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"Service": "ses.amazonaws.com"
},
"Effect": "Allow",
"Sid": ""
}
]
}
EOF
}
resource "aws_iam_role_policy" "ses_role_policy" {
name = "${var.name_prefix}-ses-role-policy"
role = "${aws_iam_role.ses_role.id}"
policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Action": [
"firehose:PutRecord",
"firehose:PutRecordBatch"
],
"Resource": "${aws_kinesis_firehose_delivery_stream.firehose.arn}"
}
]
}
EOF
}
Terraform実行
$ terraform init
$ terraform apply
※ aws_ses_event_destinationの作成に失敗することがあります。その場合、再度 terraform apply
を実行してください。
送信テスト
AWS CLIを使った以下のシェルスクリプトで送信テストができます。
Configuration Setを指定するのがポイントです。
前述の通り、開封・クリックのトラッキングが可能なのはHTMLメールのみです。
tagsについては、あとでデータを分析する際に利用できます。
#!/bin/bash -eux
TO=xxx
FROM=xxx
SUBJECT='TEST'
TEXT='hello world'
HTML="<h1>hello world</h1><a href='https://www.amazon.co.jp'>Amazon</a>"
CONFIGRATION_SET='ses-tracking-ses-configuration-set'
aws --region us-east-1 ses send-email \
--to $TO \
--from $FROM \
--subject $SUBJECT \
--text $TEXT \
--configuration-set-name $CONFIGRATION_SET \
--tags Name=tag1,Value=value1 \
--html "$HTML"
S3に溜まったデータ
S3には以下のようにデータが保存されていきます。
{"eventType":"Send","mail":...
{"eventType":"Click","mail":...
{"eventType":"Open","mail":...
{"eventType":"Delivery","mail":...