3

I created a CustomResource to call a lambda function when the CloudFormation stack is created. It fails with the following error:

 Received response status [FAILED] from custom resource. Message returned: User: arn:aws:sts::<account>:assumed-role/stack-role is not authorized to perform: lambda:InvokeFunction on resource: arn:aws:lambda:us-east-1:<account>:function:<lambda> because no identity-based policy allows the lambda:InvokeFunction action

This is the code in the CDK:

import * as cr from '@aws-cdk/custom-resources';

const callLambda = new cr.AwsCustomResource(this, 'MyCustomResource', {
        onCreate: {
            service: 'Lambda',
            action: 'invoke',
            region: 'us-east-1',
            physicalResourceId: cr.PhysicalResourceId.of(Date.now.toString()),
            parameters: {
                FunctionName: `my-function`,
                Payload: '{}'
            }, 
        },
        policy: cr.AwsCustomResourcePolicy.fromSdkCalls({
            resources: cr.AwsCustomResourcePolicy.ANY_RESOURCE,
        })
    });

How can I grant permissions to the stack's assumed role so that it can perform lambda:InvokeFunction?

3 Answers 3

2

I solved the issue by creating a role that assumes the lambda service principal, and adding a policy statement allowing the lambda:InvokeFunction.

import * as cr from '@aws-cdk/custom-resources';
import * as iam from "@aws-cdk/aws-iam";

let role = new iam.Role(this, `my-role`, {
        assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'),
    });
    role.addToPolicy(new iam.PolicyStatement({
        effect: iam.Effect.ALLOW,
        actions: ['lambda:InvokeFunction'],
        resources: ['*']
    }));
    
const callLambda = new cr.AwsCustomResource(this, 'MyCustomResource', {
    onCreate: {
        service: 'Lambda',
        action: 'invoke',
        region: 'us-east-1',
        physicalResourceId: cr.PhysicalResourceId.of(Date.now.toString()),
        parameters: {
            FunctionName: `my-function`,
            Payload: '{}'
        }, 
    },
    policy: cr.AwsCustomResourcePolicy.fromSdkCalls({
        resources: cr.AwsCustomResourcePolicy.ANY_RESOURCE,
    }),
    role: role as any
});
Sign up to request clarification or add additional context in comments.

1 Comment

Worked for me. No need to cast role as any.
1

I find fromStatements works...must be some issues with fromSdkCalls

new cr.AwsCustomResource(this, 'MyCustomResource', {
        onCreate: {
            service: 'Lambda',
            action: 'invoke',
            region: 'us-east-1',
            physicalResourceId: cr.PhysicalResourceId.of(Date.now.toString()),
            parameters: {
                FunctionName: `my-function`,
                Payload: '{}'
            }, 
        },
        policy: cr.AwsCustomResourcePolicy.fromStatements([
          new PolicyStatement({
            effect: Effect.ALLOW,
            actions: ["lambda:InvokeFunction"],
            resources: ["*"],
          }),
        ])
    });

Comments

0

Add a ResourcePolicy to your construct.

// infer the required permissions; fine-grained controls also available
policy: AwsCustomResourcePolicy.fromSdkCalls({resources: AwsCustomResourcePolicy.ANY_RESOURCE})

1 Comment

Thanks for the comment. I already had that statement in the code, I accidentally omitted it when consolidating and sanitizing. The error occurs with the policy defined.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.