Skip to content

Commit

Permalink
fix(assets): add missing SAM asset metadata information (#17591)
Browse files Browse the repository at this point in the history
Following up on issue #14593

The integration with SAM tool requires to have some more info about the Assets. SAM needs to know if the Asset was already bundled or not, and what is the original asset path before staging.

This change is to add the following assets metadata:
 - aws:asset:is-bundled 
 - aws:asset:original-path

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
  • Loading branch information
moelasmar authored Nov 19, 2021
1 parent 9b2158b commit 55df760
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 3 deletions.
7 changes: 6 additions & 1 deletion packages/@aws-cdk/aws-lambda/test/code.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ describe('code', () => {
expect(stack).toHaveResource('AWS::Lambda::Function', {
Metadata: {
[cxapi.ASSET_RESOURCE_METADATA_PATH_KEY]: 'asset.9678c34eca93259d11f2d714177347afd66c50116e1e08996eff893d3ca81232',
[cxapi.ASSET_RESOURCE_METADATA_ORIGINAL_PATH_KEY]: location,
[cxapi.ASSET_RESOURCE_METADATA_IS_BUNDLED_KEY]: false,
[cxapi.ASSET_RESOURCE_METADATA_PROPERTY_KEY]: 'Code',
},
}, ResourcePart.CompleteDefinition);
Expand Down Expand Up @@ -462,8 +464,9 @@ describe('code', () => {
stack.node.setContext(cxapi.ASSET_RESOURCE_METADATA_ENABLED_CONTEXT, true);

// when
const FunctionCodepath = path.join(__dirname, 'docker-build-lambda');
new lambda.Function(stack, 'Fn', {
code: lambda.Code.fromDockerBuild(path.join(__dirname, 'docker-build-lambda')),
code: lambda.Code.fromDockerBuild(FunctionCodepath),
handler: 'index.handler',
runtime: lambda.Runtime.NODEJS_12_X,
});
Expand All @@ -472,6 +475,8 @@ describe('code', () => {
expect(stack).toHaveResource('AWS::Lambda::Function', {
Metadata: {
[cxapi.ASSET_RESOURCE_METADATA_PATH_KEY]: 'asset.fbafdbb9ae8d1bae0def415b791a93c486d18ebc63270c748abecc3ac0ab9533',
[cxapi.ASSET_RESOURCE_METADATA_ORIGINAL_PATH_KEY]: FunctionCodepath,
[cxapi.ASSET_RESOURCE_METADATA_IS_BUNDLED_KEY]: false,
[cxapi.ASSET_RESOURCE_METADATA_PROPERTY_KEY]: 'Code',
},
}, ResourcePart.CompleteDefinition);
Expand Down
5 changes: 4 additions & 1 deletion packages/@aws-cdk/aws-lambda/test/layers.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,14 +74,17 @@ describe('layers', () => {
stack.node.setContext(cxapi.ASSET_RESOURCE_METADATA_ENABLED_CONTEXT, true);

// WHEN
let layerCodePath = path.join(__dirname, 'layer-code');
new lambda.LayerVersion(stack, 'layer', {
code: lambda.Code.fromAsset(path.join(__dirname, 'layer-code')),
code: lambda.Code.fromAsset(layerCodePath),
});

// THEN
expect(canonicalizeTemplate(SynthUtils.toCloudFormation(stack))).toHaveResource('AWS::Lambda::LayerVersion', {
Metadata: {
'aws:asset:path': 'asset.Asset1Hash',
'aws:asset:original-path': layerCodePath,
'aws:asset:is-bundled': false,
'aws:asset:property': 'Content',
},
}, ResourcePart.CompleteDefinition);
Expand Down
2 changes: 2 additions & 0 deletions packages/@aws-cdk/aws-logs/test/log-retention.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,8 @@ describe('log retention', () => {
expect(stack).toHaveResource('AWS::Lambda::Function', {
Metadata: {
'aws:asset:path': assetLocation,
'aws:asset:original-path': assetLocation,
'aws:asset:is-bundled': false,
'aws:asset:property': 'Code',
},
}, ResourcePart.CompleteDefinition);
Expand Down
20 changes: 19 additions & 1 deletion packages/@aws-cdk/aws-s3-assets/lib/asset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,13 +120,29 @@ export class Asset extends CoreConstruct implements cdk.IAsset {

public readonly assetHash: string;

/**
* The original Asset Path before it got staged.
*
* If asset staging is disabled, this will be same value as assetPath.
* If asset staging is enabled, it will be the Asset original path before staging.
*/
private readonly originalAssetPath: string;

/**
* Indicates if this asset got bundled before staged, or not.
*/
private readonly isBundled: boolean;

constructor(scope: Construct, id: string, props: AssetProps) {
super(scope, id);

this.originalAssetPath = path.resolve(props.path);
this.isBundled = props.bundling != null;

// stage the asset source (conditionally).
const staging = new cdk.AssetStaging(this, 'Stage', {
...props,
sourcePath: path.resolve(props.path),
sourcePath: this.originalAssetPath,
follow: props.followSymlinks ?? toSymlinkFollow(props.follow),
assetHash: props.assetHash ?? props.sourceHash,
});
Expand Down Expand Up @@ -191,6 +207,8 @@ export class Asset extends CoreConstruct implements cdk.IAsset {
// points to a local path in order to enable local invocation of this function.
resource.cfnOptions.metadata = resource.cfnOptions.metadata || { };
resource.cfnOptions.metadata[cxapi.ASSET_RESOURCE_METADATA_PATH_KEY] = this.assetPath;
resource.cfnOptions.metadata[cxapi.ASSET_RESOURCE_METADATA_ORIGINAL_PATH_KEY] = this.originalAssetPath;
resource.cfnOptions.metadata[cxapi.ASSET_RESOURCE_METADATA_IS_BUNDLED_KEY] = this.isBundled;
resource.cfnOptions.metadata[cxapi.ASSET_RESOURCE_METADATA_PROPERTY_KEY] = resourceProperty;
}

Expand Down
8 changes: 8 additions & 0 deletions packages/@aws-cdk/aws-s3-assets/test/asset.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,8 @@ test('addResourceMetadata can be used to add CFN metadata to resources', () => {
expect(stack).toHaveResource('My::Resource::Type', {
Metadata: {
'aws:asset:path': 'asset.6b84b87243a4a01c592d78e1fd3855c4bfef39328cd0a450cc97e81717fea2a2',
'aws:asset:original-path': location,
'aws:asset:is-bundled': false,
'aws:asset:property': 'PropName',
},
}, ResourcePart.CompleteDefinition);
Expand All @@ -222,6 +224,8 @@ test('asset metadata is only emitted if ASSET_RESOURCE_METADATA_ENABLED_CONTEXT
expect(stack).not.toHaveResource('My::Resource::Type', {
Metadata: {
'aws:asset:path': SAMPLE_ASSET_DIR,
'aws:asset:original-path': SAMPLE_ASSET_DIR,
'aws:asset:is-bundled': false,
'aws:asset:property': 'PropName',
},
}, ResourcePart.CompleteDefinition);
Expand Down Expand Up @@ -351,6 +355,8 @@ describe('staging', () => {
const template = SynthUtils.synthesize(stack).template;
expect(template.Resources.MyResource.Metadata).toEqual({
'aws:asset:path': 'asset.6b84b87243a4a01c592d78e1fd3855c4bfef39328cd0a450cc97e81717fea2a2',
'aws:asset:original-path': SAMPLE_ASSET_DIR,
'aws:asset:is-bundled': false,
'aws:asset:property': 'PropName',
});
});
Expand All @@ -377,6 +383,8 @@ describe('staging', () => {
const template = SynthUtils.synthesize(stack).template;
expect(template.Resources.MyResource.Metadata).toEqual({
'aws:asset:path': SAMPLE_ASSET_DIR,
'aws:asset:original-path': SAMPLE_ASSET_DIR,
'aws:asset:is-bundled': false,
'aws:asset:property': 'PropName',
});
});
Expand Down
2 changes: 2 additions & 0 deletions packages/@aws-cdk/cx-api/lib/assets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ export const ASSET_RESOURCE_METADATA_DOCKERFILE_PATH_KEY = 'aws:asset:dockerfile
export const ASSET_RESOURCE_METADATA_DOCKER_BUILD_ARGS_KEY = 'aws:asset:docker-build-args';
export const ASSET_RESOURCE_METADATA_DOCKER_BUILD_TARGET_KEY = 'aws:asset:docker-build-target';
export const ASSET_RESOURCE_METADATA_PROPERTY_KEY = 'aws:asset:property';
export const ASSET_RESOURCE_METADATA_IS_BUNDLED_KEY = 'aws:asset:is-bundled';
export const ASSET_RESOURCE_METADATA_ORIGINAL_PATH_KEY = 'aws:asset:original-path';

/**
* Separator string that separates the prefix separator from the object key separator.
Expand Down

0 comments on commit 55df760

Please sign in to comment.