diff --git a/lib/plugins/aws/provider/awsProvider.js b/lib/plugins/aws/provider/awsProvider.js index af0dc9199..3af8fbf36 100644 --- a/lib/plugins/aws/provider/awsProvider.js +++ b/lib/plugins/aws/provider/awsProvider.js @@ -59,6 +59,8 @@ const impl = { const profileCredentials = new AWS.SharedIniFileCredentials({ profile }); if (Object.keys(profileCredentials).length) { credentials.profile = profile; // eslint-disable-line no-param-reassign + // eslint-disable-next-line no-param-reassign + credentials.profileCredentials = profileCredentials; } impl.addCredentials(credentials, profileCredentials); } @@ -176,7 +178,13 @@ class AwsProvider { impl.addEnvironmentCredentials(credentials, `AWS_${stageUpper}`); // stage specific creds impl.addEnvironmentProfile(credentials, `AWS_${stageUpper}`); - if (Object.keys(credentials).length) { + if (credentials.profileCredentials != null && credentials.accessKeyId == null) { + // A profile was specified, but there is no access key present. This + // typically means that that temporary credentials are generated on demand. + // In this case just use the original AWS.SharedIniFileCredentials object, + // and let the AWS library handle the details. + returnValue.credentials = credentials.profileCredentials; + } else if (Object.keys(credentials).length) { returnValue.credentials = credentials; } return returnValue; diff --git a/lib/plugins/aws/provider/awsProvider.test.js b/lib/plugins/aws/provider/awsProvider.test.js index 6e4bd6f28..29cb3e245 100644 --- a/lib/plugins/aws/provider/awsProvider.test.js +++ b/lib/plugins/aws/provider/awsProvider.test.js @@ -4,6 +4,7 @@ const BbPromise = require('bluebird'); const expect = require('chai').expect; const proxyquire = require('proxyquire'); const sinon = require('sinon'); +const AWS = require('aws-sdk'); const AwsProvider = require('./awsProvider'); const Serverless = require('../../../Serverless'); @@ -351,6 +352,7 @@ describe('AwsProvider', () => { const credentials = newAwsProvider.getCredentials(); restoreEnv({ AWS_PROFILE: prevVal }); expect(credentials.credentials.profile).to.equal('notDefault'); + expect(credentials.credentials).to.instanceof(AWS.SharedIniFileCredentials); }); it('should get credentials from environment declared stage-specific profile', () => { @@ -359,6 +361,14 @@ describe('AwsProvider', () => { const credentials = newAwsProvider.getCredentials(); restoreEnv({ AWS_TESTSTAGE_PROFILE: prevVal }); expect(credentials.credentials.profile).to.equal('notDefault'); + expect(credentials.credentials).to.instanceof(AWS.SharedIniFileCredentials); + }); + + it('should get credentials from provider declared profile', () => { + serverless.service.provider.profile = 'notDefault'; + const credentials = newAwsProvider.getCredentials(); + expect(credentials.credentials.profile).to.equal('notDefault'); + expect(credentials.credentials).to.instanceof(AWS.SharedIniFileCredentials); }); });