Reputation: 3137
I'm using the serverless framework to upload an AWS Lambda function to be used as a data source in AppSync. The serverless.yml
that I have is very basic:
service: mongoose-lambda-srvrls
provider:
name: aws
runtime: nodejs6.10
region: us-west-2
functions:
mongoose:
handler: index.handler
When I run an AppSync GraphQL query I get the error:
{
"data": {
"getPost": null
},
"errors": [
{
"path": [
"getPost"
],
"data": null,
"errorType": "Lambda:AWSLambdaException",
"errorInfo": null,
"locations": [
{
"line": 43,
"column": 2
}
],
"message": "User: arn:aws:sts::433333333335:assumed-role/appsync-datasource-lam-kkzuep-mongoose-lambda-srvr/APPSYNC_ASSUME_ROLE is not authorized to perform: lambda:InvokeFunction on resource: arn:aws:lambda:us-west-2:43333333333335:function:mongoose-lambda-srvrls-dev-mongoose (Service: AWSLambda; Status Code: 403; Error Code: AccessDeniedException; Request ID: 9fa82eb9-3a64-11e8-88a1-09c4e639fc45)"
}
]
}
I'm pretty sure that I need to flesh out my YML so that this lambda stack will play nice with AppSync but I'm not quite sure what to do.
A little more info. When looking at the resources in Lambda's CloudFormation, I see:
IamRoleLambdaExecution mongoose-lambda-srvrls-dev-us-west-2-lambdaRole AWS::IAM::Role
MongooseLambdaFunction mongoose-lambda-srvrls-dev-mongoose AWS::Lambda::Function
MongooseLambdaVersionwCQ1... arn:aws:lambda:us-west-2:4542242445:function:mongoose-lambda-srvrls-dev-mongoose:4 AWS::Lambda::Version
MongooseLogGroup /aws/lambda/mongoose-lambda-srvrls-dev-mongoose AWS::Logs::LogGroup
ServerlessDeploymentBucket mongoose-lambda-srvrls-d-serverlessdeploymentbuck-qwp8sdfgjr AWS::S3::Bucket
Whereas in the Lambda that I made using the AppSync docs (AWS CLI) has the following CloudFormation resources:
AppSyncLambdaInvokePolicy Fulls-AppS-15SHASDFSADZ03N AWS::IAM::Policy
AppSyncServiceRole Fullstack-Lamba-AppSyncServiceRole-DK8QHASDFE5R AWS::IAM::Role
LambdaExecutionRole Fullstack-Lamba-LambdaExecutionRole-OJHASDF3AHG1 AWS::IAM::Role
LambdaFunction fullstack-lambda AWS::Lambda::Function
Upvotes: 2
Views: 1941
Reputation: 30997
I think they made a mistake in the https://docs.aws.amazon.com/appsync/latest/devguide/tutorial-lambda-resolvers.html#configure-data-source-for-aws-lambda documentation.
The allowed action should be lambda:InvokeFunction
and NOT lambda:Invoke
This is working:
{
"Version" : "2012-10-17",
"Statement" : [{
"Effect" : "Allow",
"Action" : "lambda:InvokeFunction",
"Resource" : "arn:aws:lambda:REGION:ACCOUNTNUMBER:function/LAMBDA_FUNCTION"
}]
}
Upvotes: 2
Reputation: 912
It looks like the role you gave AppSync to run the lambda function does not have permission to invoke that particular lambda.
You will need to create or modify a role so it has the following permissions.
The IAM role should have a policy which enables anybody who assumes it to run/invoke your lambda function:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"lambda:Invoke"
],
"Resource": "arn:aws:lambda:REGION:ACCOUNTNUMBER:function/LAMBDA_FUNCTION"
}
]
}
The role should also have a trust policy. This trust policy will allow AppSync to assume the role on your behalf. This is how AppSync invokes your lambda whenever a graphQL request comes in.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "appsync.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
Once you have an IAM role with necessary permissions, you will need to make sure it is associated with the lambda data source in AppSync. You can select the role in the Data Sources
section of the AppSync console or use the AppSync CLI to update the lambda data source and make it use your role.
For more information about creating a lambda function which plays nice with AppSync, here is the documentation: https://docs.aws.amazon.com/appsync/latest/devguide/tutorial-lambda-resolvers.html#configure-data-source-for-aws-lambda
Upvotes: 4