thomasmichaelwallace / serverless-better-credentials

Better AWS credentials resolution plugin for serverless
MIT License
54 stars 9 forks source link

Error: no such file or directory '.aws/credentials' #1

Closed Michael-1 closed 2 years ago

Michael-1 commented 2 years ago

This plugin seems to have no effect.

Extract from serverless.yml:

plugins:
  - serverless-better-credentials
  - serverless-esbuild
  - serverless-offline
  - '@haftahave/serverless-ses-template'

Running aws sso login --profile stage and then npx sls offline --stage local --aws-profile stage returns:

Environment: darwin, node 14.19.0, framework 3.2.1 (local), plugin 6.0.0, SDK 4.3.1
Credentials: Local, environment variables
Docs:        docs.serverless.com
Support:     forum.serverless.com
Bugs:        github.com/serverless/serverless/issues

Error:
Error: ENOENT: no such file or directory, open '/Users/michael/.aws/credentials'
    at Object.openSync (fs.js:497:3)
    at Object.readFileSync (fs.js:393:35)
    at Object.readFileSync (/Users/michael/code/emails/node_modules/aws-sdk/lib/util.js:95:26)

(Stack trace continues for a dozen more lines.)

Expected behavior

Serverless uses the credentials that I got with aws sso login.

Environment

thomasmichaelwallace commented 2 years ago

That's interesting - can I check that you have a file called ~/.aws/credentials ?

The reason I'm asking is a lot of people tend to use ~/.aws/config instead.

If you have ~/.aws/config then you need to tell the aws-sdk, which you can do by adding AWS_SDK_LOAD_CONFIG=1 to your environment (docs).

A quick test might be to try AWS_SDK_LOAD_CONFIG=1 npx sls offline --stage local --aws-profile stage and see if that works.

Michael-1 commented 2 years ago

Hey Thomas, thanks for getting back on this so promptly.

Indeed, I have no file ~/.aws/credentials – AWS SSO seems to use ~/.aws/config. Setting AWS_SDK_LOAD_CONFIG=1 brings me further; the container now starts successfully.

✔ serverless-better-credentials: credentials resolved from config sso profile: cli --aws-profile (stage)
Compiling to node14 bundle with esbuild...
Compiling with concurrency: Infinity
Compiling completed.

However, if then I invoke the function, I’m back on the same field:

Error [CredentialsError]: Missing credentials in config, if using AWS_CONFIG_FILE, set AWS_SDK_LOAD_CONFIG=1
    at Timeout.connectTimeout [as _onTimeout] (/Users/michael/code/emails/node_modules/aws-sdk/lib/http/node.js:69:15)
    at listOnTimeout (internal/timers.js:557:17)
    at processTimers (internal/timers.js:500:7) {
  code: 'CredentialsError',
  time: 2022-03-16T15:36:34.631Z,
  retryable: true,
  originalError: {
    message: 'Could not load credentials from any providers',
    code: 'CredentialsError',
    time: 2022-03-16T15:36:34.631Z,
    retryable: true,
    originalError: {
      message: 'EC2 Metadata roleName request returned error',
      code: 'TimeoutError',
      time: 2022-03-16T15:36:34.631Z,
      retryable: true,
      originalError: [Object]
    }
  }
}

This occurs when I try to get an object from S3. I have verified that process.env.AWS_SDK_LOAD_CONFIG is set to 1 when the call happens.

thomasmichaelwallace commented 2 years ago

Awesome - glad to have got the deployment sorted.

I'll add something to the documentation about AWS_SDK_LOAD_CONFIG, as I note that it's on a completely different page to the one about setting up SSO.

All this plugin was really intended for was the sls deploy command; and to compound things I haven't used the serverless-offline plugin. However, I do have some insights into how the aws-sdk and sls work to access your credentials, so let's see if we can get this off the ground.

That error is happening because you're trying to access AWS using the aws-sdk and SSO credentials aren't being resolved (EC2 Metadata is the last thing it tries). My plugin does the heavy lifting of sorting that when sls tries to access AWS directly, but won't do that for anything else.

Can you use the almost very latest 2.1093.0 or higher (change log) version of the aws-sdk, because that has SSO support that should work if serverless-offline is just copying your .aws folder into the container?

Michael-1 commented 2 years ago

Can you use the almost very latest 2.1093.0 or higher (change log) version of the aws-sdk, because that has SSO support that should work …

I’m using version 2.1094.0 (see original post).

… if serverless-offline is just copying your .aws folder into the container?

How can I verify if it’s doing so? (In the folder .esbuild, where the compiled files reside that I believe serverless-offline is using, there is no folder .aws.)

All this plugin was really intended for was the sls deploy command; and to compound things I haven't used the serverless-offline plugin.

I understand. Thank you for your help, nevertheless!

thomasmichaelwallace commented 2 years ago

Cool- in theory 2.1094.0 supports fetching from the SSO credentials cache, so it should work. (sorry; should have checked your original post!)

Looking at how serverless-offline resolves credentials, however, suggests that it doesn't use the serverless framework to do it. That does mean that it's probably not respecting --aws-profile, etc.

Can I confirm the command you're using to invoke the function?

Looking at the (docs) I think you need to be doing something like: AWS_PROFILE=cli AWS_SDK_LOAD_CONFIG=1 serverless offline.

Michael-1 commented 2 years ago

I’m using

AWS_SDK_LOAD_CONFIG=1 npx sls offline --stage local --aws-profile stage

to start the container, then

curl --request POST 'http://localhost:3000/local' -H "Content-Type: application/json" -d @__mocks__/event/payment-minimal.json

to invoke it.

thomasmichaelwallace commented 2 years ago

OK- I'll see if I can mock something up to experiment with;

Did you try/have any luck with AWS_PROFILE=_name_of_profile_ AWS_SDK_LOAD_CONFIG=1 serverless offline --stage local --aws-profile stage?

From the (docs) I think you will need to do this.

Michael-1 commented 2 years ago

That works, indeed, also without the aws-profile parameter:

AWS_PROFILE=stage AWS_SDK_LOAD_CONFIG=1 serverless offline --stage local
thomasmichaelwallace commented 2 years ago

Awesome- glad I could help 😄