diff --git a/packages/@aws-cdk/aws-lambda/lib/function-base.ts b/packages/@aws-cdk/aws-lambda/lib/function-base.ts index 623fabb68820a..3bbda22f1b465 100644 --- a/packages/@aws-cdk/aws-lambda/lib/function-base.ts +++ b/packages/@aws-cdk/aws-lambda/lib/function-base.ts @@ -285,8 +285,12 @@ export abstract class FunctionBase extends Resource implements IFunction { return (principal as iam.ServicePrincipal).service; } + if (`arn` in principal) { + return (principal as iam.ArnPrincipal).arn; + } + throw new Error(`Invalid principal type for Lambda permission statement: ${principal.constructor.name}. ` + - 'Supported: AccountPrincipal, ServicePrincipal'); + 'Supported: AccountPrincipal, ArnPrincipal, ServicePrincipal'); } } diff --git a/packages/@aws-cdk/aws-lambda/test/test.lambda.ts b/packages/@aws-cdk/aws-lambda/test/test.lambda.ts index 09a36697952a9..7cb3fee771356 100644 --- a/packages/@aws-cdk/aws-lambda/test/test.lambda.ts +++ b/packages/@aws-cdk/aws-lambda/test/test.lambda.ts @@ -186,15 +186,16 @@ export = { test.done(); }, - 'fails if the principal is not a service or account principals'(test: Test) { + 'fails if the principal is not a service, account or arn principal'(test: Test) { const stack = new cdk.Stack(); const fn = newTestLambda(stack); - test.throws(() => fn.addPermission('F1', { principal: new iam.ArnPrincipal('just:arn') }), + test.throws(() => fn.addPermission('F1', { principal: new iam.OrganizationPrincipal('org') }), /Invalid principal type for Lambda permission statement/); fn.addPermission('S1', { principal: new iam.ServicePrincipal('my-service') }); fn.addPermission('S2', { principal: new iam.AccountPrincipal('account') }); + fn.addPermission('S3', { principal: new iam.ArnPrincipal('my:arn') }); test.done(); }, @@ -1074,6 +1075,34 @@ export = { test.done(); }, + 'grantInvoke with an arn principal'(test: Test) { + // GIVEN + const stack = new cdk.Stack(); + const fn = new lambda.Function(stack, 'Function', { + code: lambda.Code.inline('xxx'), + handler: 'index.handler', + runtime: lambda.Runtime.NODEJS_8_10, + }); + const account = new iam.ArnPrincipal('arn:aws:iam::123456789012:role/someRole'); + + // WHEN + fn.grantInvoke(account); + + // THEN + expect(stack).to(haveResource('AWS::Lambda::Permission', { + Action: 'lambda:InvokeFunction', + FunctionName: { + 'Fn::GetAtt': [ + 'Function76856677', + 'Arn' + ] + }, + Principal: 'arn:aws:iam::123456789012:role/someRole' + })); + + test.done(); + }, + 'Can use metricErrors on a lambda Function'(test: Test) { // GIVEN const stack = new cdk.Stack();