AWS API Gateway Invoke Lambda Function Permission
Learn how to provide API Gateway permission to invoke Lambda function(s).
Issue
API Gateway endpoint can’t invoke Lambda with 5XX permission error.
When testing on API Gateway console, you see this error message:
Execution log for request d237e276-656e-11e9-aaff-51e803313fb3
... truncated
Date : Sending request to https://lambda.function.url
Date : Execution failed due to configuration error:
Invalid permissions on Lambda function
Date : Method completed with status: 500
Expected Behavior
Published API on API Gateway is able to invoke AWS Lambda functions successfully.
Reason
Why didn’t it work? The reason is we have to explicitly specify the ARN of an IAM role for API Gateway to assume when invoking a Lambda function. If none is specified, resource-based permissions are needed.
Quoting AWS x-amazon-apigateway-integration Object document:
For AWS IAM role-based credentials, specify the ARN of an appropriate IAM role. If unspecified, credentials will default to resource-based permissions that must be added manually to allow the API to access the resource. For more information, see Granting Permissions Using a Resource Policy.
Solutions
1. AWS Console
You can add a resource based policy for your API Gateway to invoke your Lambda function on AWS API Gateway console.
These are the steps to add a resource based policy. On API Gateway console, select your API then resources on left panel. Your API configuration menu will be displayed on the right like the image below.
Afterwards, choose the method you want to add a policy to. Select Integration Request item and the following menu will appear. Notice that there is a Lambda Function item in the middle, click the pencil icon on its right end to edit.
After the pencil icon is clicked, it will become an editable field. Once you click the check mark to the right of the field, there will be a popup with title ‘Add Permission to Lambda Function’ saying that ‘You are about to give API Gateway permission to invoke your Lambda function: Function-ARN’.
Once you click OK on the popup, a resource based policy will be added to Lambda function.
Issues
-
Note that a resource based policy will be added each time you do the above steps even though it is the same policy.
-
There is this
The final policy size is bigger than the limit(20480)
limit that might happen when there are too many(same or different) policies added to a Lambda Function. Check out this article on how to fix this limit error. -
Adding permission for API Gateway to invoke Lambda functions manually by clicking doesn’t scale well when we have more API endpoints. To minimize operational overhead, I recommend the following 2 methods.
2. Resource-based Policy
On the other hand, you can declare a permission entity in your yaml file. By adding a resource-based policy in your yaml file, a resource-based policy will be attached to your lambda function(s). The following is the AWS::Lambda::Permission
entity that you need to add to your yaml file. Read more about Lambda Permission on AWS document.
Note that if you use resource-based policy, you will have to attach at least one per lambda function. There is still a chance that your policy size reaches 20KB limit.
YourLambdaFunctionName:
Type: AWS::Serverless::Function
Properties:
...
YourAPIName:
Type: AWS::Serverless::Api
Properties:
...
ApiGatewayInvokeLambdaPermission:
Type: "AWS::Lambda::Permission"
Properties:
Action: lambda:InvokeFunction
FunctionName: !GetAtt
- YourLambdaFunctionName
- Arn
Principal: apigateway.amazonaws.com
SourceArn: !Join [
"", [
"arn:aws:execute-api:",
{"Ref": "AWS::Region"}, ":",
{"Ref": "AWS::AccountId"}, ":",
!Ref YourAPIName, "/*/*/*"
]
]
You can use AWS Lambda CLI get-policy to check if the policy is attached successfully.
3. IAM Role
Another way is to create an IAM role that allows lambda:InvokeFunction
action and trust API Gateway service apigateway.amazonaws.com
.
AWS IAM Console
-
Go to AWS IAM console and click
Create Role
. Afterwards, choose AWS service and Lambda.
-
Attach permissions policies that you need. Filter for AWS managed policy: AWSLambdaRole that allows
lambda:InvokeFunction
for all resources or specified Lambda functions. You can also attach other policies that you need such as CloudWatchLogsFullAccess in my case.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"lambda:InvokeFunction"
],
"Resource": [
"*"
]
}
]
}
- Tag your AWS IAM role for management purpose and click next to review.
- Give your role a name such as ApiGatewayInvokeLambdaRole and review the role that you are about to create.
- Edit Trust Relationships so that this role trusts apigateway.amazonaws.com.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
},
{
"Effect": "Allow",
"Principal": {
"Service": "apigateway.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
These are all the steps needed to create a role on AWS console.
AWS IAM CLI
You can use AWS IAM create-role and attach-role-policy command.
- Create role using the following trust relationship object.
aws iam create-role
--role-name ApiGatewayInvokeLambdaRole
--assume-role-policy-document ./trust-api-gateway.json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
},
{
"Effect": "Allow",
"Principal": {
"Service": "apigateway.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
- Then, attach AWSLambdaRole role policy.
aws iam attach-role-policy
--policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaRole
--role-name ApiGatewayInvokeLambdaRole
If you want to use CloudWatch for your API Gateway log, you can attach CloudWatchLogsFullAccess role policy too.
aws iam attach-role-policy
--policy-arn arn:aws:iam::aws:policy/CloudWatchLogsFullAccess
--role-name ApiGatewayInvokeLambdaRole
Assign Role in YAML / JSON
After creating a role using AWS console or CLI, assign the ARN of your role to the credential item in the x-amazon-apigateway-integration definition of your API yaml file. The ARN of your role looks like this: "arn:aws:iam::ACC_NUM:role/IAM_ROLE_NAME"
.
MyApi:
Type: AWS::Serverless::Api
Properties:
StageName: Prod
DefinitionBody:
swagger: '2.0'
basePath: '/Prod'
schemes:
- 'https'
paths:
/myMethod:
post:
produces:
- "application/json"
responses: {}
x-amazon-apigateway-integration:
uri: # api-gateway-arn using Fn::Join
responses: {}
httpMethod: "POST"
credentials: "arn:aws:iam::ACC_NUM:role/ApiGatewayInvokeLambdaRole"
type: "aws_proxy"
Summary
I suggest using a resource-based policy or an IAM role to minimize operational overhead.
Support Jun
Thank you for reading! Support Jun
If you are preparing for Software Engineer interviews, I suggest Elements of Programming Interviews in Java for algorithm practice. Good luck!
You can also support me by following me on Medium or Twitter.
Feel free to contact me if you have any questions.
Comments