Lambdaで異なるリージョンにSNS Publishする
LambdaではPython3.6を使用しています。
バージニア北部リージョンから、東京リージョンのSNSにPublishします。
バージニアのLambdaコードはこちら。
from __future__ import print_function
import boto3
import json
import os
def lambda_handler(event, context):
region = os.environ.get("REGION")
sns = boto3.client("sns", region_name=region)
print(region)
print(sns)
response = sns.publish(
TopicArn=os.environ.get("SNS_ARN"),
Subject="テスト",
Message="Lambdaで異なるリージョンにSNS Publishしてみた"
)
print(response)
return response
環境変数REGION
に送信先SNSのリージョンを、SNS_ARN
にSNSトピックARNを設定しています。
空のテストを作成し、テストを実行します。
数分後、以下のとおりメールの受信を確認できました。
リージョンを指定しない場合、An error occurred (InvalidParameter) when calling the Publish operation: Invalid parameter: TopicArn
とエラーになります。
なぜリージョンを指定する必要があるのか
リージョンを指定しない場合、boto3のデフォルトリージョンはLambdaのリージョンとなるからです。
これは、AWSがLambdaの環境変数でリージョンを定義しているからです。
Lambdaでos.environ
(環境変数)をprintで表示し、抜粋したものが以下のJSONです。
一番下にAWS_REGION
があり、バージニア北部リージョンが指定されています。
{
"PATH": "/var/lang/bin:/usr/local/bin:/usr/bin/:/bin:/opt/bin",
"LD_LIBRARY_PATH": "/var/lang/lib:/lib64:/usr/lib64:/var/runtime:/var/runtime/lib:/var/task:/var/task/lib:/opt/lib",
"LANG": "en_US.UTF-8",
"TZ": ":UTC",
"_HANDLER": "lambda_function.lambda_handler",
"LAMBDA_TASK_ROOT": "/var/task",
"LAMBDA_RUNTIME_DIR": "/var/runtime",
"AWS_REGION": "us-east-1",
}
クライアントのリージョンを指定していない場合、今回はデフォルトのクライアントのリージョンはバージニア北部リージョンになります。
そのため、TopicArn
で適切にリージョンを指定しても、クライアントのリージョンと異なるためエラーが出てしまいます。
boto3.client()
を実行する際にパラメーターとして資格情報(リージョン)を渡すことで、環境変数より優先されて使用されます(https://boto3.amazonaws.com/v1/documentation/api/latest/guide/credentials.html#guide-credentials)。