Skip to content

Commit

Permalink
fix(aws-cdk): fix profiles in non-'aws' partitions
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
rix0rrr committed Dec 4, 2018
1 parent 0de2da8 commit 5aef969
Showing 1 changed file with 29 additions and 3 deletions.
32 changes: 29 additions & 3 deletions packages/aws-cdk/lib/api/util/sdk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down Expand Up @@ -206,7 +206,9 @@ class DefaultAWSAccount {
private defaultAccountId?: string = undefined;
private readonly accountCache = new AccountAccessKeyCache();

constructor(private readonly defaultCredentialsProvider: Promise<AWS.CredentialProviderChain>) {
constructor(
private readonly defaultCredentialsProvider: Promise<AWS.CredentialProviderChain>,
private readonly region: Promise<string | undefined>) {
}

/**
Expand All @@ -222,6 +224,21 @@ class DefaultAWSAccount {

private async lookupDefaultAccount(): Promise<string | undefined> {
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();
Expand All @@ -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');
Expand Down Expand Up @@ -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<string | undefined> {
try {
if (!await fs.pathExists(filename)) { return undefined; }
Expand Down

0 comments on commit 5aef969

Please sign in to comment.