0
votes

After going to tons of pages (including some SO ones) suggesting some advice (see list below), I am still not able to give my APIGateway access to execute a newly added Lambda function via the AWS CLI Command Line tool.

i.e. I'm trying to replicate this:

image1

I've created a new endpoint, with the following integration setup:

enter image description here

As soon as I try and test it (from within the API Gateway Console), I get this

<AccessDeniedException>
  <Message>Unable to determine service/operation name to be authorized</Message>
</AccessDeniedException>

I know that this is because, although I have added the lambda function to the method, the APIGateway policy has still not been updated (image 1), hence, there are permission issues.

If I re-add the function and allow the permissions automatically (via the AWS GUI) the testing and execution works fine.

My current CLI command I am trying to execute is this (through PS):

aws lambda add-permission --function-name xx-url --statement-id apigateway-perm-1 --action lambda:InvokeFunction --principal apigateway.amazonaws.com --s
ource-arn "arn:aws:execute-api:{REGION}:{AWS_ACCOUNT_ID}:{API_ID}/*/*"

I have tried multiple versions of the above arn address (including /*/* | /{STAGE}/{METHOD} | /{STAGE}/{METHOD}/{RESOURCE})

I've also tried deploying the API before and after these changes, with no effect?

PS - I've also read the suggestion of changing the integration type of the function to a POST (see this URL), but my requirement is to have a GET method, also - adding this GET method manually through the console works fine, hence, so should doing the same through the CLI tool.

URL list (if anyone else is look for some resources on this issue / topic):

UPDATE #1

I can also confirm that, after comparing the newly created get-policy against an existing, working one - they seem almost identical (just named differently):

AWS CLI command used: aws lambda get-policy --function-name {FunctionName}

Result of already working policy vs. the newly created one:

enter image description here

This makes me suspect it could be an additional step I'm missing.

EDIT (per request)

Test screenshot - this log goes on to display the AccessDeniedException error.

enter image description here

Log as text (made a little shorter for readability):

Execution log for request test-request Tue Mar 28 22:59:40 UTC 2017 : Starting execution for request: test-invoke-request Tue Mar 28 22:59:40 UTC 2017 : HTTP Method: GET, Resource Path: /api/v1/{path} Tue Mar 28 22:59:40 UTC 2017 : Method request path: {} Tue Mar 28 22:59:40 UTC 2017 : Method request query string: {fileName=x.doc} Tue Mar 28 22:59:40 UTC 2017 : Method request headers: {} Tue Mar 28 22:59:40 UTC 2017 : Method request body before transformations: Tue Mar 28 22:59:40 UTC 2017 : Endpoint request URI: https://lambda.ap-southeast-2.amazonaws.com/2015-03-31/functions/arn:aws:lambda:ap-southeast-2:{accountid}:function:xx-url/invocations Tue Mar 28 22:59:40 UTC 2017 : Endpoint request headers: {X-Amz-Date=20170328T240Z, x-amzn-apigateway-api-id={resouceId}, Accept=application/json, Access-Control-Allow-Origin=*, User-Agent=AmazonAPIGateway_f, Host=lambda.ap-southeast-2.amazonaws.com, X-Amz-Content-Sha256=93438097f7627fe6203432b05e2257de86b32f74f8306, X-Amzn-Trace-Id=Root=1-58daeadc-bdd8f80d35834164c70, x-amzn-lambda-integration-tag=test-request, Authorization=*********************************************d309e7, X-Amz-Source-Arn=arn:aws:execute-api:ap-southeast-2:{AccountId}:{resourceId}/null/GET/api/v1/{path}, X-Amz-Security-Token=FQoDYXdzEDcaDAzSjIbAbD9j0wBjWFBxP++dR0+CGiK3flLOatlCr2 [TRUNCATED] Tue Mar 28 22:59:40 UTC 2017 : Endpoint request body after transformations: {"resource":"/api/v1/{path}","path":"/api/v1/{path}","httpMethod":"GET","headers":null,"queryStringParameters":{"fileName":"x.doc"},"pathParameters":null,"stageVariables":null,"requestContext":{"accountId":"{AccountId}","resourceId":"{AccountId}:{resourceId}","stage":"test-invoke-stage","requestId":"test-invoke-request","identity":{"cognitoIdentityPoolId":null,"accountId""{resourceId}","cognitoIdentityId":null,"caller":"ABPPLGO4:","apiKey":"test-invoke-api-key","sourceIp":"test-invoke-source-ip","accessKey":"ASHYYQ","cognitoAuthenticationType":null,"cognitoAuthenticationProvider":null,"userArn":"arn:aws:sts::111:assumed-role/AWS-Admins/{name}","userAgent":"Apache-HttpClient/4.5.x (Java/1.8.0_112)","user":"AROZBPPLGO4:{name}"},"resourcePath":"/api/v1/{path}","httpMethod":"GET","apiId":"{resourceId}"},"body":null,"isBase64Encoded":false} Tue Mar 28 22:59:40 UTC 2017 : Endpoint response body before transformations:

<AccessDeniedException> <Message>Unable to determine service/operation name to be authorized</Message> </AccessDeniedException>

Tue Mar 28 22:59:40 UTC 2017 : Endpoint response headers: {x-amzn-RequestId=39398a3e-140a-11e7-92a3-3fdc0fbb61c2, Connection=keep-alive, Content-Length=130, Date=Tue, 28 Mar 2017 22:59:39 GMT} Tue Mar 28 22:59:40 UTC 2017 : Execution failed due to configuration error: Malformed Lambda proxy response Tue Mar 28 22:59:40 UTC 2017 : Method completed with status: 502

The fact that this ends up reading Malformed Lambda proxy response is not the issue - I have proven it by re-selecting the lambda function manually, letting the permissions be applied, retest immediately and all works fine, the Lambda is not even getting invoked.

2
What command/code are you executing that is generating the "Unable to determine service/operation name to be authorized" error? If you were failing to update the policy correctly the expected error should be a 500 http status code with something akin to "Internal service error". - Bob Kinney
@BobKinney I'm not running a command, at that stage I am simply testing the method from within the API Gateway Console (from the "Test" section). I would however, get the same result (502), if I deploy and test from Postman. - Hexie
This is very unusual and not at all what I would expect. - Bob Kinney
I just tried to reproduce this and got the expected 500 error. Can you take a screen shot of the test invoke console when you get this error? - Bob Kinney
@BobKinney screenshot added. You should be able to reproduce this by adding a new method (GET), which uses an AWS_PROXY lambda through the AWS CLI tool. - Hexie

2 Answers

2
votes

To summarize the debugging from the chat:

The GET method was created with the incorrect http method for Lambda, GET. This caused Lambda to not be able to interpret the request from API Gateway, generating the XML error response. The XML error response is not a valid JSON proxy response, and generated a 502 as a result.

The console is adding the necessary permissions and resetting the http method to POST, hence why it is successful after using the console.

0
votes

The step you are trying to workout is solved by the command:

aws apigateway put-integration

There's a very specific thing in the options of that command you have to be very aware of. A complete "put-integration" statement comes like this:

aws apigateway put-integration
--region us-west-2
--rest-api-id y0UrApI1D
--resource-id r35ourc3ID
--http-method GET
--type AWS
--integration-http-method POST
--uri arn:aws:apigateway:us-west-2:lambda:path/2015-03-31/functions/arn:aws:lambda:us-west-2:111111111111:function:functionname/invocations

In the --uri option, you must be aware of:

  • us-west-2 is an example the region, be sure you put the correct region where your lamnda function resides
  • Be sure you do not change this next part, it must be exactly like stated, otherwise the permission will not be granted "lambda:path/2015-03-31/functions"
  • Change the value 111111111111 for your AWS account number
  • Change "functionname" for the exact name of your registered lambda function

Will work guaranteed