diff --git a/packages/@aws-cdk/aws-lambda-nodejs/README.md b/packages/@aws-cdk/aws-lambda-nodejs/README.md index 1d3eaa66a2a4a..ae6f6014fa9a1 100644 --- a/packages/@aws-cdk/aws-lambda-nodejs/README.md +++ b/packages/@aws-cdk/aws-lambda-nodejs/README.md @@ -284,3 +284,20 @@ should also have `npm`, `yarn` or `pnpm` depending on the lock file you're using Use the [default image provided by `@aws-cdk/aws-lambda-nodejs`](https://github.com/aws/aws-cdk/blob/master/packages/%40aws-cdk/aws-lambda-nodejs/lib/Dockerfile) as a source of inspiration. + +## Asset hash + +By default the asset hash will be calculated based on the bundled output (`AssetHashType.OUTPUT`). + +Use the `assetHash` prop to pass a custom hash: + +```ts +new lambda.NodejsFunction(this, 'my-handler', { + bundling: { + assetHash: 'my-custom-hash', + }, +}); +``` + +If you chose to customize the hash, you will need to make sure it is updated every time the asset +changes, or otherwise it is possible that some deployments will not be invalidated. diff --git a/packages/@aws-cdk/aws-lambda-nodejs/lib/bundling.ts b/packages/@aws-cdk/aws-lambda-nodejs/lib/bundling.ts index 5b7c6ce416b2c..31fedbafc6e3d 100644 --- a/packages/@aws-cdk/aws-lambda-nodejs/lib/bundling.ts +++ b/packages/@aws-cdk/aws-lambda-nodejs/lib/bundling.ts @@ -54,7 +54,8 @@ export class Bundling implements cdk.BundlingOptions { */ public static bundle(options: BundlingProps): AssetCode { return Code.fromAsset(options.projectRoot, { - assetHashType: cdk.AssetHashType.OUTPUT, + assetHash: options.assetHash, + assetHashType: options.assetHash ? cdk.AssetHashType.CUSTOM : cdk.AssetHashType.OUTPUT, bundling: new Bundling(options), }); } diff --git a/packages/@aws-cdk/aws-lambda-nodejs/lib/types.ts b/packages/@aws-cdk/aws-lambda-nodejs/lib/types.ts index 87d3de0eec1fc..b21d7a5fee5c2 100644 --- a/packages/@aws-cdk/aws-lambda-nodejs/lib/types.ts +++ b/packages/@aws-cdk/aws-lambda-nodejs/lib/types.ts @@ -248,6 +248,21 @@ export interface BundlingOptions { * @default - do not run additional commands */ readonly commandHooks?: ICommandHooks; + + /** + * Specify a custom hash for this asset. For consistency, this custom hash will + * be SHA256 hashed and encoded as hex. The resulting hash will be the asset + * hash. + * + * NOTE: the hash is used in order to identify a specific revision of the asset, and + * used for optimizing and caching deployment activities related to this asset such as + * packaging, uploading to Amazon S3, etc. If you chose to customize the hash, you will + * need to make sure it is updated every time the asset changes, or otherwise it is + * possible that some deployments will not be invalidated. + * + * @default - asset hash is calculated based on the bundled output + */ + readonly assetHash?: string; } /** diff --git a/packages/@aws-cdk/aws-lambda-nodejs/test/bundling.test.ts b/packages/@aws-cdk/aws-lambda-nodejs/test/bundling.test.ts index e79ddc2aca150..9ef40545baf31 100644 --- a/packages/@aws-cdk/aws-lambda-nodejs/test/bundling.test.ts +++ b/packages/@aws-cdk/aws-lambda-nodejs/test/bundling.test.ts @@ -658,3 +658,21 @@ test('esbuild bundling with pre compilations and undefined tsconfig ( Should thr }).toThrow('Cannot find a tsconfig.json, please specify the prop: tsconfig'); }); + +test('with custom hash', () => { + Bundling.bundle({ + entry, + projectRoot, + depsLockFilePath, + runtime: Runtime.NODEJS_14_X, + forceDockerBundling: true, + assetHash: 'custom', + architecture: Architecture.X86_64, + }); + + // Correctly passes asset hash options + expect(Code.fromAsset).toHaveBeenCalledWith(path.dirname(depsLockFilePath), expect.objectContaining({ + assetHash: 'custom', + assetHashType: AssetHashType.CUSTOM, + })); +});