異なる Kinesis Data Streams アカウント間で SES 通知をストリーミングする方法を教えてください。

最終更新日: 2020 年 5 月 13 日

別のアカウントの Amazon Kinesis データストリームにデータを送信するように、Amazon Simple Email Service (Amazon SES) イベント通知を設定しようと考えています。どうすればできますか?

簡単な説明

別のアカウントの Amazon Kinesis データストリームへの Amazon SES イベント通知を設定するには、次の手順を実行します。

1.    SES ソースから開始します。SES の設定を更新して、Amazon Simple Notification Service (Amazon SNS) トピックにプッシュします。更新された設定は、トピックとしてトリガーとしてサブスクライブするように AWS Lambda を設定します。

2.    SNS に登録します。

3.    クロスアカウントアクセスをセットアップします。

4.    データを Amazon Kinesis Data Streams に送信するように Lambda を設定します。次に、Lambda はコードを使用して、Amazon SNS トピックから完全なイベントを取得します。Lambda は、別のアカウントのロールを引き受け、レコードをデータストリームに配置します。

5.    Amazon Kinesis クライアントライブラリ (KCL) を使用して、ストリーム内のレコードを処理します。

解決方法

SES ソースから開始

SES 環境を作成し、メールアカウントをリストに追加します。E メールアカウントを確認し、サービスを通じて自分の E メールアドレスに E メールを送信します。テスト中に発生する可能性のあるすべてのイベントタイプを追跡するために、E メールの設定セットをセットアップします。設定セットで、デフォルトの追跡ドメインを使用して、宛先を Simple Notification Service (SNS) に設定します。

注意: トピックは、設定セットを作成するときに作成することも、セットを作成する前に作成することもできます。

設定セットの詳細については、「Amazon SES 設定セットの使用」を参照してください。

SNS にサブスクライブする

作成された通知トピックをテストするには、SNS トピックで自分の E メールアドレスを一時的にサブスクライブできます。これにより、SES から送信されるメッセージの通知を確実に受信できます。Lambda を設定するときは、サブスクリプションリストを参照する必要があることに注意してください。

重要: テスト時の open または click イベントは、HTML 形式の E メールでのみ追跡できます。これは、AWS が追跡トークンを含む非表示の GIF 画像を埋め込むためです。この追跡トークンは、開かれた通知 E メールを追跡し、イベントのフィードバックをトピックに送信します。

SES と SNS が統合されたら、SES コンソールを使用して、統合が成功したかどうかを確認できます。SES コンソールの左側にある [E メールアドレス] を選択します。次に、[テスト E メールの送信] ボタンを選択し、E メール形式として [] を選択します。

注意: フォーマット済みオプションを使用している場合、E メールは HTML で送信されません。その結果、open および click の E メールイベントのフィードバックも送信されません。

コンソールでは次のテンプレートを使用できます。

Subject: Amazon SES Raw Email Test
MIME-Version: 1.0
Content-Type: text/html
X-SES-CONFIGURATION-SET: SESxLMxKIN
<!DOCTYPE html>
<html>
<body>
<h1>This text should be large, because it is formatted as a header in HTML.</h1>
<p>Here is a formatted link: <a href="https://docs.aws.amazon.com/ses/latest/DeveloperGuide/Welcome.html">Amazon Simple Email Service Developer Guide</a>.</p>
</body>
</html>

このサンプルテンプレートでは、設定セット名がヘッダーに含まれていることに注意してください。選択したイベントの設定を使用するために、設定セット名が含まれています。この設定セットでは、受信トレイの E メールで実行されたすべてのアクションについて、E メールと通知が送信されます。SNS の詳細については、「Amazon SNS 通知の設定」を参照してください。

クロスアカウントアクセスのセットアップ

別のアカウントにメッセージを送信するための設定を作成します。これには、別のアカウントでロールを引き受けるためのロールとポリシーが必要です。

注意: 宛先のアカウントで引き受けるロールが必要です。Lambda の実行ロールと引き受けるロールも作成する必要があります。引き受けるロールには、必要なサービスを操作するためのアクセス許可があります。

SES と Lambda を使用するアカウントのサンプルテンプレートを次に示します。これは Lambda 実行ロールにアタッチする必要があります。

{
    "Version": "2012-10-17",
    "Statement": {
        "Effect": "Allow",
        "Action": "sts:AssumeRole",
        "Resource": "arn:aws:iam::222222222222:role/role-on-source-account"
    }
}

