LoginSignup
0
0

More than 1 year has passed since last update.

Lambda(SAM)からAmazon SNSトピックへpublishを行う方法メモ

Posted at
  • LocalStack上で動くAmazon SNSのトピックに対して、AWS SAM CLIで動くLambdaからpublishを行う方法をメモする。

構成

sam-sns.png

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"
    }
    

参考情報

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0