From 5aef969e5705f40a84ca5d1bde83855abe1c783e Mon Sep 17 00:00:00 2001 From: Rico Huijbers Date: Tue, 4 Dec 2018 15:40:13 +0100 Subject: [PATCH 1/2] fix(aws-cdk): fix profiles in non-'aws' partitions Properly pass on the default region to the STS call we make to discover the default AWS credentials. Also, there is no way to make use of AssumeRole profiles without the AWS_SDK_LOAD_CONFIG flag being set, so reintroduce setting that flag if we discover the file to exist. Fixes #1262 and #1109. --- packages/aws-cdk/lib/api/util/sdk.ts | 32 +++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/packages/aws-cdk/lib/api/util/sdk.ts b/packages/aws-cdk/lib/api/util/sdk.ts index dc4af454df42d..b62a63b629d86 100644 --- a/packages/aws-cdk/lib/api/util/sdk.ts +++ b/packages/aws-cdk/lib/api/util/sdk.ts @@ -72,7 +72,7 @@ export class SDK { }); } - this.defaultAwsAccount = new DefaultAWSAccount(defaultCredentialProvider); + this.defaultAwsAccount = new DefaultAWSAccount(defaultCredentialProvider, getCLICompatibleDefaultRegion(this.profile)); this.credentialsCache = new CredentialsCache(this.defaultAwsAccount, defaultCredentialProvider); } @@ -206,7 +206,9 @@ class DefaultAWSAccount { private defaultAccountId?: string = undefined; private readonly accountCache = new AccountAccessKeyCache(); - constructor(private readonly defaultCredentialsProvider: Promise) { + constructor( + private readonly defaultCredentialsProvider: Promise, + private readonly region: Promise) { } /** @@ -222,6 +224,21 @@ class DefaultAWSAccount { private async lookupDefaultAccount(): Promise { try { + // There just is *NO* way to do AssumeRole credentials as long as AWS_SDK_LOAD_CONFIG is not set. The SDK + // crash if the file does not exist though. So set the environment variable if we can find that file. + await setConfigVariable(); + + // support these + // This might try to load a profile which as AssumeRole credentials. This will normally work for the JS SDK + // if AWS_PROFILE/AWS_SDK_LOAD_CONFIG are set, but we don't set those (we work directly from the API). + // + // Since there is no way to pass a { region } argument to the STS client used for AssumeRole credentials + // (https://github.com/aws/aws-sdk-js/issues/2377), we must now configure the region globally so that it will + // be picked up there. + // AWS.config.update({ + // region: await this.region + // }); + debug('Resolving default credentials'); const credentialProvider = await this.defaultCredentialsProvider; const creds = await credentialProvider.resolvePromise(); @@ -234,7 +251,7 @@ class DefaultAWSAccount { const accountId = await this.accountCache.fetch(creds.accessKeyId, async () => { // if we don't have one, resolve from STS and store in cache. debug('Looking up default account ID from STS'); - const result = await new AWS.STS({ credentials: creds }).getCallerIdentity().promise(); + const result = await new AWS.STS({ credentials: creds, region: await this.region }).getCallerIdentity().promise(); const aid = result.Account; if (!aid) { debug('STS didn\'t return an account ID'); @@ -389,6 +406,15 @@ async function hasEc2Credentials() { return instance; } +async function setConfigVariable() { + const homeDir = process.env.HOME || process.env.USERPROFILE + || (process.env.HOMEPATH ? ((process.env.HOMEDRIVE || 'C:/') + process.env.HOMEPATH) : null) || os.homedir(); + + if (await fs.pathExists(path.resolve(homeDir, '.aws', 'config'))) { + process.env.AWS_SDK_LOAD_CONFIG = '1'; + } +} + async function readIfPossible(filename: string): Promise { try { if (!await fs.pathExists(filename)) { return undefined; } From 982bf6896834956f1654b2255e3bc0452be517ef Mon Sep 17 00:00:00 2001 From: Rico Huijbers Date: Wed, 5 Dec 2018 10:12:45 +0100 Subject: [PATCH 2/2] Remove stale comment --- packages/aws-cdk/lib/api/util/sdk.ts | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/packages/aws-cdk/lib/api/util/sdk.ts b/packages/aws-cdk/lib/api/util/sdk.ts index b62a63b629d86..a22752c1f5807 100644 --- a/packages/aws-cdk/lib/api/util/sdk.ts +++ b/packages/aws-cdk/lib/api/util/sdk.ts @@ -228,17 +228,6 @@ class DefaultAWSAccount { // crash if the file does not exist though. So set the environment variable if we can find that file. await setConfigVariable(); - // support these - // This might try to load a profile which as AssumeRole credentials. This will normally work for the JS SDK - // if AWS_PROFILE/AWS_SDK_LOAD_CONFIG are set, but we don't set those (we work directly from the API). - // - // Since there is no way to pass a { region } argument to the STS client used for AssumeRole credentials - // (https://github.com/aws/aws-sdk-js/issues/2377), we must now configure the region globally so that it will - // be picked up there. - // AWS.config.update({ - // region: await this.region - // }); - debug('Resolving default credentials'); const credentialProvider = await this.defaultCredentialsProvider; const creds = await credentialProvider.resolvePromise();