はじめに
AWSのシステムを運用していると、手動・自動問わず様々な操作が行われるため、それに応じて多数のイベントが発生します。 その中には重大なエラーなど緊急性の高いイベントもあり、発生した場合には管理者への迅速な通知が求められます。
そのようなニーズに対応するため、通知用のサービスとしてシンプルに扱えるAmazon SNS(Simple Notification Service)を用い、 AWS内で起きたイベントを管理者にメール通知する機能の実装方法及び、Amazon SNSの活用をわかりやすく解説します。
背景
AWSの学習を進める中で、個々のサービスを単体で触るだけでなく、複数のサービスを連携させて一つの仕組みを組み上げる経験を積みたいと考えていました。その最初の題材として選んだのが、今回のAWSで発生したイベントをメールで通知する仕組みです。
そこで、シンプルに導入可能で多様なサービスと連携でき、なおかつリアルタイムな通知が可能なAmazon SNSに着目し、S3のイベントをきっかけにメール通知を行う流れをハンズオン形式で整理することにしました。
通知機能としてSNSを選んだのは、機能自体はシンプルでありながらパブリッシャーとサブスクライバーを疎結合につなぐというイベント駆動の考え方を、最小構成で学べると考えたためです。
目的
今回は、AWSで発生したイベントをSNS経由で指定のメールアドレスへ通知する機能を作成します。 通知するイベントとして、S3バケットのライフサイクルポリシーによるオブジェクト削除を使用します。
本記事の目的は以下の2つです。
Amazon SNSトピックを用いて、AWS内のイベントを通知する方法を習得する。
他のサービスとAmazon SNSを連携する方法を習得する。
概要
Amazon SNSとは
Amazon SNS(Simple Notification Service)はサーバーレスで稼働するAWSのサービスであり、パブリッシャーと呼ばれる発信元から発せられたイベントを、サブスクライバーと呼ばれる受信者に配信します。
このサブスクライバーにはAWS内のサービスであるSQSやLambdaだけでなく、メールアドレスやモバイルプッシュ通知など、 様々な配信先を選択することができ、シンプルながら汎用性の高いサービスとなっています。
また、パブリッシャーも今回採用するS3の他にも様々なAWS上のサービスに対応しているため、AWS上で何かが起きた時に通知が欲しいというケースに適しています。
さらに、SNSは完全マネージドサービスであり、インフラの管理をAWS側の責任範囲で行ってもらえるため、一度設定を終えれば管理コストが軽いのも魅力です。加えて、SNSは複数のサブスクライバーに対し同時かつ即時に通知を行える点も、今回のような目的に適しています。
SNSトピックのタイプ
SNSにはスタンダードとFIFOの二種類のタイプがあり、以下のような違いがあります。
| 項目 | スタンダード | FIFO |
|---|---|---|
| サブスクライバー | HTTP/HTTPS, メールアドレス, Kinesis Data Firehose, Amazon SQS, AWS Lambda, モバイルプッシュ通知, SMS | Amazon SQSのみ |
| メッセージの重複 | 重複の可能性あり | 重複排除を保証 |
| メッセージの順序 | 入れ替わる可能性あり | 厳密な順序付けを保証 |
| 料金 | 安価 | スタンダードと比べ高額 |
上記のように、スタンダードはサブスクライバーの候補が多いため利便性が高く、一方でFIFOは在庫管理や金融系など、通知の重複や順序の入れ替わりが許されない厳格なシステムに適しています。
実装
実装の手順は以下の通りです。
- メール通知用のSNSトピックを作成する。
- 送信先メールアドレスをSNSのサブスクリプションに設定する。
- イベントを発生させるため、S3バケットを作成する。
- S3バケットにダミーファイルをアップロードし、ライフサイクルポリシーを設定する。
- ライフサイクルポリシーによる削除が発生した際に、SNSへイベント通知を行う設定をする。
- SNSトピックからの通知メールが届くことを確認する。

SNSトピックの作成

SNSトピックには前述の通り「スタンダード」と「FIFO」の2種類が提供されています。 メールアドレスに直接通知できるのはスタンダードのみのため、今回は「スタンダード」を選択します。
タイプを選択しわかりやすい名前を設定すれば、これだけでSNSトピックを作成することができます。
サブスクリプションの設定

サブスクリプションのプロトコルに「Eメール」を選択し、エンドポイントに通知を受け取りたいメールアドレスを設定します。

「サブスクリプションの作成」を実行することで、設定したメールアドレスに確認のメールが届くため、Confirm subscriptionをクリックして承認します。

画像のような表示がされれば成功です。
これで先ほど作成したS3_FileDeleteトピックから、通知として設定したメールアドレスにメールを送信してもらえるようになりました。
S3バケットの作成
次に、パブリッシャーとなるS3バケットを作成します。

今回は単純にデータの保存用として活用するため、バケット名のみを定め、他の設定はデフォルトのままバケットを作成するだけで問題ありません。
ファイルのアップロードと設定

イベントのトリガーとするため、手元にダミーのファイル(dummy.txt)を用意します。
先ほど作成したS3バケットの画面を開き、「ファイルを追加」からアップロードしてください。


次に、バケットを開いた画面の「管理」からライフサイクルポリシーを作成します。
- オブジェクトの現行バージョンを有効期限切れにする
にチェックを入れ、「オブジェクトの現行バージョンの有効期限が切れる」日数を1日に設定します。 これにより、S3にアップロードされたオブジェクトは1日で有効期限が切れ、削除されるライフサイクルポリシーが設定されました。
S3からのイベント通知の設定


サービス単位での準備が整ったので、最後にS3からSNSへイベント通知をする設定を行います。 S3のテスト用のバケットを開き「プロパティ」から「イベント通知を作成」をクリックします。
わかりやすいイベント名を設定し、今回はS3の機能であるライフサイクルポリシーによってオブジェクトが削除されたことを通知するため、 「すべてのライフサイクルの有効期限イベント」にチェックを入れます。

最後に、通知先としてSNSを選択し、先ほど作成したS3_FileDeleteSNSトピックを選択します。
メール通知の確認
S3のライフサイクルポリシーは1日1回適用されます。
イベント通知設定および、SNSのサブスクライバー設定が正しく完了していれば、削除時にSNSトピックから通知メールが届きます。
{
"Records": [
{
"eventVersion": "2.3",
"eventSource": "aws:s3",
"awsRegion": "ap-northeast-1",
"eventTime": "yyyy-MM-ddThh:mm:ss.fffZ",
"eventName": "LifecycleExpiration:Delete",
"userIdentity": {
"principalId": "s3.amazonaws.com"
},
"requestParameters": {
"sourceIPAddress": "s3.amazonaws.com"
},
"responseElements": {
"x-amz-request-id": "XXXXXXXXXXXXX",
"x-amz-id-2": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
},
"s3": {
"s3SchemaVersion": "1.0",
"configurationId": "s3-deleteobject",
"bucket": {
"name": "{dummy-bucket-name}",
"ownerIdentity": {
"principalId": "XXXXXXXXXXXX"
},
"arn": "arn:aws:s3:::{dummy-bucket-name}"
},
"object": {
"key": "dummy.txt",
"sequencer": "XXXXXXXXXXXX"
}
}
}
]
}
ライフサイクルポリシーによるdummy.txtの削除が、LifecycleExpiration:DeleteイベントとしてSNS経由で通知されたことを確認できました。
考察
今回のハンズオンを通して、Amazon SNSというサービスを実装する手軽さを実感しました。 そしてこの手軽さは、イベント通知という要件に対し、開発・運用コストを抑えられるという点で大きな利点だと感じました。
AWSのサービスは多岐にわたるため、同じ目的を実現する方法が複数あることも珍しくありません。そのため、機能要件だけでなく、要件の背景や規模に応じて最適なサービスを選択することが、AWSのアーキテクチャを構築する上で重要です。
例えば今回のハンズオンの内容(S3イベントのメール通知)についても、Amazon SNSでなく、AWS LambdaとAmazon SESを組み合わせることでも実現可能です。
しかし、複数のサービスを挟むことで、利用者1名が通知を受け取るというシンプルな要件に対しては開発・運用コストが嵩みます。 Amazon SNSであれば今回のハンズオンの通り、ネイティブ機能でS3をパブリッシャーに設定可能で、Eメールアドレスをサブスクライバーに設定するだけでアーキテクチャが完成します。

一方で、もし要件がS3をコンテンツ配信に利用しており、新コンテンツの追加を数万人規模のクライアントにメールで通知するであった場合は、内容を整形したメールを一斉配信できるという特徴のあるAmazon SESが有効です。
なぜならAmazon SNSには、サブスクリプションの登録に受信者の個別承認が必要な点や、本文がJSON形式のままで体裁を整えにくい点など、多数の一般クライアントへの配信には不向きな特徴があるためです。

このように、利用者数という要件の違いだけでも適したサービスは変化します。
こうした比較を重ねて選択肢の引き出しを増やしていくことが、AWSのアーキテクチャを設計する上で欠かせない能力だと実感しました。
まとめ
今回はAmazon SNSを用いて、S3で発生したオブジェクト削除イベントを通知することができました。
SNSはパブリッシャーにEventBridge・CloudWatch等を、サブスクライバーにLambda・SQS等を設定でき、今回のようなメール通知にとどまらず幅広いAWSサービス連携に活用できます。
今回のハンズオンを通して、AWSへの理解と関心を深めていただければ幸いです。
We Are Hiring!
Amazon SNSとS3を連携させたイベント通知の構築を通して、AWSという技術に関心を持ち、実務でも携わってキャリアを広げたいと感じた方もいるかと思います。
FindConsultingには、異業種から転身してAWSエンジニアとして活躍するメンバーや、SQLのみのスキルからPython・Reactでの開発案件に挑戦するメンバーなど、入社後にキャリアを大きく広げた社員が多くいます。
資格取得支援や実案件への早期参画など、次のステップへ踏み出すための環境が整っています。
「今のスキルだけでは先が不安」「新しい領域に挑戦してキャリアを広げたい」と感じている方は、ぜひ一度話を聞きに来てください。
現在、FindConsultingではキャリアチェンジ・スキルアップを目指す仲間を募集しています。
転職を迷っている段階でも構いません。まずはカジュアル面談でお気軽にご相談ください。


