Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(lambda-layer-awscli): Dynamically load asset for AwsCliLayer, with bundled fallback #21938

Closed
Closed
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
217a199
feat(lambda): add Code.fromAssetConstruct API for creating Code objec…
madeline-k Sep 7, 2022
3819c26
add to README
madeline-k Sep 7, 2022
6d45a8f
feat: Dynamically load asset for AwsCliLayer, with bundled fallback
madeline-k Sep 7, 2022
7e68272
Merge branch 'main' into madeline-k/reduce-package-size/lambda-layer-…
madeline-k Sep 20, 2022
c244bc8
Revert "feat(lambda): add Code.fromAssetConstruct API for creating Co…
madeline-k Sep 20, 2022
a829e28
Revert "add to README"
madeline-k Sep 20, 2022
b01414b
update to use latest name and api from @aws-cdk/asset-awscli-v1 package
madeline-k Sep 20, 2022
dcaf2ce
temporarily adjust coverage thresholds so that jest succeeds, and the…
madeline-k Sep 20, 2022
5a35d5a
wip
madeline-k Sep 21, 2022
da1f1ba
Merge branch 'main' into madeline-k/reduce-package-size/lambda-layer-…
madeline-k Sep 21, 2022
1f856c7
updates
madeline-k Sep 27, 2022
f0376b4
re-add original zip generation
madeline-k Sep 28, 2022
403313a
download zip from the external npm package, and fallback to use that
madeline-k Sep 29, 2022
18fc81c
refactor to use a slightly more functional pattern. This should be mo…
madeline-k Sep 29, 2022
9312860
remove saving state in static variable
madeline-k Sep 29, 2022
3f901f1
update jest config to raise coverage thresholds again
madeline-k Sep 29, 2022
42b84ed
make some static methods public and @internal so they can be tested
kaizencc Sep 29, 2022
f236539
add quiet option on awscli layer
kaizencc Oct 4, 2022
0f0a89e
include requirements.txt in the directory that is used to generate th…
madeline-k Oct 11, 2022
19b9c8b
some logging updates
madeline-k Oct 11, 2022
a14b01a
update logging, tests, and add a construct for the Cli Notice
madeline-k Oct 11, 2022
7c7083f
add README troubleshooting instructions
madeline-k Oct 11, 2022
a5e37e7
package.json updates
madeline-k Oct 11, 2022
c9b8740
Merge branch 'main' into madeline-k/reduce-package-size/lambda-layer-…
madeline-k Oct 11, 2022
4e84738
update yarn.lock to use 2.0.0, linter fixes in README, set CDK_DEBUG …
madeline-k Oct 11, 2022
6d5dd99
add set -eu
madeline-k Oct 11, 2022
7657203
modify pre-build script to copy files from local node_modules
madeline-k Oct 12, 2022
bda4f88
refactor functions into a separate file so they can be private and us…
madeline-k Oct 12, 2022
8c2edba
more updates
madeline-k Oct 12, 2022
b2af0c6
get target version at build time
madeline-k Oct 12, 2022
01f194e
update warning message
madeline-k Oct 12, 2022
4b11d81
remove WARNING from the warning. It's a warning.
madeline-k Oct 12, 2022
a5e35f6
fix comma placement, and add real github issue link
madeline-k Oct 12, 2022
7415ae8
use semver
madeline-k Oct 12, 2022
729f9cb
yarn build --fix
madeline-k Oct 12, 2022
9227e93
fix string match in test
madeline-k Oct 12, 2022
af77de9
use compatible semver range
madeline-k Oct 12, 2022
33df916
update asset-awscli dependency, add error handling for mkdirSync
madeline-k Oct 12, 2022
70d9fb7
remove requirement.txt from being tracked by git, since it is now gen…
madeline-k Oct 12, 2022
b9d5bd8
temporarily lower coverage thresholds
madeline-k Oct 12, 2022
2ab6282
fix: remove node_modules folder after test adds it in
kaizencc Oct 13, 2022
e97124c
fix download location to avoid duplicate node_modules folders
kaizencc Oct 13, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion packages/@aws-cdk/lambda-layer-awscli/jest.config.js
Original file line number Diff line number Diff line change
@@ -1,2 +1,10 @@
const baseConfig = require('@aws-cdk/cdk-build-tools/config/jest.config');
module.exports = baseConfig;
module.exports = {
...baseConfig,
coverageThreshold: {
global: {
branches: 10,
statements: 50,
},
},
};
1 change: 0 additions & 1 deletion packages/@aws-cdk/lambda-layer-awscli/layer/.dockerignore

This file was deleted.

54 changes: 0 additions & 54 deletions packages/@aws-cdk/lambda-layer-awscli/layer/Dockerfile

This file was deleted.

18 changes: 0 additions & 18 deletions packages/@aws-cdk/lambda-layer-awscli/layer/build.sh

This file was deleted.

This file was deleted.

69 changes: 64 additions & 5 deletions packages/@aws-cdk/lambda-layer-awscli/lib/awscli-layer.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,78 @@
/* eslint-disable no-console */
import * as childproc from 'child_process';
import * as path from 'path';
import * as lambda from '@aws-cdk/aws-lambda';
import { FileSystem } from '@aws-cdk/core';
import * as s3_assets from '@aws-cdk/aws-s3-assets';
import * as cdk from '@aws-cdk/core';
import { Construct } from 'constructs';

