AWS Lambda - CredentialsProviderError

0

I am encountering a "CredentialsProviderError" in my AWS Lambda function. The Lambda function is designed to interact with Amazon S3. The primary task of this Lambda function involves fetching a JSON file from a specified S3 bucket and responding with the retrieved data.

Despite having an IAM role associated with the function and the appropriate policies attached, the Lambda execution is failing to load credentials from any providers. This operation worked seamlessly when the Lambda function was utilizing AWS SDK v2. However, upon migrating to AWS SDK v3, the Lambda function encounters a "CredentialsProviderError."

The Lambda function does not explicitly set AWS SDK credentials, as it is expected to inherit them from the execution role.

Execution Role Trust Policy:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "lambda.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}

IAM Policy Attached to Execution Role:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:*",
                "s3-object-lambda:*"
            ],
            "Resource": "*"
        }
    ]
}
profile picture
posta 3 mesi fa202 visualizzazioni
1 Risposta
0

Hi Utsab,

this might be related to a change in behavior with the AWS SDK v3. A similar issue is documented in this GitHub issue: https://github.com/aws/aws-sdk-js-v3/issues/4867

Could you maybe share the relevant code parts of your Lambda function to help narrow this down?

Thanks, Ben

profile pictureAWS
ESPERTO
con risposta 3 mesi fa
  • Hi Ben, thank you for your prompt response.

    As I mentioned earlier, the Lambda function is quite straightforward. It simply retrieves a JSON file from an S3 bucket and returns the corresponding JSON response.

    import { fromNodeProviderChain } from "@aws-sdk/credential-providers";
    import { S3Client, GetObjectCommand } from "@aws-sdk/client-s3";
    
    const credentials = fromNodeProviderChain();
    const s3 = new S3Client({ credentials });
    
    const Bucket = "<bucket-name>"
    const Key = "<file-name>"
    
    export const handler = async function (event) {
      try {
        const command = new GetObjectCommand({ Bucket, Key });
        const response = await s3.send(command);
        const str = await response.Body.transformToString(); 
        const body = JSON.parse(str);
        return {
          statusCode: 200,
          body,
        }
      } catch (err) {
        console.error('Failed to get the file from S3', err);
        throw err;
      }
    };
    
  • Thanks for sharing the code. Is there a particular reason why you need the credentials explicitly? You can just create the S3 Client without additional configuration. See https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/setting-credentials-node.html for

    AWS SDK for JavaScript V3 provides a default credential provider chain in Node.js, so you are not required to supply a credential provider explicitly.

    Please be also aware that as per documentation https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/setting-credentials-node.html, you normally don't need to use fromNodeProviderChain explicitly:

    but with default role assumers so you don't need to import them from STS client and supply them manually. You normally don't need to use this explicitly in the client constructor.

  • Appreciate the detailed explanation! I initially faced issues with the default configuration of the S3 client, resulting in Could not load credentials from any providers error. To address this, I added fromNodeProviderChain as a precautionary measure. Interestingly, it didn't resolve the issue either.

    import { S3Client, GetObjectCommand } from "@aws-sdk/client-s3";
    
    const s3 = new S3Client({ region: 'eu-west-1' });
    
    const Bucket = "<bucket-name>"
    const Key = "<file-name>"
    
    export const handler = async function (event) {
      try {
        const command = new GetObjectCommand({ Bucket, Key });
        const response = await s3.send(command);
        const str = await response.Body.transformToString(); 
        const body = JSON.parse(str);
        return {
          statusCode: 200,
          body,
        }
      } catch (err) {
        console.error('Failed to get the file from S3', err);
        throw err;
      }
    };
    
  • Hi, thanks for the quick response. Have you tried using the @aws-sdk/credential-provider-node instead. See also the comment on this question: https://repost.aws/questions/QUXMX9z9zCSb21qsnedFZQpg/having-trouble-converting-aws-node-sdk-v2-lambda-to-v3

  • Tried using the @aws-sdk/credential-provider-node as well. Still getting the same error

    import { defaultProvider } from '@aws-sdk/credential-provider-node';
    import { S3Client, GetObjectCommand } from "@aws-sdk/client-s3";
    
    const s3 = new S3Client({ region:'eu-west-1',  credentials: defaultProvider() });
    

Accesso non effettuato. Accedi per postare una risposta.

Una buona risposta soddisfa chiaramente la domanda, fornisce un feedback costruttivo e incoraggia la crescita professionale del richiedente.

Linee guida per rispondere alle domande