Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
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
26 changes: 17 additions & 9 deletions packages/@aws-cdk/aws-lambda/lib/code.ts
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ export class InlineCode extends Code {
*/
export class AssetCode extends Code {
public readonly isInline = false;
private asset?: s3_assets.Asset;
private assets: Record<string, s3_assets.Asset> = {};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not make this a Map<Stack, s3_assets.Asset>?

Simpler and more direct.


/**
* @param path The path to the asset file or directory.
Expand All @@ -242,35 +242,43 @@ export class AssetCode extends Code {
}

public bind(scope: cdk.Construct): CodeConfig {
// If the same AssetCode is used multiple times, retain only the first instantiation.
if (!this.asset) {
this.asset = new s3_assets.Asset(scope, 'Code', {
const stackPath = cdk.Stack.of(scope).node.path; // use path instead of name to account for Stage.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this good enough? Wouldn't the same stack path in multiple Apps still give the same error?

Copy link
Contributor

@rix0rrr rix0rrr Jan 8, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aha well. This change DOES address the issue it's purporting to address (use same code in multiple stacks inside the same app), but it does NOT address the error you mentioned, and would still fail if you reused a single Code object among multiple unit tests (each of them having a distinct App).

Cannot reference across apps. Consuming and producing stacks must be defined within the same CDK app.

let asset: s3_assets.Asset;
if (stackPath in this.assets) {
// If the same AssetCode is used multiple times, retain only the first instantiation.
asset = this.assets[stackPath];
} else {
asset = new s3_assets.Asset(scope, 'Code', {
path: this.path,
...this.options,
});
this.assets[stackPath] = asset;
}

if (!this.asset.isZipArchive) {
if (!asset.isZipArchive) {
throw new Error(`Asset must be a .zip file or a directory (${this.path})`);
}

return {
s3Location: {
bucketName: this.asset.s3BucketName,
objectKey: this.asset.s3ObjectKey,
bucketName: asset.s3BucketName,
objectKey: asset.s3ObjectKey,
},
};
}

public bindToResource(resource: cdk.CfnResource, options: ResourceBindOptions = { }) {
if (!this.asset) {
const stackPath = cdk.Stack.of(resource).node.path;
const asset = this.assets[stackPath];

if (!asset) {
throw new Error('bindToResource() must be called after bind()');
}

const resourceProperty = options.resourceProperty || 'Code';

// https://github.com/aws/aws-cdk/issues/1432
this.asset.addResourceMetadata(resource, resourceProperty);
asset.addResourceMetadata(resource, resourceProperty);
}
}

Expand Down
28 changes: 28 additions & 0 deletions packages/@aws-cdk/aws-lambda/test/code.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,34 @@ describe('code', () => {
},
}, ResourcePart.CompleteDefinition);
});

test('can be used in multiple stacks', () => {
// GIVEN
const app = new cdk.App();
const stack1 = new cdk.Stack(app, 'Stack1');
const stack2 = new cdk.Stack(app, 'Stack2');
const asset = lambda.Code.fromAsset(path.join(__dirname, 'my-lambda-handler'));

// WHEN
new lambda.Function(stack1, 'Func', {
code: asset,
runtime: lambda.Runtime.NODEJS_12_X,
handler: 'foom',
});
new lambda.Function(stack2, 'Func', {
code: asset,
runtime: lambda.Runtime.NODEJS_12_X,
handler: 'foom',
});

// THEN
const assembly = app.synth();
const synthesized1 = assembly.getStackArtifact(stack1.artifactId);
const synthesized2 = assembly.getStackArtifact(stack2.artifactId);

expect(synthesized1.assets.length).toEqual(1);
expect(synthesized2.assets.length).toEqual(1);
});
});

describe('lambda.Code.fromCfnParameters', () => {
Expand Down