0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Amazon S3 Presigned URL トラブルシューティング

Posted at

Amazon S3からオブジェクトをダウンロードしたり、アップロードしたりする際に使うgenerate_presigned_urlですが、いくつかはまりがちなポイントがあるのでまとめておきます。

前提

Presigned URLの生成はAWS LambdaからBoto3を用いて、こんな感じでやるパターンを想定します。

import boto3
s3_client = boto3.client("s3")
upload_url = s3_client.generate_presigned_url(
    ClientMethod = "put_object",
    Params = {
        'Bucket': "sample-bucket",
        'Key': "folder/object.json",
        'ContentType': "image/png"
    },
    ExpiresIn = 300,
    HttpMethod = "PUT"
)

トラブルシューティング

  1. URLの有効期限が切れてないか
    URLの有効期限、例では300は秒数です。デフォルトでは3600秒なので、1時間です。

  2. Bucketが存在するか
    このgenerate_presigned_urlはBucketが存在しなくても結果が返ってきます・・・
    Bucketを変数で指定している場合など、特にBucket名をもう一度ログに出力するなどして確認してください。

  3. アップロードやダウンロードの際のHTTPリクエストはHttpMethodと一致しているか
    この場合HttpMethodにはPUTを指定していますから、実際にPresigned URLを使うときはPUTを使います。 CURLならcurl -X PUTです。PUT指定したのにPOSTしてるとかよくあるので確認してください。

  4. ContentTypeが一致してるか
    これもPresigned URLを使ってコンテンツをアップロードする場合など、Content-Typeが一致してないと受け付けません。
    また、ワイルドカードContent-Type(image/*など)もうまくいきません。Content-Typeは明示してください。
    Curlなら、curl -H "Content-Type: image/png"です。

  5. S3 BucketにCORSの設定がされているか
    Presigned URLを使ってコンテンツをダウンロードしたり、アップロードする場合にも、そのBucketのCORSの設定が影響します。
    上記の例はPUTメソッドを使いますので、S3 BucketのCORSはPUTを許可してください。

    [
        {
            "AllowedHeaders": [
                "*"
            ],
            "AllowedMethods": [
                "PUT"
            ],
            "AllowedOrigins": [
                "*"
            ],
            "ExposeHeaders": []
        }
    ]
    
  6. Presigned URLを生成するLambda関数にS3へのアクセス権限があるかどうか
    Presigned URLをLambda関数から生成する場合に、生成するLambdaのロールには、Assume Roleする関係上、S3へのアクセス権が必要です。
    上記の例のようにput_objectを使う場合は書き込み権限が必要ですから、SAMのテンプレートを確認して、以下のようにS3へ権限が設定されているかS3WritePolicy確認してください。
    SAMを使っていない場合は、個別にLambdaのロールを確認して、S3へのWriteがあるか確認する必要があります。

  CreateUploadUrlFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: functions/create_upload_url
      Handler: handler.lambda_handler
      Runtime: python3.9
      Policies:
        - S3WritePolicy:
            BucketName: sample-bucket

まとめ

Presigned URLが動くかは、特にcurlで確認してください。上記のコードを確認するCurlコマンドは
curl -X PUT -H "Content-Type: image/png" -T uploadfile.png https://PRESIGNED_URLです。

特にLambdaからBoto3を使う場合、LambdaにS3の権限が設定されてないことが原因だったりします。誰かの役に立ちますように。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?