amazon-web-servicesaws-lambdaamazon-iamaws-cdkaws-roles

adding `Lambda:InvokeLambda` action permission through cdk for the lambda to invoke itself does not work


I'm trying to use an NPM package called "lambda-warmer". it requires a permission called lambda:InvokeLambda. I tried to add this permission through cdk but I failed to do so. here is the code I tried to do this with: here's a function to add a rule:

function addActionPermissionToLambda(
    stack: Stack,
    lambdaFunction: IFunction,
    inlinePolicyName: ResourcesNames,
    resources: string[],
    actions: string[],
): void {
    const addedPolicy = new PolicyStatement({ actions, resources });

    // since adding a policy overrides basic actions/permissions. we need to add those. also called "AWSLambdaBasicExecutionRole".
    const logActions = new PolicyStatement(
        {
        actions: [
            "logs:CreateLogGroup",
            "logs:PutLogEvents",
            "logs:CreateLogStream"
        ],
        resources: ["*"]
        });

    lambdaFunction.role.attachInlinePolicy(new Policy(stack, buildConstructorId(stack, inlinePolicyName), {
        statements: [addedPolicy, logActions],
    }));
}

In order I use this function:

function addInvokeLambdaPermissionToLambda(
    stack: Stack,
    lambdaFunction: IFunction,
    name: ResourcesNames
) {
    addActionPermissionToLambda(stack, lambdaFunction, name, ["*"], ["Lambda:InvokeLambda"]);
}

in the following code:

...const { lambdaFunction, version } = createLambda(
    stack,
    ResourcesNames.ContentManager,
    ResourcesNames.ContentManagerRole,
    "lambdas/contentManager"
);

addInvokeLambdaPermissionToLambda(stack, lambdaFunction, ResourcesNames.ContentManagerInvokeLambda);

I actually see on my lambda->permissions tab that it has the action Lambda:InvokeLambda with all resources as the resources of it.

when it is getting called, I get this error:

2023-09-13T14:26:03.839Z    5693bfff-5875-450c-a46f-fd2b079cb0ae    ERROR   Invoke Error    
{
    "errorType": "AccessDeniedException",
    "errorMessage": "User: arn:aws:sts::625618361194:assumed-role/GsharimBackendStack-featu-GsharimBackendStackfeatu-1E62H8T2TSCXO/9604bdfbe04cbac6fb2dc6c98c9fdfde is not authorized to perform: lambda:InvokeFunction on resource: arn:aws:lambda:eu-west-1:625618361194:function:9604bdfbe04cbac6fb2dc6c98c9fdfde because no identity-based policy allows the lambda:InvokeFunction action",
    "name": "AccessDeniedException",
    "$fault": "client",
    "$metadata": {
        "httpStatusCode": 403,
        "requestId": "b08af667-4a78-44e2-b545-4bf8e23c31d4",
        "attempts": 1,
        "totalRetryDelay": 0
    },

why does this happen? it looks like it has the right action permission, but it still fails saying it does not.


Solution

  • As you can see from the error message, the correct action is lambda:InvokeFunction, not Lambda:InvokeLambda.

    Your approach is pretty brittle, though - consider using Function.grantInvoke instead, calling it on the functions you need to grant access to.