how does aws lambda invoke work - aws-lambda

I am fairly new to lambda and trying to wrap my head around it. I created a basic hello world function and invoked it through
aws lambda invoke
My question is
Dont I have to create an API gateway and expose the lambda function through the API gateway for it work.
How does aws lambda invoke if I have not created a gateway and exposed the function?

You do not have to necessarily create API gateway for invoking lambda function. Every lambda function is already available to be accessed via Amazon's Web Service using API:
POST /2015-03-31/functions/FunctionName/invocations?Qualifier=Qualifier HTTP/1.1
See http://docs.aws.amazon.com/lambda/latest/dg/API_Invoke.html for more details.
However, the above API expects that the request payload is signed using aws signature version 4 . The CLI call aws lambda invoke automatically takes care of that piece once you have configured valid access and secret keys.
The API Gateway in front of lambda allows you to add:
Custom resource names
Custom authentication schemes (even no authentication if desired)
Custom way of sending payload
and more...
In summary, API Gateway gives you more control over the API resource and can even abstract the user from internals of AWS API.

Related

APIGateway throws 403 back when requesting API from one lambda to another on a different APIGateway endpoint

I'm creating an Axios call to an API hosted on APIGateway with no Authorizer etc. I'm able to access the lambda via a direct postman request and also on the service lambda when it's ran in offline mode, such as:
https://localhost:3000/my/api
However when i run it on the dev stage:
12345.execute-api.eu-west-1.amazonaws.com/my/api
I'm getting a a 403: Forbidden error thrown back.
I've seen comments from other posts where they needed to append the staging environment at the end of the request but this isn't the case in this instance as it's just creating a default endpoint and all other lambdas within this service can be hit when ran on dev, it's just this one that makes a call to another APIGateway API.
The calling API is behind an authorizer with a wildcard policy so should allow all traffic and I'd like to reiterate, it works on both localhost and a direct call to the invoked api.
I'm wondering if it's something to do with the policies attached to it but I've set them all to be wildcarded as well so it should allow everything.
Any ideas would be really helpful, I've been wracking my brains over this all day.
Edit: The authorizer has no policy denying access to the API, same as the resource policy.
There are two common reasons why an API Gateway REST API with a Lambda authorizer returns a 403 error:
The Lambda authorizer function returns an AWS Identity and Access Management (IAM) policy document that explicitly denies access to the caller.
https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-lambda-authorizer-output.html
The second reason will be, The API has an attached resource policy that explicitly denies access to the caller.
https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-resource-policies.html
If both are in place, please update the question with those details.

How should I diagnose an HTTP request 500 that appears to be related to Authorizers in AWS API Gateway?

I am brand new to AWS API Gateway/AWS Lambda/AWS Amplify. I have a React Native application that I am trying to use AWS Amplify to make an API call and issue a PUT request, which would then cause the API Gateway to invoke my AWS Lambda function. When I create the AWS Amplify API endpoint, I don't see a command line option to define a PUT method. The default is "Any", which works, but I would like to specify a PUT method specifically. When I add in a PUT method manually on the API Gateway website and then call it from my React Native front end, I get...
Error: Request failed with status code 500
Looking at the API Gateway responses, this is due to either an "Authorizer Configuration Error" or an "Authorizer Failure", so I am assuming the problem is not with my front end code but with the configuration of "authorizers" on the API Gateway. What are authorizers? How do they relate to making an API call? And what steps can I take to troubleshoot what the problem might be?
You can use a lambda, a Cognito User Pool or an IaM role as an Authorizer. The short version is that your API endpoints can either be open and public or have an Authorizer, if they have an authorizer then they have to be setup correctly. It is set through the API Gateway config for an endpoint in the Method Request section.
AWS Lambda authorizer info:
https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-use-lambda-authorizer.html
AWS Cognito Info:
https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-integrate-with-cognito.html

How do I get access to the request and path variables from AWS API Gateway URI in an AWS Lambda function

