When I use Serverless framework 2, I defined authorizer like the below way.
sample:
handler: sample.handler
events:
- http:
path: sample
method: get
cors: true
authorizer: verify-token
But It's not supported in Serverless framework 3. Now, I am getting the below error.
Incorrect type. Expected "Aws.HttpAuthorizer".yaml-schema: Serverless Framework Configuration
I looked at their deprecated doc But I don't find the solution. How can resolve this issue?
Seems like serverless expects you to define HttpAuthorizer instead of Lambda Authorizer for AWS REST API
Definitions of the settings are here: https://raw.githubusercontent.com/lalcebo/json-schema/master/serverless/reference.json
Rest API (V1) is actually more advanced. see:
https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/AWS_ApiGateway.html or https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/AWS_ApiGatewayV2.html
Check the following documentation: https://serverless.com/framework/docs/providers/aws/events/apigateway#http-endpoints-with-custom-authorizers
The authorizer declaration must be completed in v3:
sample:
handler: sample.handler
events:
- http:
path: sample
method: get
cors: true
authorizer:
arn: xxx:xxx:verify-token
managedExternally: false
resultTtlInSeconds: 0
identitySource: method.request.header.Authorization
identityValidationExpression: someRegex
Related
I have a simple API developed using serverless framework that is deployed in production. The serverless.yaml is similar to this one:
service: example
provider:
name: aws
plugins:
- serverless-plugin-scripts
- serverless-offline
functions:
package:
runtime: nodejs14.x
handler: build/index.handler
events:
- httpApi: "POST /test"
The API will change in the next version and I want to offer backward compatibility to my clients. I want to create a /v1/test route in API Gateway that will point to the new implementation of the function and I want /test to remain the same.
Is there a way to do this using serverless framework?
There are a few things you can do.
Create a new function entirely, with a new route. This option is simplest to implement, but your setup may not allow you to create a new function for some reason (CloudFormation stack limits, or other non-functional reasons).
functions:
# V0 package function
package:
runtime: nodejs14.x
handler: build/index.handler
events:
- httpApi: "POST /test"
# V1 package function
packageV1:
runtime: nodejs14.x
handler: build/index.handlerv1
events:
- httpApi: "POST v1/test"
Use the same function, but append a new path. Then inside your function code inspect the event payload to determine which path was called and use that to modify the response or functionality to adhere to either API spec.
package:
runtime: nodejs14.x
handler: build/index.handler # Both routes share the function, you'll need to modify logic to implement both v0/v1 spec
events:
- httpApi: "POST /test" # V0 route
- httpApi: "POST v1/test" # V1 route
Both of these are good for temporary migrations where you'll eventually deprecate the old API. If you need both in perpetuity, you could also migrate your v0 API into a new stack (or similarly create a new stack for the v1 API).
Lambda is priced per-invocation, not per-function. So with that in mind, I'd suggest creating a totally distinct function, that will make it easier to deprecate and delete when the time comes.
I have built a simple Node.JS application that consists of a single API endpoint. Deployment works and I can all the API endpoint as expected. However the handler function also runs on deployment of the code, which is problematic for me as handler function posts a tweet to twitter, and I don't want it to tweet every time I deploy a code update. I haven't been able to find anyone online reporting a similar problem, but I'm sure this would not be expected functionality.
This is my serverless.yml file (I created originally from the GitLab Node.JS serverless template here https://gitlab.com/gitlab-org/project-templates/serverless-framework/):
service: my-project
provider:
name: aws
region: ${env:AWS_REGION}
runtime: nodejs10.x
plugins:
- serverless-offline
- serverless-jest-plugin
- serverless-stack-output # Allows us to output endpoint url to json file
functions:
post:
handler: main.main
events:
- http:
path: post
method: post
custom:
output:
handler: main.main
file: stack.json
I believe the problem in your case is the fact that the handler you have for serverless-stack-output plugin is the same as for your function. That plugin explicitly calls the handler (https://github.com/sbstjn/serverless-stack-output#handler) which executes your function. If you will drop use of the plugin or just configure a different handler for it the problem should disappear
Is it possible to have lambda function with different custom domain than others; In servlerless lambda project, I need to have one lambda to use different custom domain than other lambdas. for example
userNotification --> dev.xyz.com/users
all others
getProducts --> dev.abc.com/products
I tried using custom domain as following but it did not work.
userNotification:
handler: src/index.handler
events:
- http:
method: get
path: /userNotification
cors:
origin: '*'
headers:
- Content-Type
- X-Amz-Date
- Authorization
- X-Api-Key
- X-Amz-Security-Token
- If-Match
- If-None-Match
# override default customDomain
customDomain:
domainName: 'dev.xyz-comm-sanbox.com'
basePath: dev-newbank
stage: dev
createRoute53Record: true
In serverless.yml, I'm using custom domains as, this work fine but then i have single customDomains for all lambdas funcrion. I need to have one lambda to use different customDomain than others;
custom:
customDomain:
basePath: dev-newbank
domainName: 'dev.abc.com'
stage: 'dev'
createRoute53Record: true
endpointType: regional
securityPolicy: tls_1_2
I think you would have to have 2 different serverless.ymls, 1 for managing your /products path and one for /users. Then you could specify different domains for each. Since underneath it all API Gateway only supports custom domains on the API, not on individual endpoints in the API, you would have to split your lambdas up
I have a Lambda Edge attached to a CloudFront distribution. What I want to do is use Serverless Framework to publish the lambda (instead of manually uploading files and click on "Deploy to Lambda#Edge"). What I've tried to do, looking at the serverless documentation, is add this yml file to the project and run the deployment script
service: cloudfront-service
provider:
name: aws
runtime: nodejs10.x
functions:
cfLambda:
handler: index.handler
events:
- cloudFront:
eventType: origin-request
origin: <CloudFront-Origin-ID>
This deployed the Lambda but it didn't attached it to CloudFront (it hasn't been published and there is no versions or triggers related). So how can I do this, using an existing CloudFront distribution?
This plugin #silvermine/serverless-plugin-cloudfront-lambda-edge will not help if you want to use an existing cloud front distribution. It is only helpful if you are going to create a new one.
This issue has been already reported and as per the forum, this functionality they are not supporting.
Lambda#Edge with Serverless-Framework is quite easy. We use this plugin.
plugins:
- '#silvermine/serverless-plugin-cloudfront-lambda-edge'
Please go directly to the plugin author's website for complete examples: https://github.com/silvermine/serverless-plugin-cloudfront-lambda-edge
Base on your implementation you have a wrong indentation so I think it wont really attach it to your cloudfront. Having a wrong indetation will not create an events on your lambda function so intead of this
events:
- cloudFront:
eventType: origin-request
origin: <CloudFront-Origin-ID>
Do this:
events:
- cloudFront:
eventType: origin-request
origin: <CloudFront-Origin-ID>
I hope that this will solve your problem. Because I encounter this wrong indentation myself and wander why it is not being implemented properly.
functions:
update:
handler: todos/update.update
events:
- http:
path: /update/{title}
method: put
How do I have to define the path param in order to pass it to my AWS Lambda function using serverless framework?
The language I want to use for lambda is Python3.
This is correct, you can access the parameter you defined in the serverless.yml from event['pathParameters']['title'] inside the lambda.
hope this helps