/**
* An AWS Lambda layer that includes the AWS CLI.
*/
export class AwsCliLayer extends lambda.LayerVersion {

private static readonly assetPackageName: string = '@aws-cdk/asset-awscli-v1';
private static readonly fallbackLocation: string = '';
private static assetPackage: any;
private static asset: s3_assets.Asset;

private static requireWrapper(id: string): any {
try {
// eslint-disable-next-line @typescript-eslint/no-require-imports
return require(id);
} catch (err) {
console.log(`require('${id}') failed`);
console.log(err);
if (err instanceof Error) {
console.error(err.name, err.message.split('\n')[0]);
}
}
}

private static installNpmPackage(): any {
// TODO install to a well-known location and then copy over to the current node_modules closure
const installDir = require.main?.paths[0].split('/').slice(0, -1).join('/');
if (!installDir) {
return;
}
console.log(`Shelling out to run npm install ${this.assetPackageName} --no-save --prefix ${installDir}`);
const result = childproc.execSync(`pwd; npm prefix; npm install ${this.assetPackageName} --no-save --prefix ${installDir}`);
console.log(result.toString('utf8'));
return this.requireWrapper(path.join(installDir, 'node_modules', this.assetPackageName, 'lib/index.js'));
}

constructor(scope: Construct, id: string) {

const targetVersion = AwsCliLayer.requireWrapper(path.join(__dirname, '../package.json')).devDependencies[AwsCliLayer.assetPackageName];
const pathOfModuleIfAlreadyInstalled = require.resolve(`${AwsCliLayer.assetPackageName}`);
const versionAlreadyInstalled = AwsCliLayer.requireWrapper(path.join(pathOfModuleIfAlreadyInstalled, '../../package.json')).version;
let usedFallback = false;

if (targetVersion === versionAlreadyInstalled) {
AwsCliLayer.assetPackage = AwsCliLayer.requireWrapper(AwsCliLayer.assetPackageName);
}
if (!AwsCliLayer.assetPackage) {
AwsCliLayer.assetPackage = AwsCliLayer.installNpmPackage();
}
if (!AwsCliLayer.assetPackage) {
AwsCliLayer.assetPackage = AwsCliLayer.requireWrapper(AwsCliLayer.fallbackLocation);
usedFallback = true;
}
if (!AwsCliLayer.assetPackage) {
// This case should never happen, until the fallback to a package bundled in aws-cdk-lib is removed.
throw new Error(`Unable to load ${AwsCliLayer.assetPackageName}@${targetVersion}`);
}

AwsCliLayer.asset = new AwsCliLayer.assetPackage.AwsCliAsset(scope, `${id}-asset`);

super(scope, id, {
code: lambda.Code.fromAsset(path.join(__dirname, 'layer.zip'), {
// we hash the layer directory (it contains the tools versions and Dockerfile) because hashing the zip is non-deterministic
assetHash: FileSystem.fingerprint(path.join(__dirname, '../layer')),
}),
code: lambda.Code.fromBucket(AwsCliLayer.asset.bucket, AwsCliLayer.asset.s3ObjectKey),
description: '/opt/awscli/aws',
});

if (usedFallback) {
cdk.Annotations.of(this).addWarning('This CDK app will be impacted by an upcoming change...');
// TODO add a 'marker' construct to the construct tree so that we can create a CLI notice for this scenario
}
}
}
6 changes: 3 additions & 3 deletions packages/@aws-cdk/lambda-layer-awscli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -78,17 +78,20 @@
"@aws-cdk/integ-runner": "0.0.0",
"@aws-cdk/integ-tests": "0.0.0",
"@aws-cdk/pkglint": "0.0.0",
"@aws-cdk/asset-awscli-v1": "0.0.13",
"@types/jest": "^27.5.2",
"jest": "^27.5.1"
},
"dependencies": {
"@aws-cdk/aws-lambda": "0.0.0",
"@aws-cdk/aws-s3-assets": "0.0.0",
"@aws-cdk/core": "0.0.0",
"constructs": "^10.0.0"
},
"homepage": "https://github.com/aws/aws-cdk",
"peerDependencies": {
"@aws-cdk/aws-lambda": "0.0.0",
"@aws-cdk/aws-s3-assets": "0.0.0",
"@aws-cdk/core": "0.0.0",
"constructs": "^10.0.0"
},
Expand All @@ -101,9 +104,6 @@
"announce": false
},
"cdk-build": {
"pre": [
"layer/build.sh"
],
"env": {
"AWSLINT_BASE_CONSTRUCT": true
}
Expand Down
14 changes: 14 additions & 0 deletions packages/@aws-cdk/lambda-layer-awscli/test/awscli-layer.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,17 @@ test('synthesized to a layer version', () => {
Description: '/opt/awscli/aws',
});
});

test('installing from npm', () => {
//jest.mock('lambda-layer-awscli-v1', () => undefined);
//GIVEN
const stack = new Stack();

// WHEN
new AwsCliLayer(stack, 'MyLayer');

// THEN
Template.fromStack(stack).hasResourceProperties('AWS::Lambda::LayerVersion', {
Description: '/opt/awscli/aws',
});
});
5 changes: 5 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@
"@jridgewell/gen-mapping" "^0.1.0"
"@jridgewell/trace-mapping" "^0.3.9"

"@aws-cdk/[email protected]":
version "0.0.13"
resolved "https://registry.npmjs.org/@aws-cdk/asset-awscli-v1/-/asset-awscli-v1-0.0.13.tgz#8964f075ad3647a6fde657ea29f020b6ec903841"
integrity sha512-dZ856tGTmh9zR0fomydNwDnW2JDlCdnNzY5AwAoOB8ZgifXTYQxMzQ6dVoVEN6VPOB+UDW/eULeF3a7ER7xRvA==

"@babel/[email protected]":
version "7.12.11"
resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz#f4ad435aa263db935b8f10f2c552d23fb716a63f"
Expand Down