I am replatforming an existing application to work with AWS API Gateway and AWS Lambda. The current application exposes it functionality as REST API which is implemented as a Spring Boot application and Spring REST Controller annotations.
While I am able to get the request body JSON from the API Gateway into the Lambda function, in certain cases I would need variables from the Request object as well as path variables accessible in the Lambda function. I did take a look at the Lambda Context object but it did not have anything that could help me in this regard.
Example API URLs: I use a path variable similar to the id variable in
the following API call GET http://www.example.com/users/{id}/alerts.
{id} will be the path variable here. An example of how we use a request variable is in the following URL where the alert id is passed as a query string parameter - GET
http://www.example.com/users/{id}/alerts?id=1234
Is there any recommended way to get this done? I do not want to use the RequestHandler interface as I am aiming to tie each API to a separate Lambda function.
If you are using AWS integration type:
Use a mapping template to send $input.params('id') property in the request body to your Lambda function.
If you are using AWS_PROXY integration type:
You can access the path parameters via the "pathParameters" property of the incoming event. For more details, please read the docs.
I suggest you use the Lambda Proxy integration type, it makes all the information you need available with the least hassle.
So, the properties you need to read will be available as follows:
your /users/... path: event.path
your id in query string: event.queryStringParameters.id
you'll need the http method as well: event.httpMethod
your path parameters like the id one: event.pathParameters
Let me know if you need any more information.

Scripting permissions to execute lambda from aws api gateway

In the aws UI, I get this message when I want to add a lambda function to aws api gateway integration request. How can I script this using boto3?
Been struggling with doing it using lambda: add_permission but missing something still.
This is possible using lambda add_permission API or CLI.
The policy should be structured like this:
...
"AWS:SourceArn":"arn:aws:execute-api:[REGION]:[ACCOUNT_ID]:[API_ID]/*/[HTTP_VERB]/[RESOURCE_PATH]"}},
"Action":"lambda:InvokeFunction",
"Resource":"arn:aws:lambda:[REGION]:[ACCOUNT_ID]:function:[FUNCTION_NAME]",
"Effect":"Allow",
"Principal":{"Service":"apigateway.amazonaws.com"}
...

AWS API Gateway: How to pass IAM identity to Lambda function?

I've successfully configured IAM-authenticated access to my Lambda function with AWS API Gateway front-end, but unable to find how to pass IAM user identity to my Lambda function.
I need exactly IAM user identity and can not run Lambda function under calling IAM-user credentials.
All I need - is to get calling IAM-user identity in my Lambda function.
Is there option for that?
Support for accessing identity and other information from the Amazon API Gateway request context hadn't been available when you posted the question, but recently been added, see Announcement: Context Variables:
You can now access context variables from within mapping templates to retrieve contextual information about the API call. You can access data such as stage, resource path, and HTTP method, as well as information about the identity of the caller. This information can then be passed along to your backend integration using the $context variable. [emphasis mine]
The referenced documentation on Accessing the $context Variable features a $context Variable Reference and there are various $context.identity.* parameters that should address your use case.
Cognito Identity
As outlined in Soenke's answer to the OPs similar question in the Amazon API Gateway forum, there is an as of yet undocumented integration parameter that results in the Cognito identifier being included in this $context.identity.* context variables:
in order to have the Cognito (not IAM!) IdentityId and IdentityPoolId
available in Lambda, you have to enable "Invoke with caller
credentials" on the API Gateway "Integration Request" page of the API
GW Resource. This results in a new context struct "identity"
(containing "cognitoIdentityId" and "cognitoIdentityPoolId" being
passed to the Lambda function).
You can use Cognito with a "public" pool id, then attach role to the Cognito pool id, the role being accessing your Lambda, I think it is called InvokeLambdaRole or something
AWS.config.credentials = new AWS.CognitoIdentityCredentials({
IdentityPoolId: 'REGION:YOUR_POOL_ID',
});
Use AWS STS to get temporary credentials with limited privileges. After that you can use API Gateway with AWS_IAM authentication, then end point will invoke the Lambda methods for you. Or you can invoke lambda directly with the credentials you got, but then again you have to attache the right roles for the identity pool you created.
NB: Put strictly minimum roles on your pole, that is a publicly available id, every body can use it to get a temporary or a fixed (to track users accross devices) user_/app_ id.

Resources