Skip to content

Commit e222e87

Browse files
IainColeElad Ben-Israel
authored andcommitted
fix(lambda): allow ArnPrincipal in grantInvoke (#3501)
Fixes #3264 I'm trying to allow a lambda function in another account to be able to invoke my CDK generated lambda function. This works through the CLI like so: aws lambda add-permission --function-name=myFunction --statement-id=ABoldStatement --action=lambda:InvokeFunction --principal=arn:aws:iam::{account_id}:role/a_lambda_execution_role But CDK doesn't seem to allow me to add an ArnPrincipal doing something like this: myFunction.grantInvoke(new iam.ArnPrincipal(props.myARN)) With the error: Invalid principal type for Lambda permission statement: ArnPrincipal. Supported: AccountPrincipal, ServicePrincipal This PR allows ArnPrincipal to be passed to lambda.grantInvoke. There might be some additional validation required on the exact ARN as I believe only some ARNs are supported by lambda add-permission
1 parent 07f017b commit e222e87

File tree

2 files changed

+36
-3
lines changed

2 files changed

+36
-3
lines changed

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -285,8 +285,12 @@ export abstract class FunctionBase extends Resource implements IFunction {
285285
return (principal as iam.ServicePrincipal).service;
286286
}
287287

288+
if (`arn` in principal) {
289+
return (principal as iam.ArnPrincipal).arn;
290+
}
291+
288292
throw new Error(`Invalid principal type for Lambda permission statement: ${principal.constructor.name}. ` +
289-
'Supported: AccountPrincipal, ServicePrincipal');
293+
'Supported: AccountPrincipal, ArnPrincipal, ServicePrincipal');
290294
}
291295
}
292296

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

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -186,15 +186,16 @@ export = {
186186
test.done();
187187
},
188188

189-
'fails if the principal is not a service or account principals'(test: Test) {
189+
'fails if the principal is not a service, account or arn principal'(test: Test) {
190190
const stack = new cdk.Stack();
191191
const fn = newTestLambda(stack);
192192

193-
test.throws(() => fn.addPermission('F1', { principal: new iam.ArnPrincipal('just:arn') }),
193+
test.throws(() => fn.addPermission('F1', { principal: new iam.OrganizationPrincipal('org') }),
194194
/Invalid principal type for Lambda permission statement/);
195195

196196
fn.addPermission('S1', { principal: new iam.ServicePrincipal('my-service') });
197197
fn.addPermission('S2', { principal: new iam.AccountPrincipal('account') });
198+
fn.addPermission('S3', { principal: new iam.ArnPrincipal('my:arn') });
198199

199200
test.done();
200201
},
@@ -1074,6 +1075,34 @@ export = {
10741075
test.done();
10751076
},
10761077

1078+
'grantInvoke with an arn principal'(test: Test) {
1079+
// GIVEN
1080+
const stack = new cdk.Stack();
1081+
const fn = new lambda.Function(stack, 'Function', {
1082+
code: lambda.Code.inline('xxx'),
1083+
handler: 'index.handler',
1084+
runtime: lambda.Runtime.NODEJS_8_10,
1085+
});
1086+
const account = new iam.ArnPrincipal('arn:aws:iam::123456789012:role/someRole');
1087+
1088+
// WHEN
1089+
fn.grantInvoke(account);
1090+
1091+
// THEN
1092+
expect(stack).to(haveResource('AWS::Lambda::Permission', {
1093+
Action: 'lambda:InvokeFunction',
1094+
FunctionName: {
1095+
'Fn::GetAtt': [
1096+
'Function76856677',
1097+
'Arn'
1098+
]
1099+
},
1100+
Principal: 'arn:aws:iam::123456789012:role/someRole'
1101+
}));
1102+
1103+
test.done();
1104+
},
1105+
10771106
'Can use metricErrors on a lambda Function'(test: Test) {
10781107
// GIVEN
10791108
const stack = new cdk.Stack();

0 commit comments

Comments
 (0)