初心者向け『チュートリアル: Amazon Simple Queue Service で AWS Lambda を使用する』をやってみた

2019.07.25

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

概要

大阪オフィスのちゃだいんです。

手を動かして学ぶために、公式ドキュメントのチュートリアルをやってみました。

今回は、初Lambda。内容は以下のものです。

チュートリアル: Amazon Simple Queue Service で AWS Lambda を使用する

このチュートリアルでは、Amazon SQS キューからのメッセージを処理する Lambda 関数を作成します。

前提条件

AWS CLIが使用できる環境で行ってます。

早速やってみた

1.実行ロールを作成する

  • lambda関数にAWSリソースに対して実行権限を付与するIAMロールを作成します。

  • マネジメントコンソールを開き、IAMの画面へ移動します。

  • Roleページにて、ロールの作成を選択します。

  • Lambdaの中からAWSLambdaSQSQueueExecutionRole.を選び、以下のように作成しました。

2.関数を作成する

早速メインとなるLambda関数を作成します。

以下のコード例では、Amazon SQS イベント入力を受け取り、含まれるメッセージを処理します。このコードでは説明のために、受信イベントデータの一部が CloudWatch Logs に書き込まれます。

  • チュートリアルには複数のサンプルコードがありますが、私はPythonを選びました。

  • 実際のサンプルコードは以下の通りです。

from __future__ import print_function

def lambda_handler(event, context):
    for record in event['Records']:
       print ("test")
       payload=record["body"]
       print(str(payload))
  • このコードをコピーしてProcessSQSRecords.pyという名前でファイルを作成します。

  • この関数コードを圧縮してデプロイパッケージ(zipファイル)を作成します。

$ zip ProcessSQSRecords.zip ProcessSQSRecords.py
  • ちなみに今回はシンプルに関数コードのみですが、コードによってはAWS SDK以外のライブラリをインストールしてデプロイパッケージに入れ込む必要があります。

  • AWS CLIのaws lambda create-functionコマンドでこのデプロイパッケージで関数を作成します。

$ aws lambda create-function --function-name ProcessSQSRecord \
 --zip-file fileb://ProcessSQSRecords.zip --handler ProcessSQSRecords.lambda_handler --runtime python3.7 \
 --role arn:aws:iam::1234567890:role/lambda-sqs-role  --region ap-northeast-1
  • 実行結果ではいけてるみたいです。(ほっとする)
{
    "TracingConfig": {
        "Mode": "PassThrough"
    },
    "CodeSha256": "4gw9wNEG2AV3qM3FAoIUYkwgiesvCXnkMoDopbfq68g=",
    "FunctionName": "ProcessSQSRecord",
    "CodeSize": 322,
    "RevisionId": "0b547a88-65b7-435d-84b0-32995e2d1ae6",
    "MemorySize": 128,
    "FunctionArn": "arn:aws:lambda:ap-northeast-1:1234567890:function:ProcessSQSRecord",
    "Version": "$LATEST",
    "Role": "arn:aws:iam::1234567890:role/lambda-sqs-role",
    "Timeout": 3,
    "LastModified": "2019-07-23T09:07:59.852+0000",
    "Handler": "ProcessSQSRecords.lambda_handler",
    "Runtime": "python3.7",
    "Description": ""
}
  • Lambdaコンソールを開くと、関数のページにちゃんとできていました。

  • 関数の画面を開くとこんな感じ。

3.関数をテストする

invoke AWS Lambda CLI コマンドおよびサンプルの Amazon Simple Queue Service イベントを使用して、手動で Lambda 関数を呼び出します。

  • 以下の JSON をファイルにコピーし、input.txt という名前で保存します。
{
    "Records": [
        {
            "messageId": "059f36b4-87a3-44ab-83d2-661975830a7d",
            "receiptHandle": "AQEBwJnKyrHigUMZj6rYigCgxlaS3SLy0a...",
            "body": "test",
            "attributes": {
                "ApproximateReceiveCount": "1",
                "SentTimestamp": "1545082649183",
                "SenderId": "AIDAIENQZJOLO23YVJ4VO",
                "ApproximateFirstReceiveTimestamp": "1545082649185"
            },
            "messageAttributes": {},
            "md5OfBody": "098f6bcd4621d373cade4e832627b4f6",
            "eventSource": "aws:sqs",
            "eventSourceARN": "arn:aws:sqs:us-east-2:123456789012:my-queue",
            "awsRegion": "us-east-2"
        }
    ]
}
  • invokeコマンドでテストを実行します。
