Event object is empty in api gateway call to lambda - amazon-web-services

Now I have my lambda just echoing the event object:
def lambda_handler(event, context):
pprint(event)
I have been using the event object in the code to get the path like this event['path']
When I run sam local to start up the api gateway locally like this, when I hit the locally running api gateway the lambda dumps an event object like i would expect and I can read the path from it:
sam local start-api
But When I deploy the SAM template to aws and test it in the api gateway console "event" is empty.
Why is event empty on aws and not locally? Do I need to do something to pass the full event? This is my template:
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
sam-app
Sample SAM Template for sam-app
# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
Globals:
Function:
Timeout: 3
Resources:
lambdafunction:
Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
CodeUri: hello_world/build/
Handler: app.lambda_handler
Runtime: python2.7
Environment: # More info about Env Vars: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#environment-object
Variables:
PARAM1: VALUE
Events:
# More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
testMethod:
Type: Api
Properties:
RestApiId: !Ref ApiGatewayApi
Path: /testMethod
Method: GET
ApiGatewayApi:
Type: AWS::Serverless::Api
Properties:
StageName: Prod
DefinitionBody:
swagger: "2.0"
info:
version: "2018-09-12T06:21:35Z"
title: mytest
schemes:
- "https"
paths:
/testMethod:
x-amazon-apigateway-any-method:
produces:
- "application/json"
responses:
'200':
description: "200 response"
schema:
$ref: "#/definitions/Empty"
security:
- sigv4: []
x-amazon-apigateway-integration:
uri:
Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:${lambdafunction}/invocations
responses:
default:
statusCode: "200"
passthroughBehavior: "when_no_match"
httpMethod: "POST"
contentHandling: "CONVERT_TO_TEXT"
type: "aws"
securityDefinitions:
sigv4:
type: "apiKey"
name: "Authorization"
in: "header"
x-amazon-apigateway-authtype: "awsSigv4"
definitions:
Empty:
type: "object"
title: "Empty Schema"

Related

Override default auth in SAM templates and Open API

I have made a SAM template that deploys a mix of public and authenticated endpoints. The default auth is oauth. For public endpoints, I use overrides to make it auth NONE. This worked fine.
After I have added the OpenAPI for documentation. The auth override for public endpoints does not work anymore. What else should I do?
#sam-template.yaml
Resources:
RestApi:
Type: AWS::Serverless::Api
Properties:
Name: !Ref ApiStackName
StageName: Prod
Auth:
AddDefaultAuthorizerToCorsPreflight: false
DefaultAuthorizer: TokenAuthorizer
Authorizers:
TokenAuthorizer:
FunctionArn: !GetAtt Authorizer.Arn
Identity:
Header: Authorization
ValidationExpression: Bearer.*
ReauthorizeEvery: 0
DefinitionBody: // this is what I added.
Fn::Transform:
Name: AWS::Include
Parameters:
Location:
Fn::Join:
- ''
- - 's3://'
- Ref: S3BucketName
- '/swagger.yaml'
GetFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: ./functions
FunctionName: !Sub ${Environment}-api-get
Description: get
Handler: ./src/get.handler
Role: !Sub arn:aws:iam::${AWS::AccountId}:role/pam-${Environment}-${AWS::Region}-get-lambda-role
Events:
Api:
Type: Api
Properties:
RestApiId: !Ref RestApi
Path: /p
Method: GET
Auth:
Authorizer: NONE // this overrides the default auth
#swagger.yaml
/p:
get:
summary: Get
description: Get
responses:
200:
description: "200 response"
content:
application/json:
schema:
type: array
items:
$ref: "#/components/schemas/P"
500:
description: "500 response"
content: {}
x-amazon-apigateway-auth:
type: "NONE"
x-amazon-apigateway-integration:
uri:
Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${GetFunction.Arn}/invocations
responses:
default:
statusCode: "200"
passthroughBehavior: "when_no_match"
httpMethod: "POST"
contentHandling: "CONVERT_TO_TEXT"
type: "aws_proxy"
security: {}
OR
security:
- {}
Didn't work for me.
The below mentioned code snippet worked.
security:
- NONE: []
you are looking for security in OpenAPI. This sets Authorization on ApiGateway endpoint to NONE.
/p:
get:
summary: Get
description: Get
responses:
...
security:
- {}
x-amazon-apigateway-integration:
...

Getting access denied due to origin blocked by CORS in AWS Api-Gateway

