-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
What's the deal with credentials. It's voodoo. #1276
Comments
Hi @cmawhorter, I understand your frustration, but deprecating the global configuration object and requiring users to instantiate var AWS = require('aws-sdk');
var s3_east = new AWS.S3({region: 'us-east-1'});
s3_west = new AWS.S3({region: 'us-west-2'}); Any option that can be set via |
I'd like to see The way the js aws sdk loads credentials is... unique. I can't think of any other node lib that does anything close to this.
In practice, I've found this to not always be true. I've seen some mighty weird things around loading credentials. I've implemented with the constructor as you describe and inspect the object and confirm it's correctly set, only to have it still claim the region is missing or make it to the wrong region. I have no idea how that is even possible, which is why I opted to always instantiate a new service client at the time of using. That was the only thing I've found that is guaranteed to work. Is it possible to log where the credentials are being pulled from or better yet -- disable all credential loading magic? Edit: I found #710 which seems to at least partially describe what I've seen most recently. Also #880. Perhaps there is some lingering weirdness here? My problems weren't limited to ddb in the past, but lately, they've all been ddb related. Also -- is it possible a node dependency is using a diff version of aws and the two different versions are somehow sharing state or something? |
Getting rid of AWS.config.update isn't something we could do without a major version bump, but I'll mark this issue as a feature request to make sure we keep this feedback in mind when we do get an opportunity to make breaking changes.
When loaded in node, the SDK exports an AWS object, so each installed version of the SDK would maintain its own state. The default credential loader, however, relies on process and machine state to determine which credentials to use to sign a request: it checks environment variables, which would be shared by all installed versions of the SDK running in the same shell or process; it then checks for file-based credentials in a known location ( |
I think what I'm seeing is a bug related to a race maybe. I've recently started using a tool for deployment that requires AWS_PROFILE be set. I'm a little murky on the internals of how aws sdk handles loading, but my gut says because that var is set, it begins to async load e.g. export AWS_PROFILE=whatever
node script.js // script.js
var AWS = require('aws-sdk'); // detects AWS_PROFILE
AWS.config.update({ ... }); A race would explain the intermittent nature of what I'm seeing. Though it doesn't explain why in the past, I've had an s3 client object config say it was set to one region, but ended up making requests against another, and throwing an error that the bucket didn't exist. At any rate. I'm just going to be putting this as the first line in the entry point for my aws dependent code: if (process.env.NODE_ENV === 'development') {
Object.keys(process.env).forEach(key => 0 === key.indexOf('AWS_') ? delete process.env[key] : null);
}
var AWS = require('aws-sdk'); |
I don't think removing var ec2Client = new AWS.EC2(awsConfig) Where Otherwise, the idea of managing multiple subscriptions in-process becomes significantly more complicated. Currently today, if we asynchronously use multiple AWS credentials, we'll mix up EC2 instances between different subscriptions because one configuration bleeds over for another client. Why would you allow for dynamically instantiated clients ( |
@sedouard Taking a look at the EC2 constructor as an example, you'll notice that the Behind the scenes, the configuration passed to a service client is merged on top of a copy of |
I think I finally figured out the problem with the voodoo:
Does AWS_PROFILE get higher priority than I don't know. And that's my problem. Instead of magic on That auto-loading behavior of aws-sdk has bit me numerous times during dev. With code being deployed to wrong environments/accounts and seemingly valid credentials being rejected for some unknown reason.
If someone is using AWS.config somewhere, it's very difficult to figure out where/what/when that global method is being invoked and can lead to a race with credentials and different configs being used depending on which async code ran an AWS.config when. In practice, I never use AWS.config. But dependencies and more junior developers sometimes do. (Largely because of the abundance of docs and blog posts out there saying to use AWS.config). And that fact leads to extremely difficult to debug problems. And if you're all-in on using AWS.config, there is no way to tell an EC2 constructor for example, to not merge the global AWS.config. So even if you're doing Edit: Added inverse example |
I'd like to add my anger and frustration to this thread. I just lost half of a day I couldn't afford to lose hunting this garbage down. How many 10s's of thousands of man hours has this dumb decision (AWS.config overriding other AWS.config) cost us? I don't care if it's a breaking change, you have namespaced versions of your SDK. Make the change. |
I'd also like to add my anger and frustration to this thread (I believe this is the right place to do it, but if not, please do tell me). I've tried everything... From trying to update the credentials in the global AWS config, to keeping a reference to the credentials object passed to the service object so I can refresh them with a new token. This is my situation:
The problem is that the max duration of the token in step #2 is 24hs. So, when my client application creates an AWS.S3 object with some CognitoIdentityCredentials that use this token, this S3 object is doomed to last no more than 24hs (just because I cannot update/refresh the CognitoIdentityCredentials that the S3 is using). Am I right? I still think that maybe I'm missing something but I've done my research (i.e. Amazon Doc see last section "Immutable Configuration Data") and I cannot find where my error is. Thanks in advance to anyone that can help me... |
Got bit by this today. Here was our use-case, simplified:
In order to fix this, we had to change the return of
Basically, you can't bind anything to the global config, because there's a race to write to it and AWS will blow away whatever it finds there whenever it finishes loading up the credentials. Count me as one more who was caught off guard by the code above not working as expected. I'm rarely an advocate for backwards-incompatible changes, but race conditions for your main configuration seems like much more of a bug than a feature. |
To the original poster - var AWS = require('aws-sdk')
var s3 = new AWS.S3(); //s3 object created with whatever config is default for you
console.log('1. s3 region', s3.config.region); // us-east-1 //**looks like it's us-east-1
AWS.config.update({ region: 'us-west-2' }) //**this will affect future S3 objects but not the existing s3 isntance!
console.log('2. s3 region', s3.config.region); // us-east-1 //**still using original s3 object created in line 2
var s3 = new AWS.S3(); //**updates the config
console.log('3. s3 region', s3.config.region); // us-west-2 //**uses the new s3 object with the new config This is working reliably for me when you take this into consideration. Your workaround described initially is essentially enforcing the correct order of operations for you. |
so, first of all... i discovered aws-sdk v3 the other day and was extremely happy to see they burned aws-sdk v2 to the ground. this lib is garbage and has been the source of so much pain and suffering for so many. you're not a js dev until you've posted a rant here at aws/aws-sdk-js/issues. and @trunderw that might work in your environment but i would hesitate to say it's universal because of the variety of ways AWS can infer credentials from the env and the variety of ways some jr dev (or yourself a year later) can mess that up for everyone. it's such a mess i've just enforced always providing a region to service constructors and you must allow AWS to get creds from env. period. this means AWS_PROFILE on the dev machine and letting aws-sdk do its thing on ec2/lambda. once i did that all these issues disappeared. if for some reason you can't lean on iam roles and have to juggle creds yourself... god help you. the other issue is the i-wish-i-was-windows vague error messages aws-sdk spits out along with obscuring the real error/stack behind the internal state machine bs. meaning -- if for whatever reason AWS fails to load any local credentials it'll fall back to trying to get them via remote http. this leads to a totally unrelated (but seemingly related) error message about an http timeout that is easy to mistake as being because your endpoint/region is wrong. (there is another issue about this somewhere around here). i can't tell you how many times i've had to resort to console.log(1), 2, 3, 4, ... to figure out why/where something lead to an error that aws-sdk has swallowed. it's probably days of my life at this point which just makes me sad. and with that. i'm done here. here's to hoping MS/azure's wins continue to push AWS into action because there sure as hell wasn't any action until azure showed up. |
@cmawhorter: given the points about the environment maybe clarifying what mine is will help someone in the future. My particular S3-focused (with occasional ECR) app is running by itself on node in a docker container on a kubernetes cluster. There's nothing else running in the pod so from that perspective, it should avoid config creep from jr or any other well-intentioned developers. Maybe that is the only environment that the aws js sdk is certified to work with =) |
Hey @cmawhorter, Is this still an ongoing feature-request after #1317 ? Will go ahead and close this issue. Please re-open/reach out if you have any additional questions. |
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. |
Today I'm spending my latest hour of time debugging an issue relating to the way aws sdk loads credentials. Apart from the swallowing of errors, this is my single biggest pain point with the js aws sdk.
It seems that
require('aws-sdk')
does some magic to load credentials, but it's a very bad magician. It' more... "is this your card" than "i just made the statue of liberty disappear".This is the only way I've found to reliably use aws-sdk across all environments (tests, browserify/webpack, lambda, ec2, etc.).
And now, throw in the async nature of cognito credential loading and mixed-credential environments, and the time I've spent working through problems around loading credentials in aws sdk can be measured in the tens of hours.
Please, please, please give me
var aws = new AWS({ ...config... })
and deprecate the global AWS object.AWS.config.update is badddddddddd. It's global, but it isn't.
Hate your job? Sprinkle
AWS.config.update
's throughout the codebase and watch as your team pulls their hair out.The text was updated successfully, but these errors were encountered: