CFNでSNS入門 – email版

CFNでSNS入門 - email版

CFNでSNS入門 – email版

AWS SNSはメッセージングサービスです。

今回は入門編ということで、通知先にEmailを指定する方法をご紹介します。

構築する環境

Diagram of introduction to SNS with CFN.

2種類のリソースを作成します。

1つ目はSNSトピックです。
サブスクライバーとして、メールアドレスを指定します。

2つ目はLambda関数です。
SNSトピックにメッセージを送信するパブリッシャーとして動作します。
関数のランタイム環境はPython3.8とします。

CloudFormationテンプレートファイル

上記の構成をCloudFormationで構築します。
以下のURLにCloudFormationテンプレートを配置しています。

https://github.com/awstut-an-r/awstut-fa/tree/main/067

テンプレートファイルのポイント解説

SNSトピック

Resources:
  Topic:
    Type: AWS::SNS::Topic
    Properties:
      Subscription:
        - Endpoint: !Ref MailAddress
          Protocol: email
      TopicName: !Ref Prefix
Code language: YAML (yaml)

Subscriptionプロパティがポイントです。
メッセージをメールに送信する場合は、内部の2つのプロパティを設定します。
Protocolプロパティに「email」を指定します。
Endpointプロパティにメールアドレスを指定します。

Lambda関数

Resources:
  Function:
    Type: AWS::Lambda::Function
    Properties:
      Architectures:
        - !Ref Architecture
      Environment:
        Variables:
          REGION: !Ref AWS::Region
          TOPIC: !Ref TopicArn
      Code:
        ZipFile: |
          import boto3
          import json
          import os

          topic = os.environ['TOPIC']
          region = os.environ['REGION']

          client = boto3.client('sns', region_name=region)

          def lambda_handler(event, context):
            response = client.publish(
              TopicArn=topic,
              Subject='hogehoge',
              Message='fugafuga'
              )

            return {
              'statusCode': 200,
              'body': json.dumps(response, indent=2)
            }
      FunctionName: !Sub "${Prefix}-function"
      Handler: !Ref Handler
      Runtime: !Ref Runtime
      Role: !GetAtt FunctionRole.Arn
Code language: YAML (yaml)

Environmentプロパティで関数に渡すことができる環境変数を定義できます。
先述のSNSトピックのARNや、トピックを作成したリージョン情報を渡します。

Lambda関数で実行するコードをインライン表記で定義します。
詳細につきましては、以下のページをご確認ください。

あわせて読みたい
CloudFormationでLambdaを作成する3パータン(S3/インライン/コンテナ) 【CloudFormationでLambdaを作成する】 CloudFormationでLambdaを作成する場合、大別すると以下の3パターンあります。 S3バケットにコードをアップロードする インライ...

実行するコードの内容ですが、以下の通りです。

  1. CloudFormationテンプレートで定義した環境変数を、os.environにアクセスして取得する。
  2. Boto3でSNSクライアントオブジェクトを作成する。
  3. クライアントオブジェクトを使用して、SNSトピックにメッセージをパブリッシュする。
  4. 上記の実行結果をreturn文で返す。

なおメッセージをパブリッシュするためには、題名と本文を指定する必要があります。
今回は検証ということで、テスト用の文字列「hogehoge」と「fugafuga」を指定します。

ちなみに関数用のIAMロールは以下の通りです。

Resources:
  FunctionRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Action: sts:AssumeRole
            Principal:
              Service:
                - lambda.amazonaws.com
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
      Policies:
        - PolicyName: SNSPublishPolicy
          PolicyDocument:
            Version: 2012-10-17
            Statement:
              - Effect: Allow
                Action:
                  - sns:Publish
                Resource:
                  - !Ref TopicArn
Code language: YAML (yaml)

まずAWS管理ポリシーAWSLambdaBasicExecutionRoleを指定して、関数実行のために必要な権限を付与します。
加えて、SNSトピックにメッセージをパブリッシュする権限も付与します。

環境構築

CloudFormationを使用して、本環境を構築し、実際の挙動を確認します。

CloudFormationスタックを作成し、スタック内のリソースを確認する

CloudFormationスタックを作成します。
スタックの作成および各スタックの確認方法については、以下のページをご確認ください。

あわせて読みたい
CloudFormationのネストされたスタックで環境を構築する 【CloudFormationのネストされたスタックで環境を構築する方法】 CloudFormationにおけるネストされたスタックを検証します。 CloudFormationでは、スタックをネストす...

各スタックのリソースを確認した結果、今回作成された主要リソースの情報は以下の通りです。

  • SNSトピック:fa-067
  • Lambda関数のFunction URL:https://sh53ix7pkfnajqekan4qgeol3a0fuhwg.lambda-url.ap-northeast-1.on.aws/

メールアドレスの認証

SNSトピックのサブスクライバーとしてメールアドレスを指定した場合、そのメールアドレスを認証する必要があります。
指定したメールアドレスに、以下のような認証メールが送られてきます。

Authentication to use email address for SNS subscriber 1.

「Confirm subscription」を押下して、認証を進めます。

Authentication to use email address for SNS subscriber 2.

上記のページが表示されて、認証が完了したことがわかります。

リソース確認

AWS Management Consoleから各リソースを確認します。
まずSNSトピックを確認します。

Detail of SNS.

正常にSNSトピックが作成されていることがわかります。

加えて、サブスクライバーとして登録したメールアドレスが登録されていることもわかります。
またこのメールアドレスのStatusの値を見ると「Confirmed」とあり、認証が完了していることもわかります。

動作確認

準備が整いましたので、実際の動作を確認します。

動作確認はLambda関数のFunction URLにアクセスする形で行います。

Function URLに関する詳細は、以下のページをご確認ください。

あわせて読みたい
CFNでLambda Function URL – 認証方式: NONE 【CloudFormationでLambda Function URLを作成する(NONEバージョン)】 2022年4月22日にLambda Function URLがリリースされました。 この新機能は、AWS Lambda サービス...
Result of Lambda Function.

正常に結果が返ってきました。
関数が正常に動作したということがわかります。

以下が指定したアドレスに送られてきたメールです。

SNS Message.

検証用で指定した題名と本文のメールが届きました。
このようにSNSトピックのサブスクライバーとしてメールアドレスを指定できることがわかりました。

まとめ

SNSトピックの通知先にEmailを指定する方法をご紹介しました。