I am using CDK to create a lambda, a new version of the lambda, and point the "live" alias to the newest version of the lambda like so
const func = new lambda.Function(this, 'lambdaName', {
// Other properties
description: `Generated on: ${new Date().toISOString()}`,
});
const version = func.addVersion(new Date().toISOString());
const alias = new lambda.Alias(this, 'lambdaName-alias', {
aliasName: 'live',
version: version,
});
Now, I want to add resource based permission to the alias live
and not just the main lambda function.
I assumed that this would work but it doesn't create any resource based permissions at all:
alias.addPermission('CrossAccountAccessId', {
action: 'lambda:InvokeFunction',
principal: new ArnPrincipal('ACOUNT_NUMBER_XXX')
});
How to add permissions to an alias using AWS CDK?
I referred to this for resource based alias permission-ing: https://docs.aws.amazon.com/lambda/latest/dg/configuration-aliases.html#versioning-permissions-alias
For the CDK docs, I read this: https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_lambda.Alias.html#addwbrpermissionid-permission
I think it might be related to a bug in AWS CDK where adding resource based policy on a lambda version fails as mentioned here: AWS CDK: Resource Policies are not being granted for Lambda Version but I'm not sure if aliases also have the same problem as that of versions.
CodePudding user response:
ArnPrincipal()
requires an ARN of the principal, and the account number is not an ARN. An ARN looks like arn:aws:iam::123456789012:root
If you want an account principal, use AccountPrincipal()
:
new AccountPrincipal('ACOUNT_NUMBER_XXX')
CodePudding user response:
The following generates the expected cross-account lambda permission for the alias. I use CDK v2, although the v1 will work, too.
The addVersion
method is deprecated and is removed completely in v2. "Instead, use this.currentVersion
to obtain a reference to a version resource that gets automatically recreated when the function configuration (or code) changes".
const alias = func.currentVersion.addAlias('live');
// `iam.ArnPrincipal` will work (cdk does not validate the format), but, `iam.AccountPrincipal` is semantically correct in your case.
const principal = new iam.AccountPrincipal('123456789012');
These 3 permission methods are equivalent:
this.alias.grantInvoke(principal);
this.alias.addPermission('CrossAccountPermission', { principal });
this.alias.addPermission('CrossAccountPermission', {
action: 'lambda:InvokeFunction', // this is the default value
principal,
});
The permission is created as expected. This test passes with any of the above 3 methods:
// MyStack.test.ts
const cfnAlias = stack.alias.node.defaultChild as lambda.CfnAlias;
template.hasResourceProperties('AWS::Lambda::Permission', {
Action: 'lambda:InvokeFunction',
FunctionName: { Ref: stack.resolve(cfnAlias.logicalId) },
Principal: '123456789012',
});