adamdabb
adamdabb

Reputation: 306

Fargate returning root domain for presigned S3 URLs - Node

I have an endpoint on my API that simply uses the AWS SDK to generate a presigned URL for one of our S3 buckets. When hitting the endpoint locally, it works fine every time. However, on the first request to the deployed version (running on Fargate), the first call always returns the base S3 URL:

https://s3.amazonaws.com/

If you hit the API a second time, it generates the correct URL, and continues to do so as long as the API is warm. If you wait long enough and try hitting it again, it happens again.

I've verified that the params for generating the URL are correct, even when it generates the wrong URL. I've also added retry logic within the same method, but that continues to return the invalid URL.

Here is the code in question (including the retry):

const s3Params = {
            Key: fileName,
            Expires: 120,
            ContentType: contentType,
            ACL: "public-read",
            Bucket: process.env.IMAGE_UPLOAD_BUCKET,
        };

        let uploadUrl = this.awsService.getS3Instance().getSignedUrl("putObject", s3Params);
        // Sometimes this call fails and returns a blank URL
        if (uploadUrl === "https://s3.amazonaws.com/") {
            // Try one more time
            uploadUrl = this.awsService.getS3Instance().getSignedUrl("putObject", s3Params);
        }


        return [uploadUrl, s3Params.Key];

Any recommendations for troubleshooting this further?

Upvotes: 1

Views: 367

Answers (1)

Hannu
Hannu

Reputation: 21

You need to use asynchronous callback, because Fargate uses asynchronous credential provider. It is stated in the documentation as follows:

Note: You must ensure that you have static or previously resolved credentials if you call this method synchronously (with no callback), otherwise it may not properly sign the request. If you cannot guarantee this (you are using an asynchronous credential provider, i.e., EC2 IAM roles), you should always call this method with an asynchronous callback.

https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#getSignedUrl-property

Upvotes: 2

Related Questions