ServerlessFrameworkでSQSをデプロイする2つの書き方
ServerlessFrameworkを使用してLambdaやその周辺サービスを管理・デプロイするケースはよくあると思います。
LambdaのトリガーとしてSQSを設定したときに2つの実装の仕方があったので備忘録を兼ねて書き留めていきます
2つの実装についてはこちらになります
- serverless-lift プラグインを使用する
- resources セクションを使用する
serverless-lift プラグインを使用する
こちらはServerlessのイベントとしてsqsを指定する箇所のドキュメントになります
このページの一番下でserverless-lift
について紹介してあります
このプラグインを追加するとconstructs
セクションを記述できるようになり
functionsセクションと似たような書き方ができる他に
- デッドレターキューの作成
- 失敗した場合のリトライ回数は設定なしなら3回
- リトライ超えた際のデッドレターキューの保存期間自動設定
などデフォルトでも本番に適した設定が自動的に適用されます
導入方法は簡単で
- プラグインのインストール
- プラグインと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はこちらです
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オプションを「有効化」にする場合は下記のようになります
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を定義した例です
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が片方だけしか使えないわけではなく、同時に使用はできますので
ユースケースに合わせて選択していくと良さそうですね