Skip to content

Commit

Permalink
feat(cli): support WebIdentityCredentials (as used by EKS) (#11559)
Browse files Browse the repository at this point in the history
Fixes #11543

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
  • Loading branch information
markussiebert authored Nov 30, 2020
1 parent c072981 commit 5cfbe6c
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 4 deletions.
2 changes: 1 addition & 1 deletion packages/aws-cdk/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -361,4 +361,4 @@ Some of the interesting keys that can be used in the JSON configuration files:
The following environment variables affect aws-cdk:

- `CDK_DISABLE_VERSION_CHECK`: If set, disable automatic check for newer versions.
- `CDK_NEW_BOOTSTRAP`: use the modern bootstrapping stack.
- `CDK_NEW_BOOTSTRAP`: use the modern bootstrapping stack.
18 changes: 15 additions & 3 deletions packages/aws-cdk/lib/api/aws-auth/awscli-compatible.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,13 @@ export class AwsCliCompatible {

if (options.containerCreds ?? hasEcsCredentials()) {
sources.push(() => new AWS.ECSCredentials());
} else if (hasWebIdentityCredentials()) {
// else if: we have found WebIdentityCredentials as provided by EKS ServiceAccounts
sources.push(() => new AWS.TokenFileWebIdentityCredentials());
} else if (options.ec2instance ?? await isEc2Instance()) {
// else if: don't get EC2 creds if we should have gotten ECS creds--ECS instances also
// run on EC2 boxes but the creds represent something different. Same behavior as
// upstream code.
// else if: don't get EC2 creds if we should have gotten ECS or EKS creds
// ECS and EKS instances also run on EC2 boxes but the creds represent something different.
// Same behavior as upstream code.
sources.push(() => new AWS.EC2MetadataCredentials());
}

Expand Down Expand Up @@ -156,6 +159,15 @@ function hasEcsCredentials(): boolean {
return (AWS.ECSCredentials.prototype as any).isConfiguredForEcsCredentials();
}

/**
* Return whether it looks like we'll have WebIdentityCredentials (that's what EKS uses) available
* No check like hasEcsCredentials available, so have to implement our own.
* @see https://github.com/aws/aws-sdk-js/blob/3ccfd94da07234ae87037f55c138392f38b6881d/lib/credentials/token_file_web_identity_credentials.js#L59
*/
function hasWebIdentityCredentials(): boolean {
return Boolean(process.env.AWS_ROLE_ARN && process.env.AWS_WEB_IDENTITY_TOKEN_FILE);
}

/**
* Return whether we're on an EC2 instance
*/
Expand Down
18 changes: 18 additions & 0 deletions packages/aws-cdk/test/util/awscli-compatible.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,21 @@ test('on an EC2 instance, region lookup queries IMDS', async () => {
});
});

test('Use web identity when available', async () => {

// Scrub some environment variables that are maybe set for Ecs Credentials
delete process.env.ECS_CONTAINER_METADATA_URI_V4;
delete process.env.ECS_CONTAINER_METADATA_URI;
delete process.env.AWS_CONTAINER_CREDENTIALS_RELATIVE_URI;

// create and configure the web identity token file
process.env.AWS_WEB_IDENTITY_TOKEN_FILE = 'some-value';
process.env.AWS_ROLE_ARN = 'some-value';

// create the chain
const providers = (await AwsCliCompatible.credentialChain()).providers;

// make sure the web identity provider is in the chain
const webIdentify = (providers[2] as Function)();
expect(webIdentify).toBeInstanceOf(AWS.TokenFileWebIdentityCredentials);
});

0 comments on commit 5cfbe6c

Please sign in to comment.