Skip to content

Commit

Permalink
fix(lambda): version.fromVersionArn creates invalid Version object (#…
Browse files Browse the repository at this point in the history
…29820)

### Issue # (if applicable)

Closes #29813

### Reason for this change

improve the fromFunctionArn()  to better handle the input ARN

### Description of changes

fromFunctionArn() does not handle the ARN correctly if the input ARN has trailing version or alias.

### Description of how you validated changes

See unit tests

### Checklist
- [x] My code adheres to the [CONTRIBUTING GUIDE](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) and [DESIGN GUIDELINES](https://github.com/aws/aws-cdk/blob/main/docs/DESIGN_GUIDELINES.md)

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
  • Loading branch information
pahud authored Apr 12, 2024
1 parent f14b60f commit 8198884
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 1 deletion.
13 changes: 12 additions & 1 deletion packages/aws-cdk-lib/aws-lambda/lib/function.ts
Original file line number Diff line number Diff line change
Expand Up @@ -671,7 +671,18 @@ export class Function extends FunctionBase {
* in the same account and region as the stack you are importing it into.
*/
public static fromFunctionArn(scope: Construct, id: string, functionArn: string): IFunction {
return Function.fromFunctionAttributes(scope, id, { functionArn });
/**
* If the functionArn has a trailing version or alias (more than 7 parts when split by ":",
* we trim off the trailing version/alias to retrieve the real functionArn.
* See lambda resource ARN format here: https://docs.aws.amazon.com/lambda/latest/dg/lambda-api-permissions-ref.html
*/
const parts = functionArn.split(':');

This comment has been minimized.

Copy link
@rehos

rehos Apr 13, 2024

@pahud This split doesn't work if the function arn is passed to the CloudFormation stack as a parameter (i.e. the functionArn is an unresolved token). A solution could be:

if (Token.isUnresolved(functionArn)) {
    const parts =  Fn.split(':', functionArn);
    const _functionArn = cdk.Fn.join(':', [
        Fn.select(0, parts),
        Fn.select(1, parts),
        Fn.select(2, parts),
        Fn.select(3, parts),
        Fn.select(4, parts),
        Fn.select(5, parts),
        Fn.select(6, parts),
    ]);
    return Function.fromFunctionAttributes(scope, id, { functionArn: _functionArn });
} else {
    const parts = functionArn.split(':');
    if (parts.length > 7) {
      const _functionArn = parts.slice(0, 7).join(':');
      return Function.fromFunctionAttributes(scope, id, { functionArn: _functionArn });
    } else {
      return Function.fromFunctionAttributes(scope, id, { functionArn });
    }
}
if (parts.length > 7) {
const _functionArn = parts.slice(0, 7).join(':');
return Function.fromFunctionAttributes(scope, id, { functionArn: _functionArn });
} else {
return Function.fromFunctionAttributes(scope, id, { functionArn });
}
}

/**
Expand Down
24 changes: 24 additions & 0 deletions packages/aws-cdk-lib/aws-lambda/test/function.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,30 @@ describe('function', () => {
expect(imported.functionName).toEqual('ProcessKinesisRecords');
});

test('fromFunctionArn with verionArn as the input', () => {
// GIVEN
const stack2 = new cdk.Stack();

// WHEN
const imported = lambda.Function.fromFunctionArn(stack2, 'Imported', 'arn:aws:lambda:us-east-1:123456789012:function:ProcessKinesisRecords:1');

// THEN
expect(imported.functionArn).toEqual('arn:aws:lambda:us-east-1:123456789012:function:ProcessKinesisRecords');
expect(imported.functionName).toEqual('ProcessKinesisRecords');
});

test('fromFunctionArn with trailing alias as the input', () => {
// GIVEN
const stack2 = new cdk.Stack();

// WHEN
const imported = lambda.Function.fromFunctionArn(stack2, 'Imported', 'arn:aws:lambda:us-east-1:123456789012:function:ProcessKinesisRecords:TEST');

// THEN
expect(imported.functionArn).toEqual('arn:aws:lambda:us-east-1:123456789012:function:ProcessKinesisRecords');
expect(imported.functionName).toEqual('ProcessKinesisRecords');
});

test('Function.fromFunctionName', () => {
// GIVEN
const stack = new cdk.Stack();
Expand Down
3 changes: 3 additions & 0 deletions packages/aws-cdk-lib/aws-lambda/test/lambda-version.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ describe('lambda version', () => {
// WHEN
const version = lambda.Version.fromVersionArn(stack, 'Version', 'arn:aws:lambda:region:account-id:function:function-name:version');

expect(version.version).toStrictEqual('version');
expect(version.lambda.functionArn).toStrictEqual('arn:aws:lambda:region:account-id:function:function-name');

new cdk.CfnOutput(stack, 'ARN', { value: version.functionArn });
new cdk.CfnOutput(stack, 'Name', { value: version.functionName });

Expand Down

0 comments on commit 8198884

Please sign in to comment.