I have an AWS SAM template, which creates lambda function and post method in API Gateway. By default, it uses Lambda Proxy integration and it is working fine when I am testing through the PostMan tool but when I am using the API gateway URL with my sandbox app, it is displaying the following error.
Access to XMLHttpRequest at 'https://abcdef.execute-api.eu-west-2.amazonaws.com/dev/my-api' from origin 'https://abcd.csb.app' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.
but when I am creating API gateway post method manually and trying then it is working fine.
Lambda function also returning following header in the response.
response = {
'statusCode': status_code,
'headers': {
'Access-Control-Allow-Headers': 'Content-Type',
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'OPTIONS,POST'
},
'body': json.dumps(response_data)
}
Following is AWS SAM template.
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
AWS SAM Template
# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
Globals:
Function:
Timeout: 10
Parameters:
DeploymentEnv:
Type: String
Resources:
ApiGatewayApi:
DependsOn: LambdaFunction
Type: AWS::Serverless::Api
Properties:
StageName: !Ref DeploymentEnv
EndpointConfiguration:
Type: REGIONAL
Cors:
AllowMethods: "'POST,OPTIONS'"
AllowHeaders: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key'"
AllowOrigin: "'*'"
MaxAge: "'600'"
AllowCredentials: false
Auth:
DefaultAuthorizer: NONE
ApiKeyRequired: true # sets for all methods
LambdaFunction:
Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
FunctionName: !Join [ "", [ !Ref DeploymentEnv, "-my-lambda"]]
CodeUri: my_api/
Handler: app.lambda_handler
Runtime: python3.9
Architectures:
- x86_64
Events:
EventTriggerlambda:
Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
Properties:
RestApiId: !Ref ApiGatewayApi
Path: /my-api
Method: POST
Auth:
ApiKeyRequired: true
Role: Role_URN
Environment:
Variables:
URI: Test
USER_NAME: Test
PASSWORD: Test
ApiKey:
Type: AWS::ApiGateway::ApiKey
DependsOn: ApiGatewayApiStage
Properties:
Name: !Join ["", [{"Ref": "AWS::StackName"}, "-apikey"]]
Enabled: true
StageKeys:
- RestApiId: !Ref ApiGatewayApi
StageName: !Ref DeploymentEnv
UsagePlan:
DependsOn:
- ApiGatewayApiStage
Type: AWS::ApiGateway::UsagePlan
Properties:
ApiStages:
- ApiId: !Ref ApiGatewayApi
Stage: !Ref DeploymentEnv
Throttle:
BurstLimit: 500
RateLimit: 100
UsagePlanName: MY-UsagePlan
UsagePlanKey:
Type: AWS::ApiGateway::UsagePlanKey
Properties:
KeyId: !Ref ApiKey
KeyType: API_KEY
UsagePlanId: !Ref UsagePlan
Outputs:
LambdaFunction:
Description: "Lambda Function ARN"
Value: !GetAtt LambdaFunction.Arn
Please help, Thanks :)
Configuration is not proper for API creation in API-Gateway in the AWS SAM template. because SAM deployment uses lambda proxy integration by default that's why in method response, there are few values required which can not be set automatically using the above configuration. So I use open API specification where I defined Rest API configuration and it is working fine without any manual intervention after deployment.
Following configuration is fine.
ApiGatewayApi:
DependsOn: LambdaFunction
Type: AWS::Serverless::Api
Properties:
StageName: !Ref DeploymentEnv
DefinitionBody:
'Fn::Transform':
Name: 'AWS::Include'
Parameters:
Location: !Join [ '', [ 's3://mybucket', '/openapi-spec.yaml' ] ]
EndpointConfiguration:
Type: REGIONAL
OpenAPi Configuration
openapi: "3.0.1"
info:
title: "test-api"
description: "Created by AWS Lambda"
version: "2022-01-07T18:00:40Z"
paths:
/test-api:
post:
responses:
"200":
description: "200 response"
headers:
Access-Control-Allow-Origin:
schema:
type: "string"
content:
application/json:
schema:
$ref: "#/components/schemas/Empty"
x-amazon-apigateway-integration:
httpMethod: "POST"
uri:
Fn::Sub: "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${LambdaFunction.Arn}/invocations"
responses:
default:
statusCode: "200"
responseParameters:
method.response.header.Access-Control-Allow-Origin: "'*'"
passthroughBehavior: "when_no_match"
contentHandling: "CONVERT_TO_TEXT"
type: "aws_proxy"
options:
responses:
"200":
description: "200 response"
headers:
Access-Control-Allow-Origin:
schema:
type: "string"
Access-Control-Allow-Methods:
schema:
type: "string"
Access-Control-Allow-Headers:
schema:
type: "string"
content:
application/json:
schema:
$ref: "#/components/schemas/Empty"
x-amazon-apigateway-integration:
responses:
default:
statusCode: "200"
responseParameters:
method.response.header.Access-Control-Allow-Methods: "'DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT'"
method.response.header.Access-Control-Allow-Headers: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'"
method.response.header.Access-Control-Allow-Origin: "'*'"
requestTemplates:
application/json: "{\"statusCode\": 200}"
passthroughBehavior: "when_no_match"
type: "mock"
x-amazon-apigateway-any-method:
responses:
"200":
description: "200 response"
content: {}
security:
- api_key: []
x-amazon-apigateway-integration:
httpMethod: "POST"
uri: "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:${LambdaFunction.Arn}/invocations"
responses:
".*":
statusCode: "200"
passthroughBehavior: "when_no_match"
type: "aws_proxy"
components:
schemas:
Empty:
title: "Empty Schema"
type: "object"
securitySchemes:
api_key:
type: "apiKey"
name: "x-api-key"
in: "header"
here openapi-spec.yaml file was kept in the same folder as the AWS SAM template and it was uploaded to the S3 bucket before deployment start using the following command in the GitHub workflow pipeline file.
- run: aws s3 cp openapi-spec.yaml s3://mnai-code-deployments
- run: sam build
- run: sam deploy --no-confirm-changeset --no-fail-on-empty-changeset --stack-name my-stack --s3-bucket mybucket --capabilities CAPABILITY_IAM --region eu-west-2 --parameter-overrides ParameterKey=DeploymentEnv,ParameterValue=dev ParameterKey=S3Bucket,ParameterValue=mybucket
Thanks

