Skip to content

Add support for loading shared config #1391

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conversation

jeskew
Copy link
Contributor

@jeskew jeskew commented Mar 7, 2017

This PR adds support for loading configuration from ~/.aws/config, including credentials, the default region to use, and role assumption metadata. This is an opt-in feature and will only take effect if the AWS_SDK_LOAD_CONFIG environment variable is set to something truthy.

I also added support for some configuration environment variables that we do not currently support, namely AWS_SHARED_CREDENTIALS_FILE and AWS_CONFIG_FILE, both of which will only be used if AWS_SDK_LOAD_CONFIG is set.

This should resolve #1196 as well (via AWS_SHARED_CREDENTIALS_FILE).

Resolves #1296
Resolves #1039
Resolves #993

@coveralls
Copy link

Coverage Status

Coverage decreased (-0.02%) to 90.382% when pulling 3e73060 on jeskew:jans510-Add-AWS_CREDENTIAL_PROFILES_FILE-Environment-Variable into cd6f728 on aws:master.

@alsmola
Copy link

alsmola commented Apr 12, 2017

Anything holding back a merge here? This functionality would be really useful for compatibility with other SDKs.

/**
* @api private
*/
AWS.SharedIniFile = AWS.util.inherit({
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this is private, you could treat this as a regular module instead of hanging the class on AWS. Then you won't have to do the side-effects require in node_loader.js.

@@ -111,8 +126,7 @@ AWS.SharedIniFileCredentials = AWS.util.inherit(AWS.Credentials, {
if (this.disableAssumeRole) {
throw AWS.util.error(
new Error('Role assumption profiles are disabled. ' +
'Failed to load profile ' + this.profile + ' from ' +
this.filename),
'Failed to load profile ' + this.profile),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you still get this.filename from creds.filename instead? It might still be useful to have the filename in the message, especially now that we will be looking at credentials and config.

return process.env.AWS_REGION || process.env.AMAZON_REGION;
var env = process.env;
var region = env.AWS_REGION || env.AMAZON_REGION;
if (!region && env.AWS_SDK_LOAD_CONFIG) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe we're actually supposed to check the credentials file for region, then the config file, similar to the CLI/boto.

@@ -2,9 +2,14 @@ var AWS = require('../core');
var path = require('path');
var STS = require('../../clients/sts');

var configOptInEnv = 'AWS_SDK_LOAD_CONFIG';
var sharedFileEnv = 'AWS_SHARED_CREDENTIALS_FILE';
var defaultProfile = 'default';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we grab defaultProfile from AWS.util.defaultProfile instead?

expect(AWS.util.readFileSync.calls[0].arguments[0]).to.match(/[\/\\]home[\/\\]user[\/\\].aws[\/\\]config/)
expect(AWS.util.readFileSync.calls[1].arguments[0]).to.equal(process.env.AWS_SHARED_CREDENTIALS_FILE)

it 'loads credentials from ~/.aws/config if AWS_SDK_LOAD_CONFIG is set', ->
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add a test to make sure the credentials from ~/.aws/credentials is used preferentially over the credentials in ~/.aws/config if the same profile exists in both files?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll add a test for that.

@chrisradek
Copy link
Contributor

One thing I'm not clear on, does the following scenario work:

  • profile in credentials file contains a roleArn and source profile
  • source profile is read from config file

@jeskew jeskew force-pushed the jans510-Add-AWS_CREDENTIAL_PROFILES_FILE-Environment-Variable branch from 3e73060 to fc4d210 Compare April 13, 2017 02:37
@jeskew
Copy link
Contributor Author

jeskew commented Apr 13, 2017

I had to force push due to a merge conflict in AWS.util. The last commit add the ability to assume a role for a profile defined in ~/.aws/credentials even if the source profile is defined ~/.aws/config and vice versa.

@codecov-io
Copy link

codecov-io commented Apr 13, 2017

Codecov Report

Merging #1391 into master will decrease coverage by 0.01%.
The diff coverage is 100%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #1391      +/-   ##
==========================================
- Coverage   95.35%   95.34%   -0.02%     
==========================================
  Files         176      177       +1     
  Lines        6222     6270      +48     
  Branches     1278     1293      +15     
==========================================
+ Hits         5933     5978      +45     
- Misses        289      292       +3
Impacted Files Coverage Δ
lib/util.js 93.33% <ø> (ø) ⬆️
lib/shared_ini.js 100% <100%> (ø)
lib/node_loader.js 85.71% <100%> (-11.73%) ⬇️
lib/credentials/shared_ini_file_credentials.js 98.59% <100%> (+4.38%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 55a8f68...7528c83. Read the comment docs.


it 'prefers credentials from ~/.aws/credentials if AWS_SDK_LOAD_CONFIG is set', ->
process.env.AWS_SDK_LOAD_CONFIG = '1'
mock = '''
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This mock can probably be removed.

</AssumeRoleResult>
</AssumeRoleResponse>
'''
debugger;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extra statement :)

aws_access_key_id = akid2
aws_secret_access_key = secret2
'''
helpers.mockHttpResponse 200, {}, '''
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure this test is actually ensuring that the creds from profile foo are used instead of default.

What do you think about spying on AWS.STS or AWS.Credentials to get the accessKeyId that was used as the source?

</AssumeRoleResult>
</AssumeRoleResponse>
'''
debugger;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extra statement.

@et304383
Copy link

et304383 commented Apr 18, 2017

Am I to understand that the SDK currently doesn't support ~/.aws at all? Or just doesn't support using assumed roles through the ~/.aws entries, which has only recently been added to PHP and worked a while in Python?

@chrisradek
Copy link
Contributor

@eric-tucker
The SDK currently sources credentials using ~/.aws/credentials by default. It actually can use assumed roles if they are defined in the credentials file. This change also allows ~/.aws/config to be used when sourcing credentials, since most of the other SDKs support this now as well.

profiles[availableProfiles[i]] || {},
creds.getProfile(availableProfiles[i])
);
for (i = 0, availableProfiles = creds.getProfiles(); i < availableProfiles.length; i++) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Can we either use var i here, or declare var i at the top of the function? Just worried if we someday change i in the for loop above, then this i becomes a global.

@jeskew jeskew force-pushed the jans510-Add-AWS_CREDENTIAL_PROFILES_FILE-Environment-Variable branch from 12e966a to 7528c83 Compare April 19, 2017 17:41
Copy link
Contributor

@chrisradek chrisradek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit:

@dotchev
Copy link

dotchev commented Sep 16, 2017

Why not load ~/.aws/confi by default as AWS CLI does?

@chrisradek
Copy link
Contributor

@dotchev
We can't do that until we make a major version bump, because this could lead to the SDK loading different credentials without any code changes in consuming code. We do plan on loading ~/.aws/config by default like the CLI does when we do a major bump, but I can't give a timeline on when that will be.

tavisrudd added a commit to unbounce/iidy that referenced this pull request Oct 29, 2017
tavisrudd added a commit to unbounce/iidy that referenced this pull request Nov 22, 2017
This appears to be a bug upstream as a result of
aws/aws-sdk-js#1391 We now check for the
presence of ~/.aws prior to setting this env-var.
@lucleray
Copy link

Hi,

This page is still confusing : https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/setting-region.html#setting-region-config-file.

"The SDK for JavaScript automatically searches for a config file when it loads."

I understand here that I need to set AWS_SDK_LOAD_CONFIG to something truthy to get that behavior. Is this documented somewhere ?

@jeskew
Copy link
Contributor Author

jeskew commented Jan 29, 2018

The AWS_SDK_LOAD_CONFIG environment variable is only documented on that page in the "Order of Precedence for Setting the Region" section. I'll try to get the "Using a Shared Config File" section updated to reflect this.

@lucleray
Copy link

Thanks!

@villasv
Copy link

villasv commented Jul 18, 2018

@chrisradek any update on the version bump? Having this inconsistency for over a year is enough justification for a major release IMHO

@rezarajabii
Copy link

It would have been nice if you could add an example of using this feature. I am having issues of using assume role with JS.

@ctmlr
Copy link

ctmlr commented Jan 9, 2019

This seems to be missing support for the mfa_serial option.

@lock
Copy link

lock bot commented Sep 28, 2019

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs and link to relevant comments in this thread.

@lock lock bot locked as resolved and limited conversation to collaborators Sep 28, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet