Description
This is a question about expected behavior.
Let's say I have the following code (Node 7.5.0 because of async/await).
(async function () {
const govcloudCredential = new CredentialProviderChain([
() => { return new EnvironmentCredentials('GC_AWS'); },
() => { return new EnvironmentCredentials('GC_AMAZON'); },
() => { return new SharedIniFileCredentials({ profile: 'govcloud' }); },
() => { return new SharedIniFileCredentials({ profile: 'default' }); },
() => { return new EC2MetadataCredentials(); }
]);
const s3 = new S3({
region: 'us-gov-west-1',
credentials: undefined,
credentialProvider: govcloudCredential
});
try {
const foo = await s3.listObjectsV2({
Bucket: 'bucket'
}).promise();
console.log(foo.KeyCount);
} catch (error) {
console.error(error);
}
})()
And ~/.aws/credentials
file:
[default]
aws_access_key_id = valid-for-commercial
aws_secret_access_key = valid-for-commercial
[govcloud]
aws_access_key_id = valid-for-gov-cloud
aws_secret_access_key = valid-for-gov-cloud
[commercial]
aws_access_key_id = valid-for-commercial
aws_secret_access_key = valid-for-commercial
I would expect that the resulting S3
instance would pull from the explicit provider chain. Such that if I ran the code it would pull from the govcloud
section and work fine. However, it pulls from default
and thus prevents my call from succeeding. Just to be sure I checked by removing the default
group. Then the call actually pulls from govcloud
.
This behavior, to me, seems counter-intuitive. Can someone help my intuition?
Update
(async function () {
const govcloudCredential = new CredentialProviderChain([
() => { return new EnvironmentCredentials('GC_AWS'); },
() => { return new EnvironmentCredentials('GC_AMAZON'); },
() => { return new SharedIniFileCredentials({ profile: 'govcloud' }); },
() => { return new SharedIniFileCredentials({ profile: 'default' }); },
() => { return new EC2MetadataCredentials(); }
]);
const creds = new Promise<Credentials>((resolve, reject) => {
govcloudCredential.resolve((error, creds) => {
if (error) { reject(error); }
else { resolve(creds); }
});
});
const s3 = new S3({
region: 'us-gov-west-1',
credentials: (await creds)
});
try {
const foo = await s3.listObjectsV2({
Bucket: 'refman-bundler-dev'
}).promise();
console.log(foo.KeyCount);
} catch (error) {
console.error(error);
}
})()
This second example code does work as I expect but notice now I have explicitly called resolve
and I am awaiting the credentials resolving before creating my S3
object. This does feel like the way the documentation indicates this should work.