EventBridge、AWS Lambda、Amazon SNSで、Lambda定期実行＆メール通知を作ってみた

# 概要
こんにちは。
今回は、タイトルにもある通り以下のような内容でリソースを作ってみたので、そのまとめです。
今回はSNS、Lambda、EventBridgeをそれぞれ別々に作成しましたが、Lambdaの作成画面にある「トリガーを追加」からEventBridgeの定期スケジュール実行の作成、「送信先を追加」からSNSのトピック先選択とパブリッシュに必要なIAMロールの自動作成などが行えます。
（それぞれ別で作成した後に気づきました）


**作ったもの：**
- EventBridgeスケジューラを使ってLambdaの定期実行
- Lambdaの関数内で、Amazon SNSトピックにメッセージを送信（パブリッシュ）
- Amazon SNSからメール通知

**きっかけ：**
自身で作りたいと思ったシステムを実現する際に、今回作成した構成が必要だったため、そのテストとして作ってみました。
（結局、作りたかったシステムは別の部分で問題があり、作業は止まっていますが…）

**参考にさせていただいた記事：**
- [LambdaとSNSの連携部分](https://zenn.dev/nakam_aws/articles/6562e07cfae4fd)
- [EventBridgeスケジューラの作成部分](https://note.com/standenglish/n/n6b8b5c1563a8)

# 構成図
構成図は以下のようになります。

![AWS-qiita-eventbridge-lambda-sns.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689201/c1a56bb0-9614-198b-b95e-b891c97987fd.jpeg)



# 実際にやったこと

LambdaとSNSを連携して、Lambdaを実行するとSNSからメールを送信するようにします。
また、そのEventBridgeの定期実行スケジューラにLambdaを登録することで定期的にメール送信を行えるようにしました。

## 1. SNSトピックの作成
この章では以下のことをやりました。
1. SNSトピックの作成
1. サブスクリプションの作成

まず、AWSコンソールの画面から「SNS」と検索し、SNSのサービスを開きます。
SNSの画面から「トピックの作成」をクリックします。

トピックの作成画面で、
- トピックタイプ
- 名前
を入力し、

![01-SNSトピック作成.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689201/6daabdd4-fba6-49bd-8dab-62b2757f9e75.png)


ページ下部の「トピックの作成」をクリックします。

![02-SNSトピック作成.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689201/ce738dd1-786f-45b3-8373-59d42b6ffbee.png)




ここまででトピックの作成が完了です。


次にサブスクリプションの作成を行います。
トピックの下にサブスクリプションを登録することで、トピックにパブリッシュされたとき、サブスクリプションに登録したエンドポイントに通知が飛ぶようになります。
![SNSサブスクリプション送信先.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689201/f1113761-6290-4e69-b783-96ffce125b52.png)

今回は、メール通知をしたいので、「Eメール」を使用します。
トピック作成完了後、以下のような画面が出るので、「サブスクリプションの作成」をクリックします。

![03-SNSトピック作成.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689201/4dd4bc87-e901-4e49-9435-f3a0b8379302.png)




プロトコル→Eメール
エンドポイント→任意のメールアドレス
というように設定し、画面一番下の「サブスクリプションの作成」をクリックします。

![04-SNSトピック作成.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689201/23117663-0654-49c0-990b-9f658b675174.png)


ここで、サブスクリプションの登録確認メールが登録したメールアドレス宛に届きます。
**確認メールで確認を行うまでは、サブスクリプションのステータスが「保留中の確認」となっています。
確認メールを開き、「Confirm subscription」をクリックします。**
遷移先のブラウザで「Subscription Confirmed」と表示されれば登録完了です。

ブラウザで「Subscription Confirmed」と表示された後、念のため、サブスクリプションのステータスが「確認済み」となっていることを確認します。

![サブスクリプションのステータス確認.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689201/9054869d-600c-4dcf-938d-c721e75801df.png)



## 2. Lambda関数の作成とSNSとの連携
この章では以下のことをやりました。
1. Lambda関数の作成
1. SNSへのパブリッシュを許可するIAMロール作成
1. Lambdaへのコードのデプロイ＆テスト


### Lambda関数の作成

まずは、左上の検索欄に「Lambda」と入力し、Lambdaのダッシュボードに移動します。
「関数の作成」ボタンをクリックし、関数の作成を始めます。

![05-Lambda関数ダッシュボード.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689201/be3e5f5d-3c6e-43b4-b8e3-8ebd35cd9a32.png)

一から作成を選び、関数名を入力します。
今回はPythonコードでSNSへのメール送信を行うので、ランタイムにはPythonを選択します。

![05-Lambda作成.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689201/9f2da30d-3af7-4532-aa3d-4fcadab784e9.png)


ほかの項目はそのままに、画面下の「関数を作成」ボタンをクリックして関数を作成します。

そうすることでLambda関数の作成が行えます。

![07-Lambda作成完了.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689201/e208fdbc-f663-4175-8c3a-7ac194d4da10.png)


### SNSへのパブリッシュを許可するIAMロール作成

次に、SNSへのパブリッシュを許可するIAMロールを作成していきます。
今回はIAMロールを自身で作成する方法で進めました。
最初にも記載しましたが、Lambdaの関数画面にある「送信先を追加」を使うことで簡単にSNSトピックとの連携ができます。
(Lambdaの関数画面にある「送信先を追加」から先ほど作成したSNSトピックを指定し、アクセス権限で「必要なアクセス許可を追加」を選択することで、LambdaからSNSにパブリッシュするためのIAMロールが自動的に付与されます。)

では実際にIAMロールを作成していきます。

まずは先ほど作成したLambda関数に付与されているIAMロールの編集画面に遷移します。
タブから「設定」を選択し、サイドバーから「アクセス権限」を選択します。
そして、ロール名をクリック（画像のsns-test-role-7817uabeの部分）します。

![07-IAMロール作成画面遷移.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689201/907d0cb2-aac1-4b49-af15-7b83e51e79df.png)

クリックすると、そのIAMロールの画面に遷移します。
ここで「許可を追加」をクリックし、「ポリシーをアタッチ」を選択します。

![08-許可を追加.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689201/aea8df9d-1899-44e7-bff8-668bdbdd8940.png)

LambdaからSNSトピックへのパブリッシュを許可するポリシーである「AWSLambdaSNSTopicDestinationExecutionRole」を追加します。
（もう一つのポリシーは、LambdaがCloudWatch Logsにログを出力するための最低限の権限を持つデフォルトのIAMポリシーです。関数作成時にデフォルトの実行ロールで自動付与を選択するとこのポリシーを含んだロールが付与されます。）
![09-IAM.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689201/2d447eff-81b0-4fae-914f-5781e451c192.png)

これでIAMロールの作成が完了です。


### Lambdaへのコードのデプロイ＆テスト

続いて、Lambdaにコードをデプロイしていきます。
先ほど作成したLambdaを開き、赤枠の部分のコードタブからコードソースをデプロイしていきます。

![10-Lambdaのコード.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689201/6eb8e5b3-c09d-4f55-b341-3ae21cb7d08d.png)


今回は以下のコードをデプロイしていきます。
**TopicArnには、先ほど作成したSNSトピックのARNを入力してください**

```python:lambda_function.py
import boto3
client = boto3.client('sns')

def lambda_handler(event, context):
    
    params = {
    'TopicArn': '{先ほど作成したSNSのARN｝',
    'Subject': 'SNSからメールを送信',
    'Message': 'メールを送信\nテスト'
    }
    
    client.publish(**params)

```

コードを載せたら、以下の画像のボタンからデプロイをします。
**SNSトピックのARNの部分の修正やデプロイを忘れると正しく動作しないので気を付けてください。**

![11-Lambdaデプロイ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689201/378ab38a-6409-47e0-b424-a8cf27ea27cd.png)

最後に、Lambdaを実際に動かしてメールが送信されるかどうかをテストします。

画像のように「テスト」タブを開き、任意の「イベント名」を入力した後、「テスト」ボタンをクリックします。

![12-Lambdaテスト.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689201/84895111-f937-4047-8bf9-b24f223783e3.png)

メールが届けば作業完了です。
届かない場合は、以下の点を確認してみてください。
- SNSサブスクリプションのステータスは「確認済み」となっているか
- Lambdaに添付したIAMロールのポリシーが正しいか
- LambdaのコードにSNSトピックのARNが記載されているか
- Lambdaにコードをデプロイしたか


## 3. EventBridgeスケジューラを使ってLambdaの定期実行

この章では以下のことをやりました。
1. EventBridgeのスケジュール作成

### EventBridgeのスケジュール作成

Lambdaを定期的に呼び出すために、EventBridgeのスケジュールを作成していきます。

まずはAWSコンソールの検索欄から「EventBridge」と検索し、EventBridgeを開きます。

![13-EventBridge初期画面.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689201/91c66204-2d49-478a-a31f-9749917c1c21.png)

サイドバーの「スケジュール」を選択し、開かれた画面で「スケジュールを作成」をクリックします。

![14-EventBridgeスケジュールを作成.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689201/bbea41a5-5db2-4968-bfa2-4a213b2bf1ad.png)

「スケジュールの詳細の指定」画面で、それぞれ必要な項目を入力していきます。
- スケジュール名
- 頻度
    - 今回は「rateベースのスケジュール」を指定
- rate式
    - スケジュールを実行する間隔
- フレックスタイムウィンドウ
    - 今回はオフを指定
- 開始日時・終了日時

![15-1-EventBridgeスケジュール名入力.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689201/121131a8-0881-4d9f-b51a-251928dae559.png)

![15-EventBridgeスケジュールパターン指定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689201/7de21a49-d431-4811-96d3-134c16572027.png)

![16-EventBridgeフレックスウィンドウと時間枠指定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689201/82ce9f8f-7259-481f-9458-1ebb3eadf91b.png)

ここまで入力ができたら「次へ」ボタンをクリックします。

次はターゲットの選択です。
Lambdaを呼び出し先として設定します。
「テンプレート化されたターゲット」からLambdaを指定します。
![17-EventBridgeターゲットでLambda指定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689201/04acdb46-421e-4486-9dad-0629643da05a.png)


そして、先ほど作成したLambda関数を指定します。
今回はLambdaへの入力は特にないのでペイロード派からのままにしています。

![18-EventBridge呼び出すLambda選択.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689201/f25bbb47-4d60-4251-b816-5b9bb4b6ffa4.png)

次の「設定-オプション」ページでは、スケジュール完了後のアクションとして「DELETE」を選択し、最後の呼び出しが完了した後スケジュールを削除するようにします。（消さないこともできる）

そして、ほかの項目はそのままに「スケジュールを作成」ボタンをクリックします。


![19-EventBridgeDeleteのみ指定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689201/fa98c6be-96f1-4d79-88ab-0c0d727641a4.png)

![20-EventBridgeスケジュール作成完了ボタン.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689201/2cc82505-5f9e-4ff8-9179-90279045474a.png)

そうすることで、スケジュールの作成が完了します。

![21-EventBridgeスケジュール作成完了.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689201/a7b12469-00aa-4fd9-bf4a-6a7619709ba5.png)

ここまでで、EventBridgeからLambdaを呼び出し、LambdaからSNSにメールを出すよう通知するという処理が完成です。

# まとめ

今回はEventBridge、Lambda、SNSを使用して、メールの定期送信という機能を作成しました。
実際に作ったのは初めてですが、資格を勉強していたことである程度の作業イメージが付きました。
ただし、実際に触ってみてわかったこと（さらに簡単に作るための機能、どのような設定が可能かなど）もあるのでやってみてよかったと感じました。
今後も気になることがあればどんどん触るようにしたいと思います。
わからない点、間違っている点等あればコメントで教えてください。