aws lambda invoke --invocation-type RequestResponse --function-name ProcessSQSRecord \
--payload file://input.txt outputfile.txt --region ap-northeast-1
  • すると以下の通り実行結果が返ってきました。(いけたっぽい)
{
    "ExecutedVersion": "$LATEST",
    "StatusCode": 200
}
  • テストにて出力されたoutputfile.txtの中身はこんなnullでした。(正しくなさそう...)

めげずに次に進みます。  

4.SQSキューを作成する

Lambda 関数がイベントソースとして使用できる Amazon SQS キューを作成します。

  • 以下のようにAmazon SQS コンソールで新しいキューの作成を行います。

  • なんの変哲もないキューができました。

  • 試しに今の状態でキューにメッセージを送信してみたところ、メッセージはずっと処理されないままでした。(当たり前)

5.イベントソースの設定

指定された Amazon SQS キューと Lambda 関数間でマッピングを作成するには、次の AWS CLI create-event-source-mapping コマンドを実行します。

  • というわけで以下のコマンドを実行します。
$ aws lambda create-event-source-mapping --function-name ProcessSQSRecord  --batch-size 10 \
--event-source arn:aws:sqs:ap-northeast-1:1234567890:lambdatest --region ap-northeast-1
  • 実行結果は以下の通りです。
{
    "UUID": "81229997-1471-4abc-bc0e-73dc7d1f3f33",
    "StateTransitionReason": "USER_INITIATED",
    "LastModified": 1563881610.903,
    "BatchSize": 10,
    "State": "Creating",
    "FunctionArn": "arn:aws:lambda:ap-northeast-1:1234567890:function:ProcessSQSRecord",
    "EventSourceArn": "arn:aws:sqs:ap-northeast-1:1234567890:lambdatest"
}
  • Lambdaコンソールで関数ページを見ると、イベントソースにSQSが追加されました。これで準備完了。

6.セットアップをテストする

これで、次のようにセットアップをテストできます。
1. Amazon SQS コンソールでキューにメッセージを送信します。Amazon SQS はこれらのアクションのレコードをキューに書き込みます。
2. AWS Lambda は、キューをポーリングし、キューの更新を検出すると、キューで見つかったイベントデータを渡して Lambda 関数を呼び出します。
3. 関数が実行され、Amazon CloudWatch でログが作成されます。Amazon CloudWatch コンソールで報告されたログを確認できます。

  • まず、SQSコンソールから対象のキューでメッセージを送信しました。  

  • 先ほどのようにメッセージは「利用可能なメッセージ」に残ることなく、即処理されました。

  • CloudWatchには対象のlambda関数のログが収集されています。

  • ログの中身を見ると、以下の通りメッセージが処理され、ログに記録されていました。(よかったよかった)

つまずいたところ

ハンドラーの名称ミス

最初は、なんとなくProcessSQSRecords.pyに合わせてコマンドでlambda関数を作成する際に、ProcessSQSRecords.handlerと指定しました。テストを実行すると実行結果に"FunctionError": "Unhandled",と表示されており、うまくいきません。

調べてみると、関数コードで指定しているハンドラーと噛み合わなかったようなので、ProcessSQSRecords.lambda_handlerに変更したら、うまくいきました。

感想

初Lambdaだったので上記に書き切れてない部分で色々つまずきましたが、なんとか一通りやり抜くと、ほんのすこーしわかった気になりますね。ほんのすこーし。

誰かのお役に立てば幸いです。それではまた、大阪オフィスのちゃだいんでした。