チュートリアル: Amazon Simple Notification Service での AWS Lambda の使用
このチュートリアルでは、Lambda 関数を 1 つの AWS アカウント で使用して、別の AWS アカウント で Amazon Simple Notification Service (Amazon SNS) トピックをサブスクライブします。Amazon SNS トピックにメッセージを発行すると、Lambda 関数がメッセージの内容を読み取り、Amazon CloudWatch Logs に出力します。このチュートリアルを完了するには、AWS Command Line Interface (AWS CLI) を使用します。
このチュートリアルを完了するには、次のステップを実行します。
-
アカウント A で、Amazon SNS トピックを作成します。
-
アカウント B で、トピックからメッセージを読み取る Lambda 関数を作成します。
-
アカウント B で、トピックへのサブスクリプションを作成します。
-
アカウント A の Amazon SNS トピックにメッセージを発行し、[アカウント B] の Lambda 関数がメッセージを CloudWatch Logs に出力することを確認します。
これらのステップを完了することで、Lambda 関数を呼び出すように Amazon SNS トピックを設定する方法を学べます。また、別の AWS アカウント のリソースに Lambda を呼び出す許可を与える AWS Identity and Access Management (IAM) ポリシーを作成する方法も学習します。
このチュートリアルでは、2 つの別々の AWS アカウント を使用します。この AWS CLI コマンドは、それぞれが別の AWS アカウント で使用されるように設定された 2 つの名前付きプロファイル accountA
および accountB
を使用して実行します。異なるプロファイルを使用するように AWS CLI を設定する方法については、バージョン 2 の AWS Command Line Interface ユーザーガイドの「設定と認証情報ファイルの設定」を参照してください。両方のプロファイルに同じデフォルトの AWS リージョン を設定してください。
2 つの AWS アカウント に対して作成した AWS CLI プロファイルが異なる名前を使用している場合、またはデフォルトのプロファイルと 1 つの名前付きプロファイルを使用している場合は、必要に応じて次の手順の AWS CLI コマンドを変更します。
前提条件
AWS アカウント がない場合は、以下のステップを実行して作成します。
AWS アカウントにサインアップするには
オンラインの手順に従います。
サインアップ手順の一環として、通話呼び出しを受け取り、電話キーパッドで検証コードを入力するように求められます。
AWS アカウント にサインアップすると、AWS アカウントのルートユーザー が作成されます。ルートユーザーには、アカウントのすべてのAWS のサービスとリソースへのアクセス権があります。セキュリティのベストプラクティスとして、ユーザーに管理アクセスを割り当て、ルートユーザーのみを使用してルートユーザーアクセスが必要なタスクを実行してください。
サインアップ処理が完了すると、AWS からユーザーに確認メールが送信されます。https://aws.amazon.com/
AWS アカウント にサインアップしたら、AWS アカウントのルートユーザー をセキュリティで保護し、AWS IAM Identity Center を有効にして、管理ユーザーを作成します。これにより、日常的なタスクにルートユーザーを使用しないようにします。
AWS アカウントのルートユーザーをセキュリティで保護する
-
ルートユーザー] を選択し、AWS アカウント のメールアドレスを入力して、アカウント所有者として AWS Management Console
にサインインします。次のページでパスワードを入力します。 ルートユーザーを使用してサインインする方法については、AWS サインイン ユーザーガイドのルートユーザーとしてサインインするを参照してください。
-
ルートユーザーの多要素認証 (MFA) を有効にします。
手順については、IAM ユーザーガイドのAWS アカウント のルートユーザーの仮想 MFA デバイスを有効にする (コンソール)を参照してください。
管理アクセスを持つユーザーを作成する
-
IAM アイデンティティセンターを有効にします。
手順については、「AWS IAM Identity Center ユーザーガイド」の「AWS IAM Identity Center の有効化」を参照してください。
-
IAM アイデンティティセンターで、ユーザーに管理アクセスを付与します。
IAM アイデンティティセンターディレクトリ をアイデンティティソースとして使用するチュートリアルについては、「AWS IAM Identity Center ユーザーガイド」の「デフォルト IAM アイデンティティセンターディレクトリを使用したユーザーアクセスの設定」を参照してください。
管理アクセス権を持つユーザーとしてサインインする
-
IAM アイデンティティセンターのユーザーとしてサインインするには、IAM アイデンティティセンターのユーザーの作成時に E メールアドレスに送信されたサインイン URL を使用します。
IAM Identity Center ユーザーを使用してサインインする方法については、AWS サインイン ユーザーガイドのAWS アクセスポータルにサインインするを参照してください。
AWS Command Line Interface をまだインストールしていない場合は、「最新バージョンの AWS CLI のインストールまたは更新」にある手順に従ってインストールしてください。
このチュートリアルでは、コマンドを実行するためのコマンドラインターミナルまたはシェルが必要です。Linux および macOS では、任意のシェルとパッケージマネージャーを使用してください。
注記
Windows では、Lambda でよく使用される一部の Bash CLI コマンド (zip
など) が、オペレーティングシステムの組み込みターミナルでサポートされていません。Ubuntu および Bash の Windows 統合バージョンを取得するには、Windows Subsystem for Linux をインストール
Amazon SNS トピックを作成する (アカウント A)
トピックを作成するには
-
アカウント A で、次の AWS CLI コマンドを使用して Amazon SNS 標準トピックを作成します。
aws sns create-topic --name sns-topic-for-lambda --profile accountA
次のような出力が表示されます。
{ "TopicArn": "arn:aws:sns:us-west-2:123456789012:sns-topic-for-lambda" }
トピックの Amazon リソースネーム (ARN) をメモしておきます。これは、このチュートリアルで後ほどトピックをサブスクライブするための許可を Lambda 関数に追加するときに必要になります。
関数実行ロールを作成する (アカウント B)
実行ロールとは、AWS サービスとリソースにアクセスする許可を Lambda 関数に付与する IAM ロールです。アカウント B で関数を作成する前に、CloudWatch Logs にログを書き込むための基本的なアクセス許可を関数に与えるロールを作成します。Amazon SNS トピックから読み取るアクセス許可は、後のステップで追加します。
実行ロールを作成するには
-
アカウント B で、IAM コンソールのロールのページ
を開きます。 -
[ロールの作成] を選択します。
-
[信頼できるエンティティタイプ] で、[AWS サービス] を選択します。
-
[ユースケース] で、[Lambda] を選択します。
-
[Next] を選択します。
-
次の手順を実行して、基本的なアクセス許可ポリシーをロールに追加します。
-
[許可ポリシー] 検索ボックスに
AWSLambdaBasicExecutionRole
と入力します。 -
[Next] を選択します。
-
-
次の手順を実行して、ロールの作成を完了します。
-
[ロールの詳細] にある [ロール名] には
lambda-sns-role
を入力します。 -
[ロールの作成] を選択します。
-
Lambda 関数を作成する (アカウント B)
Amazon SNS メッセージを処理する Lambda 関数を作成します。この関数コードは、各レコードのメッセージコンテンツを Amazon CloudWatch Logs に記録します。
このチュートリアルでは Node.js 18.x ランタイムを使用しますが、他のランタイム言語のサンプルコードも提供しています。次のボックスでタブを選択すると、関心のあるランタイムのコードが表示されます。このステップで使用する JavaScript コードは、[JavaScript] タブに表示されている最初のサンプルにあります。
関数を作成するには
-
プロジェクト用のディレクトリを作成し、そのディレクトリに切り替えます。
mkdir sns-tutorial cd sns-tutorial
-
サンプル JavaScript コードを
index.js
という名前の新しいファイルにコピーします。 -
以下の
zip
コマンドを使用して、デプロイパッケージを作成します。zip function.zip index.js
-
次の AWS CLI コマンドを実行して、アカウント B に Lambda 関数を作成します。
aws lambda create-function --function-name Function-With-SNS \ --zip-file fileb://function.zip --handler index.handler --runtime nodejs18.x \ --role arn:aws:iam::
<AccountB_ID>
:role/lambda-sns-role \ --timeout 60 --profile accountB次のような出力が表示されます。
{ "FunctionName": "Function-With-SNS", "FunctionArn": "arn:aws:lambda:us-west-2:123456789012:function:Function-With-SNS", "Runtime": "nodejs18.x", "Role": "arn:aws:iam::123456789012:role/lambda_basic_role", "Handler": "index.handler", ... "RuntimeVersionConfig": { "RuntimeVersionArn": "arn:aws:lambda:us-west-2::runtime:7d5f06b69c951da8a48b926ce280a9daf2e8bb1a74fc4a2672580c787d608206" } }
-
関数の Amazon リソースネーム (ARN) を記録します。これは、このチュートリアルで後ほど Amazon SNS が関数を呼び出せるようにする許可を追加するときに必要になります。
関数にアクセス許可を追加する (アカウント B)
Amazon SNS が関数を呼び出すには、リソースベースのポリシーのステートメントでその関数にアクセス許可を付与する必要があります。AWS CLI add-permission
コマンドを使用してこのステートメントを追加します。
Amazon SNS アクセス許可を付与して関数を呼び出すには
-
アカウント B で、前に記録した Amazon SNS トピックの ARN を使用して次の AWS CLI コマンドを実行します。
aws lambda add-permission --function-name Function-With-SNS \ --source-arn arn:aws:sns:
us-east-1:<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-1:<AccountA_ID>:sns-topic-for-lambda\"}}, \"Action\":[\"lambda:InvokeFunction\"], \"Resource\":\"arn:aws:lambda:us-east-1:<AccountB_ID>:function:Function-With-SNS\", \"Effect\":\"Allow\",\"Principal\":{\"Service\":\"sns.amazonaws.com\"}, \"Sid\":\"function-with-sns\"}" }
注記
Amazon SNS トピックを持つアカウントがオプトイン AWS リージョン でホストされている場合、プリンシパルでリージョンを指定する必要があります。例えば、アジアパシフィック (香港) リージョンの Amazon SNS トピックを使用している場合、プリンシパルに「sns.amazonaws.com
」ではなく「sns.ap-east-1.amazonaws.com
」を指定する必要があります。
Amazon SNS サブスクリプションのクロスアカウントのアクセス許可を付与する (アカウント A)
アカウント B の Lambda 関数が アカウント A で作成した Amazon SNS トピックをサブスクライブするには、アカウント B にトピックをサブスクライブするアクセス許可を付与する必要があります。AWS CLI add-permission
コマンドを使用してこのアクセス許可を付与します。
トピックをサブスクライブする許可をアカウント B に付与するには
-
アカウント A で、次の AWS CLI コマンドを実行します。以前に記録した Amazon SNS トピックの ARN を使用します。
aws sns add-permission --label lambda-access --aws-account-id
<AccountB_ID>
\ --topic-arn arn:aws:sns:us-east-1:<AccountA_ID>
:sns-topic-for-lambda \ --action-name Subscribe ListSubscriptionsByTopic --profile accountA
サブスクリプションを作成する (アカウント B)
アカウント B で、Lambda 関数によってチュートリアルの最初にアカウント A で作成した Amazon SNS トピックをサブスクライブします。メッセージがこのトピック (sns-topic-for-lambda
) に送信されると、Amazon SNS はアカウント B の Lambda 関数 Function-With-SNS
を呼び出します。
サブスクリプションを作成するには
-
アカウント B で、次の AWS CLI コマンドを実行します。トピックを作成したデフォルトのリージョンと、トピックおよび Lambda 関数の ARN を使用します。
aws sns subscribe --protocol lambda \ --region
us-east-1
\ --topic-arn arn:aws:sns:us-east-1:<AccountA_ID>
:sns-topic-for-lambda \ --notification-endpoint arn:aws:lambda:us-east-1:<AccountB_ID>
:function:Function-With-SNS \ --profile accountB次のような出力が表示されます。
{ "SubscriptionArn": "arn:aws:sns:us-east-1:<AccountA_ID>:sns-topic-for-lambda:5d906xxxx-7c8x-45dx-a9dx-0484e31c98xx" }
メッセージをトピックに発行する (アカウント A とアカウント B)
アカウント B の Lambda 関数が アカウント A の Amazon SNS トピックにサブスクライブされたので、トピックにメッセージを発行してセットアップをテストします。Amazon SNS が Lambda 関数を呼び出したことを確認するには、CloudWatch Logs を使用して関数の出力を表示します。
トピックにメッセージを発行して関数の出力を表示するには
-
テキストファイルに「
Hello World
」と入力して、message.txt
として保存します。 -
テキスト ファイルを保存したのと同じディレクトリから、アカウント A で次の AWS CLI コマンドを実行します。自分のトピックの ARN を使用します。
aws sns publish --message file://message.txt --subject Test \ --topic-arn arn:aws:sns:
us-east-1:<AccountA_ID>
:sns-topic-for-lambda \ --profile accountAこれにより、メッセージが Amazon SNS によって承諾されたことを示す、一意の識別子を持つメッセージ ID が返されます。次に、Amazon SNS は、メッセージをトピックのサブスクライバーに配信しようと試みます。Amazon SNS が Lambda 関数を呼び出したことを確認するには、CloudWatch Logs を使用して次の手順で関数の出力を確認します。
-
アカウント B で、Amazon CloudWatch コンソールの [ロググループ]
ページを開きます。 -
関数のロググループの名前を選択します (
/aws/lambda/Function-With-SNS
) 。 -
最新のログストリームを選択します。
-
関数が正しく呼び出されていれば、トピックに発行したメッセージの内容を示す次のような出力が表示されます。
2023-07-31T21:42:51.250Z c1cba6b8-ade9-4380-aa32-d1a225da0e48 INFO Processed message Hello World 2023-07-31T21:42:51.250Z c1cba6b8-ade9-4380-aa32-d1a225da0e48 INFO done
リソースのクリーンアップ
このチュートリアル用に作成したリソースは、保持しない場合は削除できます。使用しなくなった AWS リソースを削除することで、AWS アカウント アカウントに請求される料金の発生を防ぎます。
[Account A] (アカウント A) で、Amazon SNS トピックをクリーンアップします。
Amazon SNS トピックを作成するには
-
Amazon SNS コンソールで [Topics (トピック)] ページ
を開きます。 -
先ほど作成したトピックを選択します。
-
[削除] を選択します。
-
テキスト入力フィールドに
delete me
を入力します。 -
[削除] を選択します。
[Account B] (アカウント A) で、実行ロール、Lambda 関数、および Amazon SNS サブスクリプションをクリーンアップします。
実行ロールを削除する
-
IAM コンソールのロールページ
を開きます。 -
作成した実行ロールを選択します。
-
[削除] を選択します。
-
テキスト入力フィールドにロールの名前を入力し、[削除] を選択します。
Lambda 関数を削除するには
-
Lambda コンソールの関数
ページを開きます。 -
作成した関数を選択します。
-
[アクション] で、[削除] を選択します。
-
テキスト入力フィールドに
delete
と入力し、[Delete] (削除) を選択します。
Amazon SNS サブスクリプションを削除するには
-
Amazon SNS コンソールのSubscriptions page
] (サブスクリプションページ) をを開きます。 -
作成したサブスクリプションを選択します。
-
[Delete] (削除) を選択し、削除します。