Unable to configure Firebase authorization to AWS API Gateway

I am developing a REST API with AWS Lambda and API Gateway. I am trying to configure Firebase authorization to this. FYI, I have not touched the AWS Web Console, just trying to do everything with the aws-sam.
Below is my code. I have not changed anything below, code is pasted as it is.
template.yaml
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
aws-restapi
Sample SAM Template for aws-restapi
# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
Globals:
Function:
Timeout: 5
VpcConfig:
SecurityGroupIds:
- sg-041f2459dcd921e8e
SubnetIds:
- subnet-038025dd
- subnet-c44254cb
Parameters:
FirebaseProjectId:
Type: String
Resources:
AuthGatewayHttpApi:
Type: AWS::Serverless::HttpApi
Properties:
Auth:
Authorizers:
FirebaseAuthorizer:
IdentitySource: $request.header.Authorization
JwtConfiguration:
audience:
- !Ref aws-7e5db
issuer: !Sub https://securetoken.google.com/${aws-7e5db}
DefaultAuthorizer: FirebaseAuthorizer
StageName: "Prod"
AuthFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: aws-restapi/
Handler: source/testfile.lambdaHandler
Runtime: nodejs14.x
Events:
Gateway:
Type: HttpApi
Properties:
ApiId: !Ref AuthGatewayHttpApi
Path: /hello
Method: GET
testfile.js
exports.lambdaHandler = async (event) => {
try {
// If an authenticated request is made to JWT
// Which we expect is what will happen
// So we simply return the claims
const jwt = event.requestContext.authorizer.jwt.claims;
// Let us get the email from the claims
// Note the email will not be available if Sign in via phone
const email = jwt.claims.email;
return {
statusCode: 200,
body: JSON.stringify({ jwt: jwt, email: email }),
};
} catch (err) {
console.error(err);
return {
statusCode: 400,
body: JSON.stringify({ error: "Please check logs" }),
};
}
};
This builds, but cannot deploy. It simply throws the following error.
Error: Failed to create changeset for the stack: aws-restapi, An error occurred (ValidationError) when calling the CreateChangeSet operation: Parameters: [FirebaseProjectId] must have values
What is wrong here? Plus, my firebase auth configuration is correct?
You are defining a parameter but not assigning a value to it.
Parameters:
FirebaseProjectId:
Type: String
Either you delete it, or assign a value
You can avoid this issue also by supplying a default value:
Parameters:
FirebaseProjectId:
Type: String
Default: "1111-2222-3333-44444"
I found the issue for this. I had to pass the parameter. Passing a parameter should be done when you are deploying. Do the following.
sam deploy --guided
Then follow the process, it will ask you for the parameter value. You have to do this whether you have done a deployment before or not.
Then, my code was wrong too. This is how it should be.
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
aws-restapi
Sample SAM Template for aws-restapi
# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
Globals:
Function:
Timeout: 5
VpcConfig:
SecurityGroupIds:
- sg-041f2459dcd921e8e
SubnetIds:
- subnet-0381asa2d
- subnet-c4dasascb
Parameters:
FirebaseProjectId:
Type: String
Resources:
AuthGatewayHttpApi:
Type: AWS::Serverless::HttpApi
Properties:
Auth:
Authorizers:
FirebaseAuthorizer:
IdentitySource: $request.header.Authorization
JwtConfiguration:
audience:
- !Ref FirebaseProjectId
issuer: !Sub https://securetoken.google.com/${FirebaseProjectId}
DefaultAuthorizer: FirebaseAuthorizer
AuthFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: peresia-restapi/
Handler: source/testfile.lambdaHandler
Runtime: nodejs14.x
Events:
Gateway:
Type: HttpApi
Properties:
ApiId: !Ref AuthGatewayHttpApi
Path: /hello
Method: get

