背景
Lambda + API Gateway + DynamoDBのメモアプリAPIをAWS SAMで構築する中で、Windows環境特有の2つのハマりどころに遭遇しました。Macの記事をそのまま試すと再現しないため、Windows環境の実体験として残します。
1. requirements.txtへの日本語コメントでビルドが落ちる
Build Failed
Error: PythonPipBuilder:ResolveDependencies - 'cp932' codec can't decode byte 0x84 in position 43: illegal multibyte sequence
原因: Windows版のSAM CLI(PythonPipBuilder)はrequirements.txtをcp932(Shift-JIS)として読み込もうとします。ファイル自体はUTF-8で保存していても、日本語コメントが含まれているとデコードに失敗します。
# NG(日本語コメント)
# boto3はLambdaランタイムに含まれるため記載不要
# OK(英語コメント)
# boto3 is included in the Lambda runtime, no need to list it here.
対処: requirements.txtのコメントは必ず英語で書きます。template.yamlのコメントはSAMがpipに直接渡さないため、日本語のままで問題ありません。同じYAMLファイル内でもファイルの用途によって扱いが変わる点に注意が必要です。
2. CMDでPUT/DELETEを叩くと400 Bad Requestになる
set MEMO_ID=6150433b-4834-4cfe-81f5-266d3dad9e57
curl -s -X PUT "%API_URL%/memos/%MEMO_ID%" -H "Content-Type: application/json" -d "{...}"
新しいターミナルでこれを実行すると:
400 ERROR - Bad request (Generated by cloudfront)
原因: CMDのsetで定義した変数は、そのターミナルセッションを閉じると消えます。別のターミナルで%MEMO_ID%を使うと変数が未展開のまま文字列としてURLに含まれ、CloudFrontが%をパーセントエンコーディングの開始文字として解釈して不正なURLと判定します。
対処: 同一セッション内で完結させるか、確実な方法としてUUIDを直接URLに貼り付けます。
3. DynamoDBCrudPolicyが自動付与する権限
Policies:
- DynamoDBCrudPolicy:
TableName: !Ref MemosTable
この2行が付与する実際の権限は以下の6アクションです。
dynamodb:GetItem, dynamodb:PutItem, dynamodb:UpdateItem,
dynamodb:DeleteItem, dynamodb:Scan, dynamodb:Query
コンソールで同じ権限を用意する場合、この6アクションを列挙したインラインポリシーJSONを自分で作成することになります。
4. Lambdaプロキシ統合とevent構造
http_method = event.get('httpMethod', '')
path = event.get('path', '')
path_parameters = event.get('pathParameters') or {}
body = event.get('body')
API Gatewayの「Lambdaプロキシ統合」を使うと、HTTPメソッド・パス・パスパラメータ・ボディがすべてeventに含まれた状態でLambdaに渡されます。SAMのEvents: Type: Apiは内部的にこのプロキシ統合を前提にしているため、5エンドポイント分のif分岐だけでルーティングが完結します。
まとめ
requirements.txtのcp932エラーは、UTF-8で正しく保存していても日本語コメート1つで再現するため、初見だと原因の特定に時間がかかります。Windows環境でSAM開発をする際は、このファイルだけ英語コメントに徹するのが安全です。完全な手順とトラブルシューティング表はこちらにまとめています。