LoginSignup
3
0

ServerlessFrameworkでSQSをデプロイする2つの書き方

Posted at

ServerlessFrameworkでSQSをデプロイする2つの書き方

ServerlessFrameworkを使用してLambdaやその周辺サービスを管理・デプロイするケースはよくあると思います。
LambdaのトリガーとしてSQSを設定したときに2つの実装の仕方があったので備忘録を兼ねて書き留めていきます

2つの実装についてはこちらになります

  • serverless-lift プラグインを使用する
  • resources セクションを使用する

serverless-lift プラグインを使用する

こちらはServerlessのイベントとしてsqsを指定する箇所のドキュメントになります
このページの一番下でserverless-liftについて紹介してあります

このプラグインを追加するとconstructsセクションを記述できるようになり
functionsセクションと似たような書き方ができる他に

  • デッドレターキューの作成
  • 失敗した場合のリトライ回数は設定なしなら3回
  • リトライ超えた際のデッドレターキューの保存期間自動設定

などデフォルトでも本番に適した設定が自動的に適用されます :smile:

導入方法は簡単で

  1. プラグインのインストール
  2. プラグインとconstructsセクションをymlに記述

↓プラグインのインストール

$ serverless plugin install -n serverless-lift

↓プラグインとconstructsセクションをymlに記述

plugins:
    - serverless-lift
constructs:
    my-queue:
        type: queue
        worker:
            handler: handler.hello

functions配下にeventとしてsqsやsnsなどのサービスを指定する普段のserverlessとの書き方と違うところとして
constructs配下にqueueを作成してその配下にworkerとしてfunctionを指定する書き方になっています

resourcesセクションを使用する

ymlファイルの中にあるresourcesセクションを使用することでLambdaが使用する各種AWSリソースを作成できます

先程と違い
「デッドレターキューの自動作成」「リトライ最大実行回数」などについては自身で設定する必要があり
functionsとは少し書き方が異なってきます
実際に先程のserverless-liftで書いた内容をresourcesに書き直したymlはこちらです

serverless.yml
functions:
  hello:
    handler: handler.hello
    events:
      - sqs:
          arn:
            Fn::GetAtt:
              - MyQueue
              - Arn
resources:
  Resources:
    MyQueue:
      Type: AWS::SQS::Queue
      Properties:
        QueueName: my-queue

以前よりも書く量も増えたし、さっきになかった記述などがいくつか出てきましたね
「serverless-lift使ってやるほうでええんちゃう?」という意見もあると思います
resourcesセクションの良さとしては「CloudFormationのドキュメントに載っている内容が定義できる」ことや「Lambdaに関係のないリソースも記載できるところにあります」

まずCloudFormationのドキュメントに載っている内容が定義できるとはどういうことなのか

CloudFormationのドキュメントに載っている内容が定義できる

こちらがCloudFormationでSQSのQueueをyamlで定義する構文です

Type: AWS::SQS::Queue
Properties: 
  ContentBasedDeduplication: Boolean
  DeduplicationScope: String
  DelaySeconds: Integer
  FifoQueue: Boolean
  FifoThroughputLimit: String
  KmsDataKeyReusePeriodSeconds: Integer
  KmsMasterKeyId: String
  MaximumMessageSize: Integer
  MessageRetentionPeriod: Integer
  QueueName: String
  ReceiveMessageWaitTimeSeconds: Integer
  RedriveAllowPolicy: Json
  RedrivePolicy: Json
  SqsManagedSseEnabled: Boolean
  Tags: 
    - Tag
  VisibilityTimeout: Integer

このドキュメントさえ見れば自分の任意のオプションを有効にできます
例えばキューの名前を「anpan」、FIFOオプションを「有効化」にする場合は下記のようになります

serverless.yml
resources:
  Resources:
    MyQueue:
      Type: AWS::SQS::Queue
      Properties:
-        QueueName: my-queue
+        QueueName: anpan
+        FifoQueue: true

CloudFormationに記載がある定義がそのまま使えるということで
serverlessがv3からv4に上がったとき
serverless-liftがv4に未対応の場合で上げられないというリスクは取らなくて済むことや
一次ドキュメントがあるので信頼性が高いと思います

続いて「Lambdaに関係のないリソースも記載できる」という内容について説明します

Lambdaに関係のないリソースも記載できる

今回はSQS→Lambdaとしましたが、このSQSの前に別のリソースがあるときも簡単にかけるということです
↓のymlでは作成したSQSへイベントを渡すSNSを定義した例です

serverless.yml
resources:
  Resources:
    MyQueue:
      Type: AWS::SQS::Queue
      Properties:
        QueueName: my-queue
        DelaySeconds: 60
+   MyTopic:
+     Type: AWS::SNS::Topic
+     Properties:
+       TopicName: my-topic
+       Subscription:
+         - Endpoint:
+             Fn::GetAtt:
+               - MyQueue
+               - Arn
+           Protocol: sqs
functions:
  hello:
    handler: handler.hello
    architecture: arm64
    memorySize: 128
    timeout: 10
    events:
      - sqs:
          arn:
            Fn::GetAtt:
              - MyQueue
              - Arn

このようにLambdaと直接関わらないAWSのリソースもまとめて記載できます

上記のコードそのままだとSQSのアクセスポリシーがないため
SNS→SQSへ正しく送信されないのでご注意を

最後に

軽く使って見て「serverless-lift」と「resources」どちらにも良い点があるので脳死で「こっち使おうぜ」というのは無いように感じました。
ただ、自分がどんなケースでどちらを選ぶかだと

  • サクッと作るならserverless-lift
  • 長い付き合いになりそうならresources

といった感じで選ぶと思います。
また、resourcesとserverless-liftが片方だけしか使えないわけではなく、同時に使用はできますので
ユースケースに合わせて選択していくと良さそうですね

3
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
3
0