From 9ae2d30c15c9bce3cae70ccbe6e227c096005695 Mon Sep 17 00:00:00 2001 From: bojeil-google Date: Tue, 23 Mar 2021 12:12:04 -0700 Subject: [PATCH] fix: support AWS_DEFAULT_REGION for determining AWS region (#1149) `AWS_DEFAULT_REGION` is also a supported environment variable for the AWS region: https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-envvars.html Priority order for region determination: `AWS_REGION` > `AWS_DEFAULT_REGION` > AWS metadata server --- src/auth/awsclient.ts | 11 +++++++---- test/test.awsclient.ts | 35 +++++++++++++++++++++++++++++++++-- 2 files changed, 40 insertions(+), 6 deletions(-) diff --git a/src/auth/awsclient.ts b/src/auth/awsclient.ts index 6b873488..9995e2f7 100644 --- a/src/auth/awsclient.ts +++ b/src/auth/awsclient.ts @@ -27,7 +27,8 @@ import {RefreshOptions} from './oauth2client'; export interface AwsClientOptions extends BaseExternalAccountClientOptions { credential_source: { environment_id: string; - // Region can also be determined from the AWS_REGION environment variable. + // Region can also be determined from the AWS_REGION or AWS_DEFAULT_REGION + // environment variables. region_url?: string; // The url field is used to determine the AWS security credentials. // This is optional since these credentials can be retrieved from the @@ -78,7 +79,7 @@ export class AwsClient extends BaseExternalAccountClient { super(options, additionalOptions); this.environmentId = options.credential_source.environment_id; // This is only required if the AWS region is not available in the - // AWS_REGION environment variable + // AWS_REGION or AWS_DEFAULT_REGION environment variables. this.regionUrl = options.credential_source.region_url; // This is only required if AWS security credentials are not available in // environment variables. @@ -200,8 +201,10 @@ export class AwsClient extends BaseExternalAccountClient { * @return A promise that resolves with the current AWS region. */ private async getAwsRegion(): Promise { - if (process.env['AWS_REGION']) { - return process.env['AWS_REGION']; + // Priority order for region determination: + // AWS_REGION > AWS_DEFAULT_REGION > metadata server. + if (process.env['AWS_REGION'] || process.env['AWS_DEFAULT_REGION']) { + return (process.env['AWS_REGION'] || process.env['AWS_DEFAULT_REGION'])!; } if (!this.regionUrl) { throw new Error( diff --git a/test/test.awsclient.ts b/test/test.awsclient.ts index b318cea2..9ce18920 100644 --- a/test/test.awsclient.ts +++ b/test/test.awsclient.ts @@ -527,18 +527,21 @@ describe('AwsClient', () => { let envAwsSecretAccessKey: string | undefined; let envAwsSessionToken: string | undefined; let envAwsRegion: string | undefined; + let envAwsDefaultRegion: string | undefined; beforeEach(() => { // Store external state. envAwsAccessKeyId = process.env.AWS_ACCESS_KEY_ID; envAwsSecretAccessKey = process.env.AWS_SECRET_ACCESS_KEY; envAwsSessionToken = process.env.AWS_SESSION_TOKEN; - envAwsAccessKeyId = process.env.AWS_REGION; + envAwsRegion = process.env.AWS_REGION; + envAwsDefaultRegion = process.env.AWS_DEFAULT_REGION; // Reset environment variables. delete process.env.AWS_ACCESS_KEY_ID; delete process.env.AWS_SECRET_ACCESS_KEY; delete process.env.AWS_SESSION_TOKEN; delete process.env.AWS_REGION; + delete process.env.AWS_DEFAULT_REGION; }); afterEach(() => { @@ -563,6 +566,11 @@ describe('AwsClient', () => { } else { delete process.env.AWS_REGION; } + if (envAwsDefaultRegion) { + process.env.AWS_DEFAULT_REGION = envAwsDefaultRegion; + } else { + delete process.env.AWS_DEFAULT_REGION; + } }); describe('retrieveSubjectToken()', () => { @@ -614,10 +622,33 @@ describe('AwsClient', () => { scope.done(); }); - it('should resolve when AWS region is set as environment variable', async () => { + it('should resolve when AWS_REGION is set as environment variable', async () => { + process.env.AWS_ACCESS_KEY_ID = accessKeyId; + process.env.AWS_SECRET_ACCESS_KEY = secretAccessKey; + process.env.AWS_REGION = awsRegion; + + const client = new AwsClient(awsOptions); + const subjectToken = await client.retrieveSubjectToken(); + + assert.deepEqual(subjectToken, expectedSubjectTokenNoToken); + }); + + it('should resolve when AWS_DEFAULT_REGION is set as environment variable', async () => { + process.env.AWS_ACCESS_KEY_ID = accessKeyId; + process.env.AWS_SECRET_ACCESS_KEY = secretAccessKey; + process.env.AWS_DEFAULT_REGION = awsRegion; + + const client = new AwsClient(awsOptions); + const subjectToken = await client.retrieveSubjectToken(); + + assert.deepEqual(subjectToken, expectedSubjectTokenNoToken); + }); + + it('should prioritize AWS_REGION over AWS_DEFAULT_REGION environment variable', async () => { process.env.AWS_ACCESS_KEY_ID = accessKeyId; process.env.AWS_SECRET_ACCESS_KEY = secretAccessKey; process.env.AWS_REGION = awsRegion; + process.env.AWS_DEFAULT_REGION = 'fail-if-used'; const client = new AwsClient(awsOptions); const subjectToken = await client.retrieveSubjectToken();