以下に示しているのは、データストリームを持つアカウントのサンプルテンプレートです。これは、Lambda が引き受ける新しいロールにアタッチする必要があります。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::111111111111:role/my-lambda-executionrole-source-account"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}

このテンプレートは、Lambda 実行ロールの信頼関係を定義します。Lambda 実行ロールは、データを Kinesis データストリームに配信するロールを引き受けます。

注意: Lambda が引き受ける役割には、レコードを Kinesis データストリームに配置するためのアクセス許可が必要です。

Kinesis Data Streams にデータを送信するように Lambda を設定する

次のようなテンプレートを使用して、データストリームにデータを送信するように Lambda を設定できます。

from __future__ import print_function
import base64 #Kinesis only accepts base64 encoded payloads. 
import boto3  #Allow programmatic access to AWS services.
import json
print('Loading function')
def lambda_handler(event, context):
    # Setting up the assumeRole for cross-account
    sts_connection = boto3.client('sts')
    acct_b = sts_connection.assume_role(
        RoleArn="arn:aws:iam::[ADD_ACCOUNT_ID]:role/AssumeLambdaCrossAccount", #TODO: Add relevant role ARN
        RoleSessionName="cross_acct_lambda"
    )
    print(acct_b)
    
    ACCESS_KEY = acct_b['Credentials']['AccessKeyId']
    SECRET_KEY = acct_b['Credentials']['SecretAccessKey']
    SESSION_TOKEN = acct_b['Credentials']['SessionToken']
    
    #Gets the SNS message that was posted (cliks, opens, sends, deliveries etc.)
    message = event['Records'][0]['Sns']['Message'] #Fetching the message in the JSON structure received.
    print("From SNS: " + message) #Checking the message received from SNS.
    
    #TODO:Generate a random partitionKey for kinesis. 
    #If a random partitionKey is not used in a multi shard stream it will lead to performance problems
    #PartitionKey = RandomKey
    
    print("Add data to cross-account stream")
    kinesis_client = boto3.client('kinesis',region_name="us-east-1",aws_access_key_id=ACCESS_KEY,aws_secret_access_key=SECRET_KEY,aws_session_token=SESSION_TOKEN) #Initiates the kinesis service with cross-account credentials.. 
    kinesis_client.put_record(StreamName="CrossAccountTest",Data=json.dumps(message),PartitionKey="partitionKey")

このサンプル Python コードでは、RoleArn をご使用の環境に合わせてストリーム名とリージョンに置き換えます。この関数は、宛先アカウントからのロールを引き受けて、SES から受信した SNS メッセージを受け取ります。次に、引き受けたロールは、宛先ストリームにメッセージを配信します。

Lambda を SNS トピックのサブスクライバーとして設定するには、次の手順に従います。

1.    Amazon SNS コンソールにサインインします。

2.    ナビゲーションペインで、[トピック] を選択します。

3.    [トピック] ページで、トピックを選択します。

4.    [サブスクリプション] セクションで、[サブスクリプションの作成] を選択します。

5.    [サブスクリプションの作成] ページで、選択したトピック ARN を確認します。

6.    プロトコルタイプとして [AWS Lambda] を選択します。

7.    関数の Amazon リソースネーム (ARN) を入力して、エンドポイントを確立します。

8.    [サブスクリプションの作成] を選択します。

Lambda を SNS のサブスクライバーとして使用する方法の詳細については、「サブスクライバーとして AWS Lambda 関数を使用したシステム間メッセージングに Amazon SNS を使用する」を参照してください。

Lambda によってサブスクライブされている SNS トピックにメッセージが発行されると、Lambda は発行されたメッセージのペイロードとともに呼び出されます。サンプルのメッセージ履歴ストアを作成する方法の詳細については、「Amazon SNS を介した AWS Lambda 関数の呼び出し」を参照してください。

注意: クロスアカウントアクセスを設定しない場合は、[認証情報] セクションを削除して、ローカルの Kinesis データストリームに書き込むことができます。Lambda および Python での Kinesis の使用の詳細については、AWS Boto3 ドキュメントの Kinesis を参照してください。

KCL を使用してレコードを処理する

KCL を使用して、Kinesis データストリームのレコードを処理できます。データが Kinesis データストリームに保存されると、カスタムアプリケーションを構築し、分析と視覚化のために Kinesis Data Analytics を実装できます。


この記事はお役に立ちましたか?

改善できることはありますか?


さらにサポートが必要な場合