Lambda を aws lambda invoke
コマンドで直接テストしようとした際に、「Invalid base64」 や 「Could not parse payload into json」 といったエラーにハマりました。
やりたかったこと
センサーデータを API Gateway 経由で受け取る Lambda を想定。
CLI からLambdaの単体テストしてみる。→「Invalid base64」エラー
{
"body": "{\"sensor_id\": \"car-001\", \"timestamp\": \"2025-03-23T12:34:56Z\", \"temperature\": 24.5, \"speed\": 50.0}"
}
Code language: JSON / JSON with Comments (json)
しかしこの JSON ペイロードで Lambda を呼び出すと、さまざまなエラーが発生。。
最初のエラー:UTF-8のエンコーディングエラー
Could not parse request body into json: Invalid UTF-8 start byte 0x87
ファイルが Shift_JISやASCII で保存されているのが原因の様子。
UTF-8 に変換(macOS)
iconv -f US-ASCII -t UTF-8 test-payload.json > test-payload-utf8.json
Code language: CSS (css)
次のエラー:「Invalid base64」
Invalid base64: "{"body":"{...}"}"
Code language: JavaScript (javascript)
このエラーは、--cli-binary-format
オプションを付けていないことで、CLIがJSONをBase64として解釈しようとしたことが原因でした。
解決手順まとめ
- JSONを1行で整形
- –cli-binary-format オプションを追加
この実行で無事、以下のような成功レスポンスが返ってくる
akira_mba@amba cfn-demo-api_lambda_waf % aws lambda invoke \
--function-name ApiWafDemoFunction \
--payload '{"body":"{\"sensor_id\": \"car-001\", \"timestamp\": \"2025-03-23T12:34:56Z\", \"temperature\": 24.5, \"speed\": 50.0}"}' \
--cli-binary-format raw-in-base64-out \
output.json
{
"StatusCode": 200,
"ExecutedVersion": "$LATEST"
}
akira_mba@amba cfn-demo-api_lambda_waf %
メモ
・API Gatewayからデータを送る場合は、文字列で送られる
(サンプル)
"body": "{\"sensor_id\": \"car-001\", \"temperature\": 24.5, \"speed\": 50.0}"
→文字列としてエスケープされたJSON(JSON構造ではない)
・今回、API Gatewayからデータを受け取る想定でLambda関数を作成した
(文字列で受け取ることを想定)
・Lambda関数ではデータの処理はPythonで処理できるdict型(JSONと構造が同じ形式)にする必要がある
そのため、以下で定義した
### ingest_vehicle_sensor.py ###
def lambda_handler(event, context):
body = event.get("body")
payload = json.loads(body) # JSON文字列 → dict : "文字列(文字列としてエスケープされたJSON)"をPythonの辞書にする
...
######################
・なので、aws lambda invoke コマンドでテストする時は、JSON形式で渡さずに、文字列型で渡す必要がある。
Code language: PHP (php)
CloudWatch Logsでの確認
aws logs get-log-events
コマンドで Lambda のログを取得し、正しくセンサーデータが記録されていることを確認
akira_mba@amba cfn-demo-api_lambda_waf % aws logs get-log-events \
--log-group-name /aws/lambda/ApiWafDemoFunction \
--log-stream-name '2025/03/29/[$LATEST]c5718097ca18438cb6429a8e4798b829'
<省略>
"events": [
{
"timestamp": 1743252382479,
"message": "INIT_START Runtime Version: python:3.9.v82\tRuntime Version ARN: arn:aws:lambda:ap-northeast-1::runtime:d6dc717114b06da7d4b5a2df328222709ec4fad2853004fac301b8b63a65c084\n",
"ingestionTime": 1743252387405
},
{
"timestamp": 1743252382559,
"message": "START RequestId: 4af0cf07-a5a1-4b81-af20-6f6c697058ef Version: $LATEST\n",
"ingestionTime": 1743252387405
},
{
"timestamp": 1743252382560,
"message": "[INFO]\t2025-03-29T12:46:22.559Z\t4af0cf07-a5a1-4b81-af20-6f6c697058ef\tReceived sensor data: {\"sensor_id\": \"car-001\", \"timestamp\": \"2025-03-23T12:34:56Z\", \"temperature\": 24.5, \"speed\": 50.0, \"source_ip\": \"N/A\"}\n",
"ingestionTime": 1743252387405
},
{
"timestamp": 1743252382574,
"message": "END RequestId: 4af0cf07-a5a1-4b81-af20-6f6c697058ef\n",
"ingestionTime": 1743252387405
},
<省略>
これで Lambda 関数が想定通りに動作していることが確認できました。
補足:
ログストリーム名の $LATEST
や [
]
の特殊文字含んでいる
Bash、Zshではダブルクォート「”」で囲むと$
が環境変数で展開される
シングルクォート「’」で囲むと完全な文字列で扱われる
akira_mba@amba cfn-demo-api_lambda_waf % aws logs get-log-events \
--log-group-name /aws/lambda/ApiWafDemoFunction \
--log-stream-name "2025/03/29/[$LATEST]c5718097ca18438cb6429a8e4798b829"
An error occurred (ResourceNotFoundException) when calling the GetLogEvents operation: The specified log stream does not exist.
akira_mba@amba cfn-demo-api_lambda_waf %
まとめ
問題 | 対策 |
---|---|
文字コードエラー | UTF-8に変換する |
JSON構文エラー | 1行のJSON形式で保存 |
Invalid base64 | --cli-binary-format raw-in-base64-out を明示 |