チュートリアル: Amazon Simple Notification Service での AWS Lambda の使用
ある AWS アカウントの Lambda 関数を使用して、別の AWS アカウントにあるAmazon SNS トピックをサブスクライブすることができます。このチュートリアルでは、AWS Command Line Interface を使用して、Lambda 関数の作成、Amazon SNS トピックの作成、これら 2 つのリソースに相互にアクセスするアクセス権限の付与などの AWS Lambda オペレーションを実行します。
前提条件
このチュートリアルでは、基本的な Lambda オペレーションと Lambda コンソールについてある程度の知識があることを前提としています。初めての方は、コンソールで Lambda の関数の作成 の手順に従って最初の Lambda 関数を作成してください。
次のステップを完了するには、コマンドを実行するコマンドラインターミナルまたはシェルが必要です。コマンドと予想される出力は、別々のブロックにリストされます。
aws --version
次のような出力が表示されます。
aws-cli/2.0.57 Python/3.7.4 Darwin/19.6.0 exe/x86_64
コマンドが長い場合、コマンドを複数行に分割するためにエスケープ文字 (\
) が使用されます。
Linux および macOS では、任意のシェルとパッケージマネージャーを使用します。
Windows では、Lambda でよく使用される一部の Bash CLI コマンド (zip
など) が、オペレーティングシステムの組み込みターミナルでサポートされていません。Ubuntu および Bash の Windows 統合バージョンを取得するには、Windows Subsystem for Linux をインストール
このチュートリアルでは、2 つのアカウントを使用します。この AWS CLI コマンドは、それぞれが別のアカウントで使用されるように設定された 2 つの 名前付きプロファイル を使用して実行します。異なる名前のプロファイル、またはデフォルトのプロファイルと名前付きのプロファイルを使用する場合、必要に応じてコマンドを変更します。
Amazon SNS トピックを作成する (アカウント A)
[Account A] (アカウント A) で、ソース Amazon SNS トピックを作成します。
aws sns create-topic --name sns-topic-for-lambda --profile accountA
トピックを作成したら、その Amazonリソースネーム (ARN) を記録します。これは、後ほどトピックをサブスクライブするための許可を Lambda 関数に追加するときに必要になります。
実行ロールを作成する (アカウント B)
[Account B] (アカウント B) で、AWS リソースにアクセスするための許可を関数に付与する実行ロールを作成します。
実行ロールを作成するには
-
IAM コンソールの [roles page (ロールページ)
] を開きます。 -
[ロールの作成] を選択します。
-
次のプロパティでロールを作成します。
-
信頼されたエンティティ - AWS Lambda
-
アクセス許可 – AWSLambdaBasicExecutionRole。
-
ロール名 –
lambda-sns-role
。
-
AWSLambdaBasicExecutionRole ポリシーには、ログを CloudWatch Logs に書き込むために関数が必要とするアクセス許可があります。
Lambda 関数を作成する (アカウント B)
[Account B] (アカウント B) で、Amazon SNS からのイベントを処理する関数を作成します。以下のコード例では、Amazon SNS イベント入力を受け取り、含まれるメッセージを処理します。例示のため、このコードでは受信イベントデータの一部を CloudWatch Logs に書き込みます。
他の言語によるサンプルコードについては、「」を参照してくださいサンプル関数コード
例 index.js
console.log('Loading function'); exports.handler = function(event, context, callback) { // console.log('Received event:', JSON.stringify(event, null, 4)); var message = event.Records[0].Sns.Message; console.log('Message received from SNS:', message); callback(null, "Success"); };
関数を作成するには
-
サンプルコードを
index.js
という名前のファイルにコピーします。 -
デプロイパッケージを作成します。
zip function.zip index.js
-
create-function
コマンドを使用して Lambda 関数を作成します。aws lambda create-function --function-name Function-With-SNS \ --zip-file fileb://function.zip --handler index.handler --runtime nodejs12.x \ --role
arn:aws:iam::
\ --timeout 60 --profile accountB<AccountB_ID>
:role/lambda-sns-role
関数を作成したら、その関数 ARN を記録します。これは、後ほど Amazon SNS が関数を呼び出せるようにする許可を追加するときに必要になります。
クロスアカウント許可をセットアップする (アカウント A と B)
[Account A] (アカウント A) で、トピックにサブスクライブする許可を [Account B] (アカウント B) に付与します。
aws sns add-permission --label lambda-access --aws-account-id
<AccountB_ID>
\ --topic-arn arn:aws:sns:us-east-2
:<AccountA_ID>
:sns-topic-for-lambda \ --action-name Subscribe ListSubscriptionsByTopic --profile accountA
[Account B] (アカウント B) で、Amazon SNS からの呼び出しを許可する Lambda 許可を追加します。
aws lambda add-permission --function-name Function-With-SNS \ --source-arn arn:aws:sns:
us-east-2
:<AccountA_ID>
:sns-topic-for-lambda \ --statement-id function-with-sns --action "lambda:InvokeFunction" \ --principal sns.amazonaws.com --profile accountB
次のような出力が表示されます。
{ "Statement": "{\"Condition\":{\"ArnLike\":{\"AWS:SourceArn\": \"arn:aws:sns:us-east-2:
<AccountA_ID>
:sns-topic-for-lambda\"}}, \"Action\":[\"lambda:InvokeFunction\"], \"Resource\":\"arn:aws:lambda:us-east-2:<AccountB_ID>
:function:Function-With-SNS\", \"Effect\":\"Allow\",\"Principal\":{\"Service\":\"sns.amazonaws.com\"}, \"Sid\":\"function-with-sns1\"}" }
ポリシーを追加するときは、--source-account
パラメータを使ってソースアカウントを Lambda ポリシーに追加しないようにします。ソースアカウントは Amazon SNS イベントソースとしてサポートされていないため、アクセスが拒否されます。
SNS トピックを持つアカウントがオプトインリージョンでホストされている場合、プリンシパルでリージョンを指定する必要があります。例えば、アジアパシフィック (香港) リージョンの SNS トピックを使用している場合、プリンシパルに 「sns.amazonaws.com
」 ではなく、「sns.ap-east-1.amazonaws.com
」 を指定する必要があります。
サブスクリプションを作成する (アカウント B)
[Account B] (アカウント B) で、Lambda 関数をトピックにサブスクライブします。[Account A] (アカウント A) の sns-topic-for-lambda
トピックにメッセージが送信されると、Amazon SNS が [Account B] (アカウント B) で Function-With-SNS
関数を呼び出します。
aws sns subscribe --protocol lambda \ --topic-arn arn:aws:sns:
us-east-2
:<AccountA_ID>
:sns-topic-for-lambda \ --notification-endpoint arn:aws:lambda:us-east-2
:<AccountB_ID>
:function:Function-With-SNS \ --profile accountB
次のような出力が表示されます。
{ "SubscriptionArn": "arn:aws:sns:us-east-2:
<AccountA_ID>
:sns-topic-for-lambda:5d906xxxx-7c8x-45dx-a9dx-0484e31c98xx" }
出力には、トピックのサブスクリプションの ARN が含まれています。
サブスクリプションをテストする (アカウント A)
[Account A] (アカウント A) で、サブスクリプションをテストします。テキストファイルに「Hello World
」と入力して、message.txt
として保存します。次に、以下のコマンドを実行します。
aws sns publish --message file://message.txt --subject Test \ --topic-arn arn:aws:sns:
us-east-2
:<AccountA_ID>
:sns-topic-for-lambda \ --profile accountA
これは、メッセージが Amazon SNS サービスによって承諾されたことを示す、一意の識別子を持つメッセージ ID を返します。次に、Amazon SNS は、これをトピックのサブスクライバー配信しようと試みます。また、message
パラメーターに直接 JSON 文字列を入力することもできますが、テキストファイルを使用するとメッセージに改行を使用できます。
Amazon SNS の詳細については、Amazon Simple Notification Service (Amazon SNS) とは何ですか? を参照してください。
リソースのクリーンアップ
このチュートリアル用に作成したリソースは、保持を希望しない場合、すぐに削除できます。使用しなくなった AWS リソースを削除することで、AWS アカウントに請求される料金が発生しないようにできます。
[Account A] (アカウント A) で、Amazon SNS トピックをクリーンアップします。
Amazon SNS トピックを作成するには
-
Amazon SNS コンソールで [Topics (トピック)] ページ
を開きます。 -
先ほど作成したトピックを選択します。
-
[Delete] (削除) をクリックします。
-
テキストボックスに「
delete me
」と入力します。 -
[Delete] (削除) をクリックします。
[Account B] (アカウント A) で、実行ロール、Lambda 関数、および Amazon SNS サブスクリプションをクリーンアップします。
実行ロールを削除するには
-
IAM コンソールの [Roles (ロール)] ページ
を開きます。 -
作成した実行ロールを選択します。
-
[ロールの削除] を選択します。
-
[はい、削除します] を選択します。
Lambda 関数を削除するには
-
Lambda コンソールの [Functions]
(関数) ページを開きます。 -
作成した関数を選択します。
-
[アクション] を選択してから、[削除] をクリックします。
-
[Delete] (削除) をクリックします。
Amazon SNS サブスクリプションを削除するには
-
Amazon SNS コンソールのSubscriptions page
] (サブスクリプションページ) をを開きます。 -
作成したサブスクリプションを選択します。
-
[Delete] (削除) を選択し、削除します。