SAM Template : Cognito User Pool integrate in APIgateway - Authorizer doesn't work

I want to integrate Cognito token in my application.
How can i do it in AWS Sam Template ?
To update my template, I look on https://docs.aws.amazon.com/fr_fr/apigateway/latest/developerguide/apigateway-enable-cognito-user-pool.html?shortFooter=true
Info:
My UserPool is created in the AWS console (on web)
I test with Postman without header: if it worked I should be refused ==> reallity: I have results (my Authorizer doesn't work)
=========================
My question is : why Authorizer doesn't work ?
AWSTemplateFormatVersion: '2010-09-09'
Transform: 'AWS::Serverless-2016-10-31'
Globals:
Function:
Runtime: nodejs6.10
Handler: index.handler
Timeout: 30
Resources:
GRApi:
Type: 'AWS::Serverless::Api'
Properties:
Name: 'Myname'
StageName: !Ref Stage
Cors: "'*'"
EndpointConfiguration: REGIONAL
DefinitionBody:
swagger: "2.0"
info:
version: "1.0"
title: "myTitle"
host: !Ref Host
securityDefinitions:
cognitoUserPool:
type: apiKey
name: Authorization
in: header
x-amazon-apigateway-authtype: cognito_user_pools
x-amazon-apigateway-authorizer:
type: cognito_user_pools
providerARNs:
- "arn:aws:cognito-idp..."
schemes:
- "https"
consumes:
- application/json
produces:
- application/json
paths:
/project:
get:
responses: {}
security:
- cognitoUserPool: []
x-amazon-apigateway-integration:
uri:
- 'arn:aws:apigateway:....Arn'
passthroughBehavior: "when_no_match"
httpMethod: "POST"
type: "aws_proxy"
GetAllProjectsFunction:
Type: 'AWS::Serverless::Function'
Properties:
CodeUri: URI/
Handler: index.handler
Runtime: nodejs8.10
MemorySize: 128
Timeout: 30
Role: 'arn:....role'
Events:
GetAllProjects:
Type: Api
Properties:
Path: /project
Method: get
RestApiId: !Ref GRApi
Outputs:
...

Pass a referance to API Gateway to Lambda

I'm using the Serverless framework and one of my lambda functions needs to know the API gateway id. I tried setting an envierment varable like the following.
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Globals:
Function:
Runtime: nodejs6.10
Environment:
Variables:
API_GATEWAY: !Ref ApiGatewayRestApi
Resources:
Test:
Type: AWS::Serverless::Function
Properties:
Handler: LeadLambda.test
CodeUri: ./Lead
Events:
GetResource:
Type: Api
Properties:
Path: /
Method: get
But when I try and deploy I get a circular dependency error.
Failed to create the changeset: Waiter ChangeSetCreateComplete failed: Waiter encountered a terminal failure state Status: FAILED. Reason: Circular dependency between resources: [TestGetResourcePermissionProd, ServerlessRestApi, Test, TestGetResourcePermissionTest, ServerlessRestApiDeploymentb5240aa4ca, ServerlessRestApiProdStage]
The solution I ended up using was to hard code the integration uri in the API instead of referencing the Lambda.
Globals:
Function:
Runtime: nodejs6.10
Environment:
Variables:
API: !Sub https://${Api}.execute-api.${AWS::Region}.amazonaws.com/prod
Resources:
Entry:
Type: AWS::Serverless::Function
Properties:
FunctionName: prompt-stack-Entry
Handler: LeadLambda.entry
CodeUri: s3://ddg-prompt/LeadLambda.zip
Role: !GetAtt LeadRole.Arn
Events:
GetResource:
Type: Api
Properties:
Path: /lead
Method: POST
RestApiId: !Ref Api
Api:
Type: AWS::Serverless::Api
Properties:
StageName: prod
DefinitionBody:
swagger: 2.0
info:
title:
Ref: AWS::StackName
paths:
/lead:
post:
responses:
'200':
description: Successful operation
responseTemplates:
application/json: ""
x-amazon-apigateway-integration:
httpMethod: POST
type: aws
uri: !Sub arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:prompt-stack-Entry/invocations
responses:
default:
statusCode: '200'
responseTemplates:
application/json: ''