- LocalStack上で動くAWS SQSのキューに対してAWS SAM CLIで動くLambdaからメッセージ送受信を行う方法をメモする。
構成
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
SQS準備
キュー作成
aws sqs create-queue --queue-name test-queue --endpoint-url http://localhost:4566 --profile localstack
{
"QueueUrl": "http://localhost:4566/000000000000/test-queue"
}
キューの確認
aws sqs list-queues --endpoint-url http://localhost:4566 --profile localstack
{
"QueueUrls": [
"http://localhost:4566/000000000000/test-queue"
]
}
Lambda準備
Lambda
-
ひな形作成
sam init
※ランタイムはPython3.8を選択。
-
template.yml
-
Hello World Exampleを利用する。
-
POST(メッセージ送信)/GET(メッセージ受信)用に以下修正
Events: SendMessage: 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: /message Method: post ReceiveMessage: 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: /message Method: get
-
-
requrements.txt
requests boto3
※SQSアクセス用にboto3追加
-
Lambda処理(
app.py
)修正import json from boto3.session import Session from datetime import datetime # SQS 接続設定 session = Session( aws_access_key_id='dummy', aws_secret_access_key='dummy', region_name='ap-northeast-1' ) client = session.client( service_name='sqs', endpoint_url='http://localstack:4566' ) def lambda_handler(event, context): # キューURL queue_url="http://localstack:4566/000000000000/test-queue" if event["httpMethod"] == "POST": # メッセージ送信 response = client.send_message(QueueUrl=queue_url, MessageBody=json.dumps(event["body"])) res = {"MD5OfMessageBody":response["MD5OfMessageBody"],"MessageId":response["MessageId"]} return { "statusCode": 200, "body": json.dumps(res), } if event["httpMethod"] == "GET": # メッセージ受信 response = client.receive_message(QueueUrl=queue_url, MaxNumberOfMessages=1, VisibilityTimeout=60) # メッセージ削除 for message in response["Messages"]: client.delete_message(QueueUrl=queue_url, ReceiptHandle=message["ReceiptHandle"]) return { "statusCode": 200, "body": json.dumps(response["Messages"][0]), }
動作確認
-
ビルド
sam build
-
実行
sam local start-api --docker-network docker.internal
-
メッセージ送信
-
リクエスト
POST /message HTTP/1.1 Host: localhost:3000 Content-Type: application/json Content-Length: 34 { "message":"test message1" }
-
レスポンス
{ "MD5OfMessageBody": "65b7b348e7f42918ad0d487de1a20c47", "MessageId": "2cafdcd9-2620-14b4-645a-da15dbddf8b5" }
-
-
メッセージ受信
-
リクエスト
GET /message HTTP/1.1 Host: localhost:3000 Content-Type: application/json
-
レスポンス
{ "MessageId": "2cafdcd9-2620-14b4-645a-da15dbddf8b5", "ReceiptHandle": "imvqeantfgqrgtkzhwowwzywsxmtdrakkhjdqkwyybxlevsltiefnfjrmoksniovizimonlkixhdixufzqlmejbmtwcxvwuaintwwojbompbfqjhsmokjtojxdlnxquvqslbrevmrinvzxeymkrcpstcmzrtfzhlclwpmkcuokfqjdahkiqhlxcli", "MD5OfBody": "65b7b348e7f42918ad0d487de1a20c47", "Body": "\"{\\n \\\"message\\\":\\\"test message1\\\"\\n}\"" }
-