- LocalStack上で動くAmazon SNSのトピックに対して、AWS SAM CLIで動くLambdaからpublishを行う方法をメモする。
構成
LocalStack準備
-
docker-compose.yml
version: "3.8" networks: container-link: name: docker.internal services: localstack: container_name: "${LOCALSTACK_DOCKER_NAME-localstack_main}" image: localstack/localstack ports: - "127.0.0.1:53:53" # only required for Pro - "127.0.0.1:53:53/udp" # only required for Pro - "127.0.0.1:443:443" # only required for Pro - "127.0.0.1:4510-4530:4510-4530" # only required for Pro - "127.0.0.1:4566:4566" - "127.0.0.1:4571:4571" environment: - SERVICES=${SERVICES- } - DEBUG=${DEBUG- } - DATA_DIR=${DATA_DIR- } - LAMBDA_EXECUTOR=${LAMBDA_EXECUTOR- } - LOCALSTACK_API_KEY=${LOCALSTACK_API_KEY- } # only required for Pro - HOST_TMP_FOLDER=${TMPDIR:-/tmp/}localstack - DOCKER_HOST=unix:///var/run/docker.sock volumes: - "${TMPDIR:-/tmp}/localstack:/tmp/localstack" - "/var/run/docker.sock:/var/run/docker.sock" networks: - container-link
-
起動
docker-compose up
SNS準備
トピックの作成
aws sns create-topic --name test-topic --endpoint-url http://localhost:4566 --profile localstack
{
"TopicArn": "arn:aws:sns:ap-northeast-1:000000000000:test-topic"
}
トピックへのサブスクライブ
-
email
プロトコルとnotification-endpoint
の E メールアドレスを指定する。
aws sns subscribe --topic-arn arn:aws:sns:ap-northeast-1:000000000000:test-topic --protocol email --notification-endpoint test@example.com --endpoint-url http://localhost:4566 --profile localstack
{
"SubscriptionArn": "arn:aws:sns:ap-northeast-1:000000000000:test-topic:36e4e475-b360-4c7a-96f0-0690371e7566"
}
Lambda準備
-
ひな形作成
sam init
※ランタイムはPython3.8を選択。
-
template.yml
-
Hello World Exampleを利用する。
-
/topic/subscribe(サブスクライブ用)と/topic/publish(パブリッシュ用)を設定するように以下修正
Events: PublishTopic: Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api Properties: Path: /topic/publish Method: post
-
-
requrements.txt
requests boto3
※SNSアクセス用にboto3追加
-
Lambda処理(
app.py
)修正import json from boto3.session import Session # TopicARN TOPIC_ARN = u'arn:aws:sns:ap-northeast-1:000000000000:test-topic' # SNS 接続設定 session = Session( aws_access_key_id='dummy', aws_secret_access_key='dummy', region_name='ap-northeast-1' ) client = session.client( service_name='sns', endpoint_url='http://localstack:4566' ) def lambda_handler(event, context): # メッセージpublish request = { 'TopicArn': TOPIC_ARN, 'Message': json.loads(event["body"])["msg"], 'Subject': json.loads(event["body"])["subject"] } response = client.publish(**request) return { "statusCode": 200, "body": json.dumps({"MessageId":response["MessageId"]}), }
動作確認
-
ビルド
sam build
-
実行
sam local start-api --docker-network docker.internal
-
メッセージPublish
-
リクエスト
POST /topic/publish HTTP/1.1
-
Host: localhost:3000
Content-Type: application/json
Content-Length: 61
{
"msg":"test message",
"subject":"test subject"
}
```
-
レスポンス
{ "MessageId": "e08bba69-1ceb-4eef-9b88-19f74529bcbf"
}
```