Skip to content

Commit 5b92cc3

Browse files
authored
feat(lambda): add a fromFunctionName() method (#19076)
After #18255 has been merged, the account and region of the Function's imported ARN is correctly recognized. Unfortunately, this has surfaced a few cases where that causes problems, like when using an imported Function as the target of a CodePipeline invoke Action (the pipeline construct needs to verify that the target Function is in the same account and region as the pipeline). Add a `Function.fromFunctionName()` method that allows you to import a Function in the same account and region. Fixes #19031 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
1 parent 78f1076 commit 5b92cc3

File tree

4 files changed

+58
-2
lines changed

4 files changed

+58
-2
lines changed

packages/@aws-cdk/aws-lambda/README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -509,6 +509,14 @@ const fn = lambda.Function.fromFunctionAttributes(this, 'Function', {
509509
});
510510
```
511511

512+
If `fromFunctionArn()` causes an error related to having to provide an account and/or region in a different construct,
513+
and the lambda is in the same account and region as the stack you're importing it into,
514+
you can use `Function.fromFunctionName()` instead:
515+
516+
```ts
517+
const fn = lambda.Function.fromFunctionName(this, 'Function', 'MyFn');
518+
```
519+
512520
## Lambda with DLQ
513521

514522
A dead-letter queue can be automatically created for a Lambda function by

packages/@aws-cdk/aws-lambda/lib/function.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -435,6 +435,20 @@ export class Function extends FunctionBase {
435435
this._VER_PROPS[propertyName] = locked;
436436
}
437437

438+
/**
439+
* Import a lambda function into the CDK using its name
440+
*/
441+
public static fromFunctionName(scope: Construct, id: string, functionName: string): IFunction {
442+
return Function.fromFunctionAttributes(scope, id, {
443+
functionArn: Stack.of(scope).formatArn({
444+
service: 'lambda',
445+
resource: 'function',
446+
resourceName: functionName,
447+
arnFormat: ArnFormat.COLON_RESOURCE_NAME,
448+
}),
449+
});
450+
}
451+
438452
/**
439453
* Import a lambda function into the CDK using its ARN
440454
*/

packages/@aws-cdk/aws-lambda/test/function.test.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,42 @@ describe('function', () => {
298298
expect(imported.functionName).toEqual('ProcessKinesisRecords');
299299
});
300300

301+
test('Function.fromFunctionName', () => {
302+
// GIVEN
303+
const stack = new cdk.Stack();
304+
305+
// WHEN
306+
const imported = lambda.Function.fromFunctionName(stack, 'Imported', 'my-function');
307+
308+
// THEN
309+
expect(stack.resolve(imported.functionArn)).toStrictEqual({
310+
'Fn::Join': ['', [
311+
'arn:',
312+
{ Ref: 'AWS::Partition' },
313+
':lambda:',
314+
{ Ref: 'AWS::Region' },
315+
':',
316+
{ Ref: 'AWS::AccountId' },
317+
':function:my-function',
318+
]],
319+
});
320+
expect(stack.resolve(imported.functionName)).toStrictEqual({
321+
'Fn::Select': [6, {
322+
'Fn::Split': [':', {
323+
'Fn::Join': ['', [
324+
'arn:',
325+
{ Ref: 'AWS::Partition' },
326+
':lambda:',
327+
{ Ref: 'AWS::Region' },
328+
':',
329+
{ Ref: 'AWS::AccountId' },
330+
':function:my-function',
331+
]],
332+
}],
333+
}],
334+
});
335+
});
336+
301337
describe('Function.fromFunctionAttributes()', () => {
302338
let stack: cdk.Stack;
303339

packages/@aws-cdk/core/lib/arn.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -417,8 +417,6 @@ function parseArnShape(arn: string): 'token' | string[] {
417417
// Tokens won't contain ":", so this won't break them.
418418
const components = arn.split(':');
419419

420-
// const [/* arn */, partition, service, /* region */ , /* account */ , resource] = components;
421-
422420
const partition = components.length > 1 ? components[1] : undefined;
423421
if (!partition) {
424422
throw new Error('The `partition` component (2nd component) of an ARN is required: ' + arn);

0 commit comments

Comments
 (0)