AWS CloudFormationを利用して、サーバレス環境をコードで管理しようとしています。今回は、SQS (Simple Queue Service)を使って、メッセージがキューに送られた時に、そのメッセージを処理するLambdaが起動するようにCloudFormationで設定しようとした時にエラーが発生したため、その解決方法について紹介します。
エラーの内容
まず、エラーの内容については、WebコンソールからCloudFormationへアクセスし、対象となるエラーが発生したCloudFormationのスタックを確認します。次に、Evnetsのタブを開いて、タイプがAWS::Lambda::EventSourceMappingのリソースでエラーが生じていることを確認します。また、今回、解決したエラーは次の通りです。
ここで、エラーの内容がSQSのReceiveMessageを実行するための権限がないと書かれているので、その周辺にエラーの原因があるのだろうと思ったことが、ハマった原因となりました。
エラーの原因
明確にこれが原因ということはわかっていませんが、CloudFormation上での実行のタイミングがエラーの原因のようでした。今回、関係ありそうなタスクとしては、「SQSのキュー作成」、「Lambda用IAM作成」、「Lambda関数作成」、「SQSとLambdaの関連付け」の4つがあります。
まず、試したこととしては、1.「Lambda用IAM作成」、2.「SQSのキュー作成」、3.「Lambda関数作成」、4.「SQSとLambdaの関連付け」という順番でタスクを実行した場合、1と4の間に複数のdynamoDB作成など他のタスクを挟むと、問題なく実行することができました。しかし、これら4つのタスクに限定して実行すると、エラーが発生してしまうということがわかりました。
次に試したこととしては、順番の入れ替えです。1.「SQSのキュー作成」、2.「Lambda用IAM作成」、、3.「Lambda関数作成」、4.「SQSとLambdaの関連付け」という順番、1.「Lambda用IAM作成」、2.「Lambda関数作成」、3.「SQSのキュー作成」、4.「SQSとLambdaの関連付け」という順番でこれら4つのタスクのみ実行するスタックを試しましたが、どちらもエラーが発生してしまいます。また、前者の処理を1.「SQSのキュー作成」を別のスタックにして、スタックが終了するのを待った上で残りのタスクを実行する手順でもエラーが発生しました。
エラーが発生する場合と発生しない場合の違いを調べたところ、「Lambda用IAM作成」と「SQSとLambdaの関連付け」のタスク間に他のタスクが多くあるかが違いでした。
解決方法
今回、この問題を解決する方法として、「SQSとLambdaの関連付け」を別のスタックに分ける方法を選択しました。その結果、これまでに起こっていた問題は今の